11 #ifndef NLOHMANN_JSON_HPP 12 #define NLOHMANN_JSON_HPP 23 #include <initializer_list> 33 #include <type_traits> 40 #include <sys/types.h> 45 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 46 #pragma GCC diagnostic push 47 #pragma GCC diagnostic ignored "-Wfloat-equal" 53 using ssize_t = SSIZE_T;
76 struct has_mapped_type
79 template<
typename C>
static char test(
typename C::mapped_type*);
80 template<
typename C>
static char (&test(...))[2];
82 static constexpr
bool value =
sizeof(test<T>(0)) == 1;
159 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
160 template<
typename U,
typename... Args>
class ArrayType = std::vector,
161 class StringType = std::string,
162 class BooleanType = bool,
163 class NumberIntegerType = int64_t,
164 class NumberUnsignedType = uint64_t,
165 class NumberFloatType = double,
166 template<
typename U>
class AllocatorType = std::allocator
207 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
209 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
324 using object_t = ObjectType<StringType,
326 std::less<StringType>,
327 AllocatorType<std::pair<
const StringType,
374 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
693 template<
typename T,
typename... Args>
694 static T* create(Args&& ... args)
696 AllocatorType<T> alloc;
697 auto deleter = [&](T * object)
699 alloc.deallocate(
object, 1);
701 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
702 alloc.construct(
object.
get(), std::forward<Args>(args)...);
703 return object.release();
735 json_value() noexcept =
default;
737 json_value(
boolean_t v) noexcept : boolean(v) {}
749 case value_t::object:
751 object = create<object_t>();
757 array = create<array_t>();
761 case value_t::string:
763 string = create<string_t>(
"");
767 case value_t::boolean:
773 case value_t::number_integer:
779 case value_t::number_unsigned:
785 case value_t::number_float:
801 string = create<string_t>(value);
807 object = create<object_t>(value);
811 json_value(
const array_t& value)
813 array = create<array_t>(value);
896 using parser_callback_t = std::function<bool(int depth, parse_event_t event, basic_json& parsed)>;
946 : m_type(value_type), m_value(value_type)
970 basic_json() noexcept =
default;
1015 : m_type(
value_t::object), m_value(val)
1041 template <
class CompatibleObjectType,
typename 1043 std::is_constructible<typename object_t::key_type, typename CompatibleObjectType::key_type>::value and
1044 std::is_constructible<basic_json, typename CompatibleObjectType::mapped_type>::value,
int>::type
1051 m_value.object = create<object_t>(begin(val), end(val));
1074 : m_type(
value_t::array), m_value(val)
1100 template <
class CompatibleArrayType,
typename 1102 not std::is_same<CompatibleArrayType, typename basic_json_t::iterator>::value and
1103 not std::is_same<CompatibleArrayType, typename basic_json_t::const_iterator>::value and
1104 not std::is_same<CompatibleArrayType, typename basic_json_t::reverse_iterator>::value and
1105 not std::is_same<CompatibleArrayType, typename basic_json_t::const_reverse_iterator>::value and
1106 not std::is_same<CompatibleArrayType, typename array_t::iterator>::value and
1107 not std::is_same<CompatibleArrayType, typename array_t::const_iterator>::value and
1108 std::is_constructible<basic_json, typename CompatibleArrayType::value_type>::value,
int>::type
1115 m_value.array = create<array_t>(begin(val), end(val));
1140 : m_type(
value_t::string), m_value(val)
1190 template <
class CompatibleStringType,
typename 1192 std::is_constructible<string_t, CompatibleStringType>::value,
int>::type
1213 : m_type(
value_t::boolean), m_value(val)
1241 template<
typename T,
1242 typename std::enable_if<
1243 not (std::is_same<T, int>::value)
1244 and std::is_same<T, number_integer_t>::value
1248 : m_type(
value_t::number_integer), m_value(val)
1277 : m_type(
value_t::number_integer),
1306 template<
typename CompatibleNumberIntegerType,
typename 1308 std::is_constructible<number_integer_t, CompatibleNumberIntegerType>::value and
1309 std::numeric_limits<CompatibleNumberIntegerType>::is_integer and
1310 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1311 CompatibleNumberIntegerType>::type
1314 : m_type(value_t::number_integer),
1315 m_value(static_cast<number_integer_t>(val))
1335 template<
typename T,
1336 typename std::enable_if<
1337 not (std::is_same<T, int>::value)
1338 and std::is_same<T, number_unsigned_t>::value
1342 : m_type(
value_t::number_unsigned), m_value(val)
1365 template <
typename CompatibleNumberUnsignedType,
typename 1367 std::is_constructible<number_unsigned_t, CompatibleNumberUnsignedType>::value and
1368 std::numeric_limits<CompatibleNumberUnsignedType>::is_integer and
1369 !std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1370 CompatibleNumberUnsignedType >::type
1373 : m_type(value_t::number_unsigned),
1374 m_value(static_cast<number_unsigned_t>(val))
1402 : m_type(
value_t::number_float), m_value(val)
1405 if (not std::isfinite(val))
1407 m_type = value_t::null;
1408 m_value = json_value();
1442 template<
typename CompatibleNumberFloatType,
typename =
typename 1444 std::is_constructible<number_float_t, CompatibleNumberFloatType>::value and
1445 std::is_floating_point<CompatibleNumberFloatType>::value>::type
1521 bool type_deduction =
true,
1522 value_t manual_type = value_t::array)
1525 bool is_an_object =
true;
1529 for (
const auto& element : init)
1531 if (not element.is_array() or element.size() != 2
1532 or not element[0].is_string())
1536 is_an_object =
false;
1542 if (not type_deduction)
1545 if (manual_type == value_t::array)
1547 is_an_object =
false;
1551 if (manual_type == value_t::object and not is_an_object)
1553 throw std::domain_error(
"cannot create object from initializer list");
1560 m_type = value_t::object;
1561 m_value = value_t::object;
1563 assert(m_value.object !=
nullptr);
1565 for (
auto& element : init)
1567 m_value.object->emplace(std::move(*(element[0].m_value.string)), std::move(element[1]));
1573 m_type = value_t::array;
1574 m_value.array = create<array_t>(std::move(init));
1612 static basic_json
array(std::initializer_list<basic_json> init =
1613 std::initializer_list<basic_json>())
1615 return basic_json(init,
false, value_t::array);
1652 static basic_json
object(std::initializer_list<basic_json> init =
1653 std::initializer_list<basic_json>())
1655 return basic_json(init,
false, value_t::object);
1679 m_value.array = create<array_t>(cnt, val);
1716 template <
class InputIT,
typename 1718 std::is_same<InputIT, typename basic_json_t::iterator>::value or
1719 std::is_same<InputIT, typename basic_json_t::const_iterator>::value
1722 basic_json(InputIT first, InputIT last) : m_type(first.m_object->m_type)
1725 if (first.m_object != last.m_object)
1727 throw std::domain_error(
"iterators are not compatible");
1733 case value_t::boolean:
1734 case value_t::number_float:
1735 case value_t::number_integer:
1736 case value_t::number_unsigned:
1737 case value_t::string:
1739 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1741 throw std::out_of_range(
"iterators out of range");
1754 case value_t::number_integer:
1756 assert(first.m_object !=
nullptr);
1757 m_value.number_integer = first.m_object->m_value.number_integer;
1761 case value_t::number_unsigned:
1763 assert(first.m_object !=
nullptr);
1764 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1768 case value_t::number_float:
1770 assert(first.m_object !=
nullptr);
1771 m_value.number_float = first.m_object->m_value.number_float;
1775 case value_t::boolean:
1777 assert(first.m_object !=
nullptr);
1778 m_value.boolean = first.m_object->m_value.boolean;
1782 case value_t::string:
1784 assert(first.m_object !=
nullptr);
1785 m_value = *first.m_object->m_value.string;
1789 case value_t::object:
1791 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1795 case value_t::array:
1797 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1803 assert(first.m_object !=
nullptr);
1804 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1831 *
this = parser(i, cb).parse();
1861 : m_type(other.m_type)
1865 case value_t::object:
1867 assert(other.m_value.object !=
nullptr);
1868 m_value = *other.m_value.object;
1872 case value_t::array:
1874 assert(other.m_value.array !=
nullptr);
1875 m_value = *other.m_value.array;
1879 case value_t::string:
1881 assert(other.m_value.string !=
nullptr);
1882 m_value = *other.m_value.string;
1886 case value_t::boolean:
1888 m_value = other.m_value.boolean;
1892 case value_t::number_integer:
1894 m_value = other.m_value.number_integer;
1898 case value_t::number_unsigned:
1900 m_value = other.m_value.number_unsigned;
1904 case value_t::number_float:
1906 m_value = other.m_value.number_float;
1936 : m_type(
std::move(other.m_type)),
1937 m_value(
std::move(other.m_value))
1940 other.m_type = value_t::null;
1968 std::is_nothrow_move_constructible<value_t>::value and
1969 std::is_nothrow_move_assignable<value_t>::value and
1970 std::is_nothrow_move_constructible<json_value>::value and
1971 std::is_nothrow_move_assignable<json_value>::value
1975 swap(m_type, other.m_type);
1976 swap(m_value, other.m_value);
1999 case value_t::object:
2001 AllocatorType<object_t> alloc;
2002 alloc.destroy(m_value.object);
2003 alloc.deallocate(m_value.object, 1);
2007 case value_t::array:
2009 AllocatorType<array_t> alloc;
2010 alloc.destroy(m_value.array);
2011 alloc.deallocate(m_value.array, 1);
2015 case value_t::string:
2017 AllocatorType<string_t> alloc;
2018 alloc.destroy(m_value.string);
2019 alloc.deallocate(m_value.string, 1);
2066 std::stringstream ss;
2070 dump(ss,
true, static_cast<unsigned int>(indent));
2124 return is_null() or is_string() or is_boolean() or is_number();
2148 return is_array() or is_object();
2167 return m_type == value_t::null;
2186 return m_type == value_t::boolean;
2213 return is_number_integer() or is_number_float();
2239 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2264 return m_type == value_t::number_unsigned;
2289 return m_type == value_t::number_float;
2308 return m_type == value_t::object;
2327 return m_type == value_t::array;
2346 return m_type == value_t::string;
2370 return m_type == value_t::discarded;
2401 template <
class T,
typename 2403 std::is_convertible<typename object_t::key_type, typename T::key_type>::value and
2404 std::is_convertible<basic_json_t, typename T::mapped_type>::value
2406 T get_impl(T*)
const 2410 assert(m_value.object !=
nullptr);
2411 return T(m_value.object->begin(), m_value.object->end());
2415 throw std::domain_error(
"type must be object, but is " + type_name());
2424 assert(m_value.object !=
nullptr);
2425 return *(m_value.object);
2429 throw std::domain_error(
"type must be object, but is " + type_name());
2434 template <
class T,
typename 2436 std::is_convertible<basic_json_t, typename T::value_type>::value and
2437 not std::is_same<basic_json_t, typename T::value_type>::value and
2438 not std::is_arithmetic<T>::value and
2439 not std::is_convertible<std::string, T>::value and
2440 not has_mapped_type<T>::value
2442 T get_impl(T*)
const 2447 assert(m_value.array !=
nullptr);
2448 std::transform(m_value.array->begin(), m_value.array->end(),
2449 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2451 return i.
get<
typename T::value_type>();
2457 throw std::domain_error(
"type must be array, but is " + type_name());
2462 template <
class T,
typename 2464 std::is_convertible<basic_json_t, T>::value and
2465 not std::is_same<basic_json_t, T>::value
2467 std::vector<T> get_impl(std::vector<T>*)
const 2471 std::vector<T> to_vector;
2472 assert(m_value.array !=
nullptr);
2473 to_vector.reserve(m_value.array->size());
2474 std::transform(m_value.array->begin(), m_value.array->end(),
2475 std::inserter(to_vector, to_vector.end()), [](basic_json i)
2483 throw std::domain_error(
"type must be array, but is " + type_name());
2488 template <
class T,
typename 2490 std::is_same<basic_json, typename T::value_type>::value and
2491 not has_mapped_type<T>::value
2493 T get_impl(T*)
const 2497 assert(m_value.array !=
nullptr);
2498 return T(m_value.array->begin(), m_value.array->end());
2502 throw std::domain_error(
"type must be array, but is " + type_name());
2511 assert(m_value.array !=
nullptr);
2512 return *(m_value.array);
2516 throw std::domain_error(
"type must be array, but is " + type_name());
2521 template <
typename T,
typename 2523 std::is_convertible<string_t, T>::value
2525 T get_impl(T*)
const 2529 assert(m_value.string !=
nullptr);
2530 return *m_value.string;
2534 throw std::domain_error(
"type must be string, but is " + type_name());
2539 template<
typename T,
typename 2541 std::is_arithmetic<T>::value
2543 T get_impl(T*)
const 2547 case value_t::number_integer:
2549 return static_cast<T
>(m_value.number_integer);
2552 case value_t::number_unsigned:
2554 return static_cast<T
>(m_value.number_unsigned);
2557 case value_t::number_float:
2559 return static_cast<T
>(m_value.number_float);
2564 throw std::domain_error(
"type must be number, but is " + type_name());
2574 return m_value.boolean;
2578 throw std::domain_error(
"type must be boolean, but is " + type_name());
2585 return is_object() ? m_value.object :
nullptr;
2591 return is_object() ? m_value.object :
nullptr;
2597 return is_array() ? m_value.array :
nullptr;
2603 return is_array() ? m_value.array :
nullptr;
2609 return is_string() ? m_value.string :
nullptr;
2615 return is_string() ? m_value.string :
nullptr;
2621 return is_boolean() ? &m_value.boolean :
nullptr;
2627 return is_boolean() ? &m_value.boolean :
nullptr;
2633 return is_number_integer() ? &m_value.number_integer :
nullptr;
2639 return is_number_integer() ? &m_value.number_integer :
nullptr;
2645 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2651 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2657 return is_number_float() ? &m_value.number_float :
nullptr;
2663 return is_number_float() ? &m_value.number_float :
nullptr;
2677 template<
typename ReferenceType,
typename ThisType>
2678 static ReferenceType get_ref_impl(ThisType& obj)
2681 using PointerType =
typename std::add_pointer<ReferenceType>::type;
2682 auto ptr = obj.template get_ptr<PointerType>();
2690 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2733 template<
typename ValueType,
typename 2735 not std::is_pointer<ValueType>::value
2737 ValueType
get()
const 2739 return get_impl(static_cast<ValueType*>(
nullptr));
2768 template<
typename PointerType,
typename 2770 std::is_pointer<PointerType>::value
2772 PointerType
get() noexcept
2775 return get_ptr<PointerType>();
2782 template<
typename PointerType,
typename 2784 std::is_pointer<PointerType>::value
2786 const PointerType
get()
const noexcept
2789 return get_ptr<PointerType>();
2817 template<
typename PointerType,
typename 2819 std::is_pointer<PointerType>::value
2824 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2831 template<
typename PointerType,
typename 2833 std::is_pointer<PointerType>::value
2834 and std::is_const<typename std::remove_pointer<PointerType>::type>::value
2839 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
2868 template<
typename ReferenceType,
typename 2870 std::is_reference<ReferenceType>::value
2875 return get_ref_impl<ReferenceType>(*this);
2882 template<
typename ReferenceType,
typename 2884 std::is_reference<ReferenceType>::value
2885 and std::is_const<typename std::remove_reference<ReferenceType>::type>::value
2890 return get_ref_impl<ReferenceType>(*this);
2921 template <
typename ValueType,
typename 2923 not std::is_pointer<ValueType>::value
2924 and not std::is_same<ValueType, typename string_t::value_type>::value
2925 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 2926 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
2929 operator ValueType()
const 2932 return get<ValueType>();
2974 assert(m_value.array !=
nullptr);
2975 return m_value.array->at(idx);
2977 catch (std::out_of_range&)
2980 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
2985 throw std::domain_error(
"cannot use at() with " + type_name());
3018 assert(m_value.array !=
nullptr);
3019 return m_value.array->at(idx);
3021 catch (std::out_of_range&)
3024 throw std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range");
3029 throw std::domain_error(
"cannot use at() with " + type_name());
3066 assert(m_value.object !=
nullptr);
3067 return m_value.object->at(key);
3069 catch (std::out_of_range&)
3072 throw std::out_of_range(
"key '" + key +
"' not found");
3077 throw std::domain_error(
"cannot use at() with " + type_name());
3114 assert(m_value.object !=
nullptr);
3115 return m_value.object->at(key);
3117 catch (std::out_of_range&)
3120 throw std::out_of_range(
"key '" + key +
"' not found");
3125 throw std::domain_error(
"cannot use at() with " + type_name());
3159 m_type = value_t::array;
3160 m_value.
array = create<array_t>();
3166 assert(m_value.array !=
nullptr);
3167 for (
size_t i = m_value.array->size(); i <= idx; ++i)
3169 m_value.array->push_back(basic_json());
3172 return m_value.array->operator[](idx);
3176 throw std::domain_error(
"cannot use operator[] with " + type_name());
3204 assert(m_value.array !=
nullptr);
3205 return m_value.array->operator[](idx);
3209 throw std::domain_error(
"cannot use operator[] with " + type_name());
3245 m_type = value_t::object;
3246 m_value.
object = create<object_t>();
3252 assert(m_value.object !=
nullptr);
3253 return m_value.object->operator[](key);
3257 throw std::domain_error(
"cannot use operator[] with " + type_name());
3293 assert(m_value.object !=
nullptr);
3294 assert(m_value.object->find(key) != m_value.object->end());
3295 return m_value.object->find(key)->second;
3299 throw std::domain_error(
"cannot use operator[] with " + type_name());
3330 template<
typename T, std::
size_t n>
3333 return operator[](static_cast<const T>(key));
3365 template<
typename T, std::
size_t n>
3368 return operator[](static_cast<const T>(key));
3398 template<
typename T>
3404 m_type = value_t::object;
3405 m_value = value_t::object;
3411 assert(m_value.object !=
nullptr);
3412 return m_value.object->operator[](key);
3416 throw std::domain_error(
"cannot use operator[] with " + type_name());
3447 template<
typename T>
3453 assert(m_value.object !=
nullptr);
3454 assert(m_value.object->find(key) != m_value.object->end());
3455 return m_value.object->find(key)->second;
3459 throw std::domain_error(
"cannot use operator[] with " + type_name());
3511 template <
class ValueType,
typename 3513 std::is_convertible<basic_json_t, ValueType>::value
3515 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 3521 const auto it = find(key);
3528 return default_value;
3533 throw std::domain_error(
"cannot use value() with " + type_name());
3541 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 3543 return value(key,
string_t(default_value));
3669 template <
class InteratorType,
typename 3671 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3672 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3678 if (
this != pos.m_object)
3680 throw std::domain_error(
"iterator does not fit current value");
3683 InteratorType result = end();
3687 case value_t::boolean:
3688 case value_t::number_float:
3689 case value_t::number_integer:
3690 case value_t::number_unsigned:
3691 case value_t::string:
3693 if (not pos.m_it.primitive_iterator.is_begin())
3695 throw std::out_of_range(
"iterator out of range");
3700 delete m_value.string;
3701 m_value.string =
nullptr;
3704 m_type = value_t::null;
3708 case value_t::object:
3710 assert(m_value.object !=
nullptr);
3711 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3715 case value_t::array:
3717 assert(m_value.array !=
nullptr);
3718 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3724 throw std::domain_error(
"cannot use erase() with " + type_name());
3775 template <
class InteratorType,
typename 3777 std::is_same<InteratorType, typename basic_json_t::iterator>::value or
3778 std::is_same<InteratorType, typename basic_json_t::const_iterator>::value
3781 InteratorType
erase(InteratorType first, InteratorType last)
3784 if (
this != first.m_object or
this != last.m_object)
3786 throw std::domain_error(
"iterators do not fit current value");
3789 InteratorType result = end();
3793 case value_t::boolean:
3794 case value_t::number_float:
3795 case value_t::number_integer:
3796 case value_t::number_unsigned:
3797 case value_t::string:
3799 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
3801 throw std::out_of_range(
"iterators out of range");
3806 delete m_value.string;
3807 m_value.string =
nullptr;
3810 m_type = value_t::null;
3814 case value_t::object:
3816 assert(m_value.object !=
nullptr);
3817 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
3818 last.m_it.object_iterator);
3822 case value_t::array:
3824 assert(m_value.array !=
nullptr);
3825 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
3826 last.m_it.array_iterator);
3832 throw std::domain_error(
"cannot use erase() with " + type_name());
3870 assert(m_value.object !=
nullptr);
3871 return m_value.object->erase(key);
3875 throw std::domain_error(
"cannot use erase() with " + type_name());
3910 throw std::out_of_range(
"index out of range");
3913 assert(m_value.array !=
nullptr);
3914 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
3918 throw std::domain_error(
"cannot use erase() with " + type_name());
3941 auto result = end();
3945 assert(m_value.object !=
nullptr);
3946 result.m_it.object_iterator = m_value.object->find(key);
3958 auto result = cend();
3962 assert(m_value.object !=
nullptr);
3963 result.m_it.object_iterator = m_value.object->find(key);
3990 assert(not is_object() or m_value.object !=
nullptr);
3991 return is_object() ? m_value.object->count(key) : 0;
4279 template<
typename IteratorType>
class iteration_proxy;
4295 return iteration_proxy<iterator>(cont);
4303 return iteration_proxy<const_iterator>(cont);
4359 case value_t::array:
4361 assert(m_value.array !=
nullptr);
4362 return m_value.array->empty();
4365 case value_t::object:
4367 assert(m_value.object !=
nullptr);
4368 return m_value.object->empty();
4422 case value_t::array:
4424 assert(m_value.array !=
nullptr);
4425 return m_value.array->size();
4428 case value_t::object:
4430 assert(m_value.object !=
nullptr);
4431 return m_value.object->size();
4482 case value_t::array:
4484 assert(m_value.array !=
nullptr);
4485 return m_value.array->max_size();
4488 case value_t::object:
4490 assert(m_value.object !=
nullptr);
4491 return m_value.object->max_size();
4541 case value_t::number_integer:
4543 m_value.number_integer = 0;
4547 case value_t::number_unsigned:
4549 m_value.number_unsigned = 0;
4553 case value_t::number_float:
4555 m_value.number_float = 0.0;
4559 case value_t::boolean:
4561 m_value.boolean =
false;
4565 case value_t::string:
4567 assert(m_value.string !=
nullptr);
4568 m_value.string->clear();
4572 case value_t::array:
4574 assert(m_value.array !=
nullptr);
4575 m_value.array->clear();
4579 case value_t::object:
4581 assert(m_value.object !=
nullptr);
4582 m_value.object->clear();
4616 if (not(is_null() or is_array()))
4618 throw std::domain_error(
"cannot use push_back() with " + type_name());
4624 m_type = value_t::array;
4625 m_value = value_t::array;
4629 assert(m_value.array !=
nullptr);
4630 m_value.array->push_back(std::move(val));
4632 val.m_type = value_t::null;
4641 push_back(std::move(val));
4652 if (not(is_null() or is_array()))
4654 throw std::domain_error(
"cannot use push_back() with " + type_name());
4660 m_type = value_t::array;
4661 m_value = value_t::array;
4665 assert(m_value.array !=
nullptr);
4666 m_value.array->push_back(val);
4702 if (not(is_null() or is_object()))
4704 throw std::domain_error(
"cannot use push_back() with " + type_name());
4710 m_type = value_t::object;
4711 m_value = value_t::object;
4715 assert(m_value.object !=
nullptr);
4716 m_value.object->insert(val);
4726 return operator[](val.first);
4757 if (pos.m_object !=
this)
4759 throw std::domain_error(
"iterator does not fit current value");
4764 assert(m_value.array !=
nullptr);
4765 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
4770 throw std::domain_error(
"cannot use insert() with " + type_name());
4780 return insert(pos, val);
4813 if (pos.m_object !=
this)
4815 throw std::domain_error(
"iterator does not fit current value");
4820 assert(m_value.array !=
nullptr);
4821 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
4826 throw std::domain_error(
"cannot use insert() with " + type_name());
4865 throw std::domain_error(
"cannot use insert() with " + type_name());
4869 if (pos.m_object !=
this)
4871 throw std::domain_error(
"iterator does not fit current value");
4874 if (first.m_object != last.m_object)
4876 throw std::domain_error(
"iterators do not fit");
4879 if (first.m_object ==
this or last.m_object ==
this)
4881 throw std::domain_error(
"passed iterators may not belong to container");
4886 assert(m_value.array !=
nullptr);
4887 result.m_it.array_iterator = m_value.array->insert(
4888 pos.m_it.array_iterator,
4889 first.m_it.array_iterator,
4890 last.m_it.array_iterator);
4923 throw std::domain_error(
"cannot use insert() with " + type_name());
4927 if (pos.m_object !=
this)
4929 throw std::domain_error(
"iterator does not fit current value");
4934 assert(m_value.array !=
nullptr);
4935 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
4957 std::is_nothrow_move_constructible<value_t>::value and
4958 std::is_nothrow_move_assignable<value_t>::value and
4959 std::is_nothrow_move_constructible<json_value>::value and
4960 std::is_nothrow_move_assignable<json_value>::value
4963 std::swap(m_type, other.m_type);
4964 std::swap(m_value, other.m_value);
4992 assert(m_value.array !=
nullptr);
4993 std::swap(*(m_value.array), other);
4997 throw std::domain_error(
"cannot use swap() with " + type_name());
5026 assert(m_value.object !=
nullptr);
5027 std::swap(*(m_value.object), other);
5031 throw std::domain_error(
"cannot use swap() with " + type_name());
5060 assert(m_value.string !=
nullptr);
5061 std::swap(*(m_value.string), other);
5065 throw std::domain_error(
"cannot use swap() with " + type_name());
5091 static constexpr std::array<uint8_t, 8> order = {{
5104 if (lhs == value_t::discarded or rhs == value_t::discarded)
5109 return order[
static_cast<std::size_t
>(lhs)] < order[static_cast<std::size_t>(rhs)];
5138 const auto lhs_type = lhs.type();
5139 const auto rhs_type = rhs.type();
5141 if (lhs_type == rhs_type)
5145 case value_t::array:
5147 assert(lhs.m_value.array !=
nullptr);
5148 assert(rhs.m_value.array !=
nullptr);
5149 return *lhs.m_value.array == *rhs.m_value.array;
5151 case value_t::object:
5153 assert(lhs.m_value.object !=
nullptr);
5154 assert(rhs.m_value.object !=
nullptr);
5155 return *lhs.m_value.object == *rhs.m_value.object;
5161 case value_t::string:
5163 assert(lhs.m_value.string !=
nullptr);
5164 assert(rhs.m_value.string !=
nullptr);
5165 return *lhs.m_value.string == *rhs.m_value.string;
5167 case value_t::boolean:
5169 return lhs.m_value.boolean == rhs.m_value.boolean;
5171 case value_t::number_integer:
5173 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5175 case value_t::number_unsigned:
5177 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5179 case value_t::number_float:
5181 return lhs.m_value.number_float == rhs.m_value.number_float;
5189 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5191 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5193 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5195 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5197 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5199 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5201 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5203 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5205 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5207 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5209 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5211 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5267 return not (lhs == rhs);
5299 return not v.is_null();
5328 const auto lhs_type = lhs.type();
5329 const auto rhs_type = rhs.type();
5331 if (lhs_type == rhs_type)
5335 case value_t::array:
5337 assert(lhs.m_value.array !=
nullptr);
5338 assert(rhs.m_value.array !=
nullptr);
5339 return *lhs.m_value.array < *rhs.m_value.array;
5341 case value_t::object:
5343 assert(lhs.m_value.object !=
nullptr);
5344 assert(rhs.m_value.object !=
nullptr);
5345 return *lhs.m_value.object < *rhs.m_value.object;
5351 case value_t::string:
5353 assert(lhs.m_value.string !=
nullptr);
5354 assert(rhs.m_value.string !=
nullptr);
5355 return *lhs.m_value.string < *rhs.m_value.string;
5357 case value_t::boolean:
5359 return lhs.m_value.boolean < rhs.m_value.boolean;
5361 case value_t::number_integer:
5363 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5365 case value_t::number_unsigned:
5367 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5369 case value_t::number_float:
5371 return lhs.m_value.number_float < rhs.m_value.number_float;
5379 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5381 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
5383 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5385 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5387 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5389 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5391 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5393 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5395 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5397 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5399 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5401 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5407 return operator<(lhs_type, rhs_type);
5429 return not (rhs < lhs);
5451 return not (lhs <= rhs);
5473 return not (lhs < rhs);
5508 friend std::ostream&
operator<<(std::ostream& o,
const basic_json& j)
5511 const bool pretty_print = (o.width() > 0);
5512 const auto indentation = (pretty_print ? o.width() : 0);
5518 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5526 friend std::ostream&
operator>>(
const basic_json& j, std::ostream& o)
5567 return parser(s, cb).
parse();
5596 return parser(i, cb).
parse();
5604 return parser(i, cb).
parse();
5632 j = parser(i).
parse();
5642 j = parser(i).
parse();
5661 case value_t::object:
5663 case value_t::array:
5665 case value_t::string:
5667 case value_t::boolean:
5669 case value_t::discarded:
5684 static std::size_t extra_space(
const string_t& s) noexcept
5686 std::size_t result = 0;
5688 for (
const auto& c : s)
5707 if (c >= 0x00 and c <= 0x1f)
5735 const auto space = extra_space(s);
5742 string_t result(s.size() + space,
'\\');
5743 std::size_t pos = 0;
5745 for (
const auto& c : s)
5752 result[pos + 1] =
'"';
5768 result[pos + 1] =
'b';
5776 result[pos + 1] =
'f';
5784 result[pos + 1] =
'n';
5792 result[pos + 1] =
'r';
5800 result[pos + 1] =
't';
5807 if (c >= 0x00 and c <= 0x1f)
5811 auto hexify = [](
const char v) ->
char 5813 return (v < 10) ? (
'0' + v) : (
'a' + v - 10);
5818 {
'u',
'0',
'0', hexify(c >> 4), hexify(c & 0x0f)
5856 void dump(std::ostream& o,
5857 const bool pretty_print,
5858 const unsigned int indent_step,
5859 const unsigned int current_indent = 0)
const 5862 unsigned int new_indent = current_indent;
5866 case value_t::object:
5868 assert(m_value.object !=
nullptr);
5870 if (m_value.object->empty())
5881 new_indent += indent_step;
5885 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
5887 if (i != m_value.object->cbegin())
5889 o << (pretty_print ?
",\n" :
",");
5891 o <<
string_t(new_indent,
' ') <<
"\"" 5892 << escape_string(i->first) <<
"\":" 5893 << (pretty_print ?
" " :
"");
5894 i->second.dump(o, pretty_print, indent_step, new_indent);
5900 new_indent -= indent_step;
5904 o <<
string_t(new_indent,
' ') +
"}";
5908 case value_t::array:
5910 assert(m_value.array !=
nullptr);
5912 if (m_value.array->empty())
5923 new_indent += indent_step;
5927 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
5929 if (i != m_value.array->cbegin())
5931 o << (pretty_print ?
",\n" :
",");
5934 i->dump(o, pretty_print, indent_step, new_indent);
5940 new_indent -= indent_step;
5944 o <<
string_t(new_indent,
' ') <<
"]";
5948 case value_t::string:
5950 assert(m_value.string !=
nullptr);
5951 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
5955 case value_t::boolean:
5957 o << (m_value.boolean ?
"true" :
"false");
5961 case value_t::number_integer:
5963 o << m_value.number_integer;
5967 case value_t::number_unsigned:
5969 o << m_value.number_unsigned;
5973 case value_t::number_float:
5981 if (std::fmod(m_value.number_float, 1) == 0)
5983 o << std::fixed << std::setprecision(1);
5988 o.unsetf(std::ios_base::floatfield);
5989 o << std::setprecision(std::numeric_limits<double>::digits10);
5991 o << m_value.number_float;
5995 case value_t::discarded:
6015 value_t m_type = value_t::null;
6018 json_value m_value = {};
6035 class primitive_iterator_t
6051 bool is_begin()
const 6053 return (m_it == begin_value);
6059 return (m_it == end_value);
6079 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
6089 struct internal_iterator
6092 typename object_t::iterator object_iterator;
6094 typename array_t::iterator array_iterator;
6096 primitive_iterator_t primitive_iterator;
6100 : object_iterator(), array_iterator(), primitive_iterator()
6105 template<
typename IteratorType>
6106 class iteration_proxy
6110 class iteration_proxy_internal
6114 IteratorType anchor;
6116 size_t array_index = 0;
6119 iteration_proxy_internal(IteratorType it)
6124 iteration_proxy_internal& operator*()
6130 iteration_proxy_internal& operator++()
6139 bool operator!= (
const iteration_proxy_internal& o)
const 6141 return anchor != o.anchor;
6147 assert(anchor.m_object !=
nullptr);
6149 switch (anchor.m_object->type())
6152 case value_t::array:
6154 return std::to_string(array_index);
6158 case value_t::object:
6160 return anchor.key();
6172 typename IteratorType::reference value()
const 6174 return anchor.value();
6179 typename IteratorType::reference container;
6183 iteration_proxy(
typename IteratorType::reference cont)
6188 iteration_proxy_internal begin()
6190 return iteration_proxy_internal(container.begin());
6194 iteration_proxy_internal end()
6196 return iteration_proxy_internal(container.end());
6214 class const_iterator :
public std::iterator<std::random_access_iterator_tag, const basic_json>
6217 friend class basic_json;
6237 assert(m_object !=
nullptr);
6239 switch (m_object->m_type)
6243 m_it.object_iterator =
typename object_t::iterator();
6249 m_it.array_iterator =
typename array_t::iterator();
6255 m_it.primitive_iterator = primitive_iterator_t();
6264 assert(m_object !=
nullptr);
6266 switch (m_object->m_type)
6270 m_it.object_iterator = other.m_it.object_iterator;
6276 m_it.array_iterator = other.m_it.array_iterator;
6282 m_it.primitive_iterator = other.m_it.primitive_iterator;
6290 : m_object(other.m_object), m_it(other.m_it)
6295 std::is_nothrow_move_constructible<pointer>::value and
6296 std::is_nothrow_move_assignable<pointer>::value and
6297 std::is_nothrow_move_constructible<internal_iterator>::value and
6298 std::is_nothrow_move_assignable<internal_iterator>::value
6301 std::swap(m_object, other.m_object);
6302 std::swap(m_it, other.m_it);
6310 assert(m_object !=
nullptr);
6312 switch (m_object->m_type)
6316 assert(m_object->m_value.object !=
nullptr);
6317 m_it.object_iterator = m_object->m_value.object->begin();
6323 assert(m_object->m_value.array !=
nullptr);
6324 m_it.array_iterator = m_object->m_value.array->begin();
6331 m_it.primitive_iterator.set_end();
6337 m_it.primitive_iterator.set_begin();
6346 assert(m_object !=
nullptr);
6348 switch (m_object->m_type)
6352 assert(m_object->m_value.object !=
nullptr);
6353 m_it.object_iterator = m_object->m_value.object->end();
6359 assert(m_object->m_value.array !=
nullptr);
6360 m_it.array_iterator = m_object->m_value.array->end();
6366 m_it.primitive_iterator.set_end();
6376 assert(m_object !=
nullptr);
6378 switch (m_object->m_type)
6382 assert(m_object->m_value.object);
6383 assert(m_it.object_iterator != m_object->m_value.object->end());
6384 return m_it.object_iterator->second;
6389 assert(m_object->m_value.array);
6390 assert(m_it.array_iterator != m_object->m_value.array->end());
6391 return *m_it.array_iterator;
6396 throw std::out_of_range(
"cannot get value");
6401 if (m_it.primitive_iterator.is_begin())
6407 throw std::out_of_range(
"cannot get value");
6416 assert(m_object !=
nullptr);
6418 switch (m_object->m_type)
6422 assert(m_object->m_value.object);
6423 assert(m_it.object_iterator != m_object->m_value.object->end());
6424 return &(m_it.object_iterator->second);
6429 assert(m_object->m_value.array);
6430 assert(m_it.array_iterator != m_object->m_value.array->end());
6431 return &*m_it.array_iterator;
6436 if (m_it.primitive_iterator.is_begin())
6442 throw std::out_of_range(
"cannot get value");
6451 auto result = *
this;
6459 assert(m_object !=
nullptr);
6461 switch (m_object->m_type)
6465 ++m_it.object_iterator;
6471 ++m_it.array_iterator;
6477 ++m_it.primitive_iterator;
6488 auto result = *
this;
6496 assert(m_object !=
nullptr);
6498 switch (m_object->m_type)
6502 --m_it.object_iterator;
6508 --m_it.array_iterator;
6514 --m_it.primitive_iterator;
6526 if (m_object != other.m_object)
6528 throw std::domain_error(
"cannot compare iterators of different containers");
6531 assert(m_object !=
nullptr);
6533 switch (m_object->m_type)
6537 return (m_it.object_iterator == other.m_it.object_iterator);
6542 return (m_it.array_iterator == other.m_it.array_iterator);
6547 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
6555 return not operator==(other);
6562 if (m_object != other.m_object)
6564 throw std::domain_error(
"cannot compare iterators of different containers");
6567 assert(m_object !=
nullptr);
6569 switch (m_object->m_type)
6573 throw std::domain_error(
"cannot compare order of object iterators");
6578 return (m_it.array_iterator < other.m_it.array_iterator);
6583 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
6591 return not other.operator < (*this);
6597 return not operator<=(other);
6603 return not operator<(other);
6609 assert(m_object !=
nullptr);
6611 switch (m_object->m_type)
6615 throw std::domain_error(
"cannot use offsets with object iterators");
6620 m_it.array_iterator += i;
6626 m_it.primitive_iterator += i;
6637 return operator+=(-i);
6643 auto result = *
this;
6651 auto result = *
this;
6659 assert(m_object !=
nullptr);
6661 switch (m_object->m_type)
6665 throw std::domain_error(
"cannot use offsets with object iterators");
6670 return m_it.array_iterator - other.m_it.array_iterator;
6675 return m_it.primitive_iterator - other.m_it.primitive_iterator;
6683 assert(m_object !=
nullptr);
6685 switch (m_object->m_type)
6689 throw std::domain_error(
"cannot use operator[] for object iterators");
6694 return *(m_it.array_iterator + n);
6699 throw std::out_of_range(
"cannot get value");
6704 if (m_it.primitive_iterator == -n)
6710 throw std::out_of_range(
"cannot get value");
6717 typename object_t::key_type
key()
const 6719 assert(m_object !=
nullptr);
6721 if (m_object->is_object())
6723 return m_it.object_iterator->first;
6727 throw std::domain_error(
"cannot use key() for non-object iterators");
6741 internal_iterator m_it = internal_iterator();
6778 std::is_nothrow_move_constructible<pointer>::value and
6779 std::is_nothrow_move_assignable<pointer>::value and
6780 std::is_nothrow_move_constructible<internal_iterator>::value and
6781 std::is_nothrow_move_assignable<internal_iterator>::value
6784 base_iterator::operator=(other);
6791 return const_cast<reference>(base_iterator::operator*());
6797 return const_cast<pointer>(base_iterator::operator->());
6804 base_iterator::operator++();
6811 base_iterator::operator++();
6819 base_iterator::operator--();
6826 base_iterator::operator--();
6833 base_iterator::operator+=(i);
6840 base_iterator::operator-=(i);
6847 auto result = *
this;
6855 auto result = *
this;
6863 return base_iterator::operator-(other);
6869 return const_cast<reference>(base_iterator::operator[](n));
6875 return const_cast<reference>(base_iterator::value());
6896 template<
typename Base>
6918 return base_iterator::operator++(1);
6924 base_iterator::operator++();
6931 return base_iterator::operator--(1);
6937 base_iterator::operator--();
6944 base_iterator::operator+=(i);
6951 auto result = *
this;
6959 auto result = *
this;
6967 return this->base() - other.base();
6973 return *(this->operator+(n));
6977 typename object_t::key_type
key()
const 6979 auto it = --this->base();
6986 auto it = --this->base();
6987 return it.operator * ();
7008 enum class token_type
7027 using lexer_char_t =
unsigned char;
7030 explicit lexer(
const string_t& s) noexcept
7031 : m_stream(
nullptr), m_buffer(s)
7033 m_content =
reinterpret_cast<const lexer_char_t*
>(s.c_str());
7034 assert(m_content !=
nullptr);
7035 m_start = m_cursor = m_content;
7036 m_limit = m_content + s.size();
7040 explicit lexer(std::istream* s) noexcept
7041 : m_stream(s), m_buffer()
7043 assert(m_stream !=
nullptr);
7044 getline(*m_stream, m_buffer);
7045 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7046 assert(m_content !=
nullptr);
7047 m_start = m_cursor = m_content;
7048 m_limit = m_content + m_buffer.size();
7055 lexer(
const lexer&) =
delete;
7056 lexer operator=(
const lexer&) =
delete;
7073 static string_t to_unicode(
const std::size_t codepoint1,
7074 const std::size_t codepoint2 = 0)
7077 std::size_t codepoint = codepoint1;
7080 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
7083 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
7097 throw std::invalid_argument(
"missing or wrong low surrogate");
7103 if (codepoint < 0x80)
7106 result.append(1, static_cast<typename string_t::value_type>(codepoint));
7108 else if (codepoint <= 0x7ff)
7111 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
7112 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7114 else if (codepoint <= 0xffff)
7117 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
7118 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7119 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7121 else if (codepoint <= 0x10ffff)
7124 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
7125 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
7126 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
7127 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
7131 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
7138 static std::string token_type_name(token_type t)
7142 case token_type::uninitialized:
7143 return "<uninitialized>";
7144 case token_type::literal_true:
7145 return "true literal";
7146 case token_type::literal_false:
7147 return "false literal";
7148 case token_type::literal_null:
7149 return "null literal";
7150 case token_type::value_string:
7151 return "string literal";
7152 case token_type::value_number:
7153 return "number literal";
7154 case token_type::begin_array:
7156 case token_type::begin_object:
7158 case token_type::end_array:
7160 case token_type::end_object:
7162 case token_type::name_separator:
7164 case token_type::value_separator:
7166 case token_type::parse_error:
7167 return "<parse error>";
7168 case token_type::end_of_input:
7169 return "end of input";
7173 return "unknown token";
7188 token_type scan() noexcept
7195 assert(m_start !=
nullptr);
7200 unsigned int yyaccept = 0;
7201 static const unsigned char yybm[] =
7203 0, 0, 0, 0, 0, 0, 0, 0,
7204 0, 32, 32, 0, 0, 32, 0, 0,
7205 128, 128, 128, 128, 128, 128, 128, 128,
7206 128, 128, 128, 128, 128, 128, 128, 128,
7207 160, 128, 0, 128, 128, 128, 128, 128,
7208 128, 128, 128, 128, 128, 128, 128, 128,
7209 192, 192, 192, 192, 192, 192, 192, 192,
7210 192, 192, 128, 128, 128, 128, 128, 128,
7211 128, 128, 128, 128, 128, 128, 128, 128,
7212 128, 128, 128, 128, 128, 128, 128, 128,
7213 128, 128, 128, 128, 128, 128, 128, 128,
7214 128, 128, 128, 128, 0, 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, 128, 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,
7236 if ((m_limit - m_cursor) < 5)
7241 if (yybm[0 + yych] & 32)
7243 goto basic_json_parser_6;
7253 goto basic_json_parser_2;
7257 goto basic_json_parser_4;
7259 goto basic_json_parser_9;
7265 goto basic_json_parser_4;
7269 goto basic_json_parser_10;
7271 goto basic_json_parser_12;
7280 goto basic_json_parser_4;
7284 goto basic_json_parser_13;
7286 goto basic_json_parser_15;
7292 goto basic_json_parser_17;
7296 goto basic_json_parser_19;
7298 goto basic_json_parser_4;
7310 goto basic_json_parser_21;
7314 goto basic_json_parser_4;
7316 goto basic_json_parser_23;
7322 goto basic_json_parser_24;
7326 goto basic_json_parser_4;
7328 goto basic_json_parser_25;
7337 goto basic_json_parser_26;
7339 goto basic_json_parser_4;
7345 goto basic_json_parser_28;
7349 goto basic_json_parser_30;
7351 goto basic_json_parser_4;
7355 basic_json_parser_2:
7358 return token_type::end_of_input;
7360 basic_json_parser_4:
7362 basic_json_parser_5:
7364 return token_type::parse_error;
7366 basic_json_parser_6:
7368 if (m_limit <= m_cursor)
7373 if (yybm[0 + yych] & 32)
7375 goto basic_json_parser_6;
7380 basic_json_parser_9:
7382 yych = *(m_marker = ++m_cursor);
7385 goto basic_json_parser_5;
7387 goto basic_json_parser_32;
7388 basic_json_parser_10:
7391 return token_type::value_separator;
7393 basic_json_parser_12:
7397 goto basic_json_parser_5;
7401 goto basic_json_parser_13;
7405 goto basic_json_parser_15;
7407 goto basic_json_parser_5;
7408 basic_json_parser_13:
7410 yych = *(m_marker = ++m_cursor);
7415 goto basic_json_parser_37;
7422 goto basic_json_parser_38;
7426 goto basic_json_parser_38;
7429 basic_json_parser_14:
7431 return token_type::value_number;
7433 basic_json_parser_15:
7435 m_marker = ++m_cursor;
7436 if ((m_limit - m_cursor) < 3)
7441 if (yybm[0 + yych] & 64)
7443 goto basic_json_parser_15;
7449 goto basic_json_parser_37;
7451 goto basic_json_parser_14;
7457 goto basic_json_parser_38;
7461 goto basic_json_parser_38;
7463 goto basic_json_parser_14;
7465 basic_json_parser_17:
7468 return token_type::name_separator;
7470 basic_json_parser_19:
7473 return token_type::begin_array;
7475 basic_json_parser_21:
7478 return token_type::end_array;
7480 basic_json_parser_23:
7482 yych = *(m_marker = ++m_cursor);
7485 goto basic_json_parser_39;
7487 goto basic_json_parser_5;
7488 basic_json_parser_24:
7490 yych = *(m_marker = ++m_cursor);
7493 goto basic_json_parser_40;
7495 goto basic_json_parser_5;
7496 basic_json_parser_25:
7498 yych = *(m_marker = ++m_cursor);
7501 goto basic_json_parser_41;
7503 goto basic_json_parser_5;
7504 basic_json_parser_26:
7507 return token_type::begin_object;
7509 basic_json_parser_28:
7512 return token_type::end_object;
7514 basic_json_parser_30:
7516 yych = *(m_marker = ++m_cursor);
7519 goto basic_json_parser_42;
7521 goto basic_json_parser_5;
7522 basic_json_parser_31:
7524 if (m_limit <= m_cursor)
7529 basic_json_parser_32:
7530 if (yybm[0 + yych] & 128)
7532 goto basic_json_parser_31;
7536 goto basic_json_parser_33;
7540 goto basic_json_parser_34;
7542 goto basic_json_parser_36;
7543 basic_json_parser_33:
7544 m_cursor = m_marker;
7547 goto basic_json_parser_5;
7551 goto basic_json_parser_14;
7553 basic_json_parser_34:
7556 return token_type::value_string;
7558 basic_json_parser_36:
7560 if (m_limit <= m_cursor)
7571 goto basic_json_parser_31;
7575 goto basic_json_parser_33;
7577 goto basic_json_parser_31;
7585 goto basic_json_parser_33;
7587 goto basic_json_parser_31;
7593 goto basic_json_parser_31;
7595 goto basic_json_parser_33;
7605 goto basic_json_parser_31;
7609 goto basic_json_parser_31;
7611 goto basic_json_parser_33;
7619 goto basic_json_parser_31;
7621 goto basic_json_parser_33;
7627 goto basic_json_parser_31;
7631 goto basic_json_parser_43;
7633 goto basic_json_parser_33;
7637 basic_json_parser_37:
7641 goto basic_json_parser_33;
7645 goto basic_json_parser_44;
7647 goto basic_json_parser_33;
7648 basic_json_parser_38:
7654 goto basic_json_parser_46;
7656 goto basic_json_parser_33;
7662 goto basic_json_parser_46;
7666 goto basic_json_parser_33;
7670 goto basic_json_parser_47;
7672 goto basic_json_parser_33;
7674 basic_json_parser_39:
7678 goto basic_json_parser_49;
7680 goto basic_json_parser_33;
7681 basic_json_parser_40:
7685 goto basic_json_parser_50;
7687 goto basic_json_parser_33;
7688 basic_json_parser_41:
7692 goto basic_json_parser_51;
7694 goto basic_json_parser_33;
7695 basic_json_parser_42:
7699 goto basic_json_parser_52;
7701 goto basic_json_parser_33;
7702 basic_json_parser_43:
7704 if (m_limit <= m_cursor)
7713 goto basic_json_parser_33;
7717 goto basic_json_parser_54;
7719 goto basic_json_parser_33;
7725 goto basic_json_parser_54;
7729 goto basic_json_parser_33;
7733 goto basic_json_parser_54;
7735 goto basic_json_parser_33;
7737 basic_json_parser_44:
7739 m_marker = ++m_cursor;
7740 if ((m_limit - m_cursor) < 3)
7749 goto basic_json_parser_14;
7753 goto basic_json_parser_44;
7755 goto basic_json_parser_14;
7761 goto basic_json_parser_38;
7765 goto basic_json_parser_38;
7767 goto basic_json_parser_14;
7769 basic_json_parser_46:
7773 goto basic_json_parser_33;
7777 goto basic_json_parser_33;
7779 basic_json_parser_47:
7781 if (m_limit <= m_cursor)
7788 goto basic_json_parser_14;
7792 goto basic_json_parser_47;
7794 goto basic_json_parser_14;
7795 basic_json_parser_49:
7799 goto basic_json_parser_55;
7801 goto basic_json_parser_33;
7802 basic_json_parser_50:
7806 goto basic_json_parser_56;
7808 goto basic_json_parser_33;
7809 basic_json_parser_51:
7813 goto basic_json_parser_58;
7815 goto basic_json_parser_33;
7816 basic_json_parser_52:
7821 basic_json_parser_54:
7823 if (m_limit <= m_cursor)
7832 goto basic_json_parser_33;
7836 goto basic_json_parser_60;
7838 goto basic_json_parser_33;
7844 goto basic_json_parser_60;
7848 goto basic_json_parser_33;
7852 goto basic_json_parser_60;
7854 goto basic_json_parser_33;
7856 basic_json_parser_55:
7860 goto basic_json_parser_61;
7862 goto basic_json_parser_33;
7863 basic_json_parser_56:
7866 return token_type::literal_null;
7868 basic_json_parser_58:
7871 return token_type::literal_true;
7873 basic_json_parser_60:
7875 if (m_limit <= m_cursor)
7884 goto basic_json_parser_33;
7888 goto basic_json_parser_63;
7890 goto basic_json_parser_33;
7896 goto basic_json_parser_63;
7900 goto basic_json_parser_33;
7904 goto basic_json_parser_63;
7906 goto basic_json_parser_33;
7908 basic_json_parser_61:
7911 return token_type::literal_false;
7913 basic_json_parser_63:
7915 if (m_limit <= m_cursor)
7924 goto basic_json_parser_33;
7928 goto basic_json_parser_31;
7930 goto basic_json_parser_33;
7936 goto basic_json_parser_31;
7940 goto basic_json_parser_33;
7944 goto basic_json_parser_31;
7946 goto basic_json_parser_33;
7954 void yyfill() noexcept
7956 if (m_stream ==
nullptr or not * m_stream)
7961 const ssize_t offset_start = m_start - m_content;
7962 const ssize_t offset_marker = m_marker - m_start;
7963 const ssize_t offset_cursor = m_cursor - m_start;
7965 m_buffer.erase(0, static_cast<size_t>(offset_start));
7967 assert(m_stream !=
nullptr);
7968 std::getline(*m_stream, line);
7969 m_buffer +=
"\n" + line;
7971 m_content =
reinterpret_cast<const lexer_char_t*
>(m_buffer.c_str());
7972 assert(m_content !=
nullptr);
7973 m_start = m_content;
7974 m_marker = m_start + offset_marker;
7975 m_cursor = m_start + offset_cursor;
7976 m_limit = m_start + m_buffer.size() - 1;
7980 string_t get_token()
const noexcept
7982 assert(m_start !=
nullptr);
7983 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
7984 static_cast<size_t>(m_cursor - m_start));
8011 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
8014 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
8070 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
8071 4).c_str(),
nullptr, 16);
8074 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
8077 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
8079 throw std::invalid_argument(
"missing low surrogate");
8083 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
8084 (i + 7), 4).c_str(),
nullptr, 16);
8085 result += to_unicode(codepoint, codepoint2);
8092 result += to_unicode(codepoint);
8104 result.append(1, static_cast<typename string_t::value_type>(*i));
8131 long double str_to_float_t(
long double* ,
char** endptr)
const 8133 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8151 double str_to_float_t(
double* ,
char** endptr)
const 8153 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8171 float str_to_float_t(
float* ,
char** endptr)
const 8173 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
8188 template <
typename T_A,
typename T_B>
8189 bool attempt_cast(T_A source, T_B& dest)
const 8191 dest =
static_cast<T_B
>(source);
8192 return (source == static_cast<T_A>(dest));
8233 void get_number(basic_json& result)
const 8235 typename string_t::value_type* endptr;
8236 assert(m_start !=
nullptr);
8241 if (*reinterpret_cast<typename string_t::const_pointer>(m_start) !=
'-')
8245 if (attempt_cast(std::strtoull(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8246 10), result.m_value.number_unsigned))
8248 result.m_type = value_t::number_unsigned;
8253 result.m_type = value_t::number_float;
8260 if (attempt_cast(std::strtoll(reinterpret_cast<typename string_t::const_pointer>(m_start), &endptr,
8261 10), result.m_value.number_integer))
8263 result.m_type = value_t::number_integer;
8268 result.m_type = value_t::number_float;
8274 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor || errno == ERANGE)
8276 result.m_type = value_t::number_float;
8279 if (result.m_type == value_t::number_float)
8286 result.m_value.number_float = str_to_float_t(static_cast<number_float_t*>(
nullptr), &endptr);
8289 if (reinterpret_cast<lexer_char_t*>(endptr) != m_cursor)
8291 throw std::invalid_argument(std::string(
"parse error - ") + get_token() +
" is not a number");
8298 std::istream* m_stream =
nullptr;
8302 const lexer_char_t* m_content =
nullptr;
8304 const lexer_char_t* m_start =
nullptr;
8306 const lexer_char_t* m_marker =
nullptr;
8308 const lexer_char_t* m_cursor =
nullptr;
8310 const lexer_char_t* m_limit =
nullptr;
8323 : callback(cb), m_lexer(s)
8331 : callback(cb), m_lexer(&_is)
8340 basic_json result = parse_internal(
true);
8342 expect(lexer::token_type::end_of_input);
8351 basic_json parse_internal(
bool keep)
8353 auto result = basic_json(value_t::discarded);
8357 case lexer::token_type::begin_object:
8359 if (keep and (not callback or (keep = callback(depth++, parse_event_t::object_start, result))))
8362 result.m_type = value_t::object;
8363 result.m_value = json_value(value_t::object);
8370 if (last_token == lexer::token_type::end_object)
8373 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8375 result = basic_json(value_t::discarded);
8381 unexpect(lexer::token_type::value_separator);
8387 if (last_token == lexer::token_type::value_separator)
8393 expect(lexer::token_type::value_string);
8394 const auto key = m_lexer.get_string();
8396 bool keep_tag =
false;
8402 keep_tag = callback(depth, parse_event_t::key, k);
8412 expect(lexer::token_type::name_separator);
8416 auto value = parse_internal(keep);
8417 if (keep and keep_tag and not value.is_discarded())
8419 result[key] = std::move(value);
8422 while (last_token == lexer::token_type::value_separator);
8425 expect(lexer::token_type::end_object);
8427 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
8429 result = basic_json(value_t::discarded);
8435 case lexer::token_type::begin_array:
8437 if (keep and (not callback or (keep = callback(depth++, parse_event_t::array_start, result))))
8440 result.m_type = value_t::array;
8441 result.m_value = json_value(value_t::array);
8448 if (last_token == lexer::token_type::end_array)
8451 if (callback and not callback(--depth, parse_event_t::array_end, result))
8453 result = basic_json(value_t::discarded);
8459 unexpect(lexer::token_type::value_separator);
8465 if (last_token == lexer::token_type::value_separator)
8471 auto value = parse_internal(keep);
8472 if (keep and not value.is_discarded())
8474 result.push_back(std::move(value));
8477 while (last_token == lexer::token_type::value_separator);
8480 expect(lexer::token_type::end_array);
8482 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
8484 result = basic_json(value_t::discarded);
8490 case lexer::token_type::literal_null:
8493 result.m_type = value_t::null;
8497 case lexer::token_type::value_string:
8499 const auto s = m_lexer.get_string();
8501 result = basic_json(s);
8505 case lexer::token_type::literal_true:
8508 result.m_type = value_t::boolean;
8509 result.m_value =
true;
8513 case lexer::token_type::literal_false:
8516 result.m_type = value_t::boolean;
8517 result.m_value =
false;
8521 case lexer::token_type::value_number:
8523 m_lexer.get_number(result);
8531 unexpect(last_token);
8535 if (keep and callback and not callback(depth, parse_event_t::value, result))
8537 result = basic_json(value_t::discarded);
8543 typename lexer::token_type get_token()
8545 last_token = m_lexer.scan();
8549 void expect(
typename lexer::token_type t)
const 8551 if (t != last_token)
8553 std::string error_msg =
"parse error - unexpected ";
8554 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8555 lexer::token_type_name(last_token));
8556 error_msg +=
"; expected " + lexer::token_type_name(t);
8557 throw std::invalid_argument(error_msg);
8561 void unexpect(
typename lexer::token_type t)
const 8563 if (t == last_token)
8565 std::string error_msg =
"parse error - unexpected ";
8566 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token() +
"'") :
8567 lexer::token_type_name(last_token));
8568 throw std::invalid_argument(error_msg);
8578 typename lexer::token_type last_token = lexer::token_type::uninitialized;
8616 is_nothrow_move_constructible<nlohmann::json>::value and
8617 is_nothrow_move_assignable<nlohmann::json>::value
8635 const auto& h = hash<nlohmann::json::string_t>();
8653 inline nlohmann::json operator "" _json(
const char* s, std::size_t)
8659 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 8660 #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.