29 #ifndef NLOHMANN_JSON_HPP 30 #define NLOHMANN_JSON_HPP 43 #include <initializer_list> 55 #include <type_traits> 60 #if defined(__clang__) 61 #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) 62 #if CLANG_VERSION < 30400 63 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 65 #elif defined(__GNUC__) 66 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 67 #if GCC_VERSION < 40900 68 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" 73 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 74 #pragma GCC diagnostic push 75 #pragma GCC diagnostic ignored "-Wfloat-equal" 79 #if defined(__clang__) 80 #pragma GCC diagnostic push 81 #pragma GCC diagnostic ignored "-Wdocumentation" 85 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 86 #define JSON_DEPRECATED __attribute__((deprecated)) 87 #elif defined(_MSC_VER) 88 #define JSON_DEPRECATED __declspec(deprecated) 90 #define JSON_DEPRECATED 119 struct has_mapped_type
122 template <
typename U,
typename =
typename U::mapped_type>
123 static int detect(U&&);
125 static void detect(...);
128 std::is_integral<decltype(detect(std::declval<T>()))>::
value;
212 template<
typename U,
typename V,
typename... Args>
class ObjectType =
std::map,
213 template<
typename U,
typename... Args>
class ArrayType = std::vector,
215 class BooleanType = bool,
218 class NumberFloatType = double,
219 template<
typename U>
class AllocatorType = std::allocator
226 BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
263 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
378 using object_t = ObjectType<StringType,
380 std::less<StringType>,
381 AllocatorType<std::pair<
const StringType,
428 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
760 template<
typename T,
typename... Args>
763 AllocatorType<T> alloc;
766 alloc.deallocate(
object, 1);
768 std::unique_ptr<T, decltype(deleter)>
object(alloc.allocate(1), deleter);
769 alloc.construct(
object.
get(), std::forward<Args>(
args)...);
770 assert(
object.
get() !=
nullptr);
771 return object.release();
836 object = create<object_t>();
842 array = create<array_t>();
848 string = create<string_t>(
"");
852 case value_t::boolean:
858 case value_t::number_integer:
864 case value_t::number_unsigned:
870 case value_t::number_float:
886 string = create<string_t>(
value);
892 object = create<object_t>(
value);
898 array = create<array_t>(
value);
1003 basic_json& parsed)>;
1055 : m_type(value_type), m_value(value_type)
1135 template<
class CompatibleObjectType,
typename std::enable_if<
1143 m_value.object = create<object_t>(
begin(val),
end(val));
1198 template<
class CompatibleArrayType,
typename std::enable_if<
1211 m_value.array = create<array_t>(
begin(val),
end(val));
1291 template<
class CompatibleStringType,
typename std::enable_if<
1314 : m_type(value_t::boolean), m_value(
val)
1342 template<
typename T,
typename std::enable_if<
1346 : m_type(value_t::number_integer), m_value(
val)
1377 : m_type(value_t::number_integer),
1378 m_value(static_cast<number_integer_t>(
val))
1408 template<
typename CompatibleNumberIntegerType,
typename std::enable_if<
1411 std::numeric_limits<CompatibleNumberIntegerType>::is_signed,
1412 CompatibleNumberIntegerType>
::type = 0>
1414 : m_type(value_t::number_integer),
1415 m_value(static_cast<number_integer_t>(
val))
1437 template<
typename T,
typename std::enable_if<
1441 : m_type(value_t::number_unsigned), m_value(
val)
1466 template<
typename CompatibleNumberUnsignedType,
typename std::enable_if <
1469 not std::numeric_limits<CompatibleNumberUnsignedType>::is_signed,
1470 CompatibleNumberUnsignedType>::type = 0>
1472 : m_type(value_t::number_unsigned),
1473 m_value(static_cast<number_unsigned_t>(
val))
1503 : m_type(value_t::number_float), m_value(
val)
1506 if (not std::isfinite(
val))
1508 m_type = value_t::null;
1546 template<
typename CompatibleNumberFloatType,
typename =
typename std::enable_if<
1625 bool type_deduction =
true,
1630 bool is_an_object = std::all_of(init.begin(), init.end(),
1633 return element.is_array() and element.size() == 2 and element[0].is_string();
1637 if (not type_deduction)
1642 is_an_object =
false;
1648 throw std::domain_error(
"cannot create object from initializer list");
1658 std::for_each(init.begin(), init.end(), [
this](
const basic_json & element)
1660 m_value.object->emplace(*(element[0].m_value.string), element[1]);
1667 m_value.array = create<array_t>(
init);
1708 std::initializer_list<basic_json>())
1748 std::initializer_list<basic_json>())
1774 m_value.array = create<array_t>(cnt,
val);
1815 template<
class InputIT,
typename std::enable_if<
1820 assert(first.m_object !=
nullptr);
1821 assert(last.m_object !=
nullptr);
1824 if (first.m_object != last.m_object)
1826 throw std::domain_error(
"iterators are not compatible");
1830 m_type = first.m_object->m_type;
1835 case value_t::boolean:
1836 case value_t::number_float:
1837 case value_t::number_integer:
1838 case value_t::number_unsigned:
1841 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
1843 throw std::out_of_range(
"iterators out of range");
1856 case value_t::number_integer:
1858 m_value.number_integer = first.m_object->m_value.number_integer;
1862 case value_t::number_unsigned:
1864 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
1868 case value_t::number_float:
1870 m_value.number_float = first.m_object->m_value.number_float;
1874 case value_t::boolean:
1876 m_value.boolean = first.m_object->m_value.boolean;
1882 m_value = *first.m_object->m_value.string;
1888 m_value.object = create<object_t>(first.m_it.object_iterator, last.m_it.object_iterator);
1894 m_value.array = create<array_t>(first.m_it.array_iterator, last.m_it.array_iterator);
1900 throw std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name());
1938 *
this =
parser(i, cb).parse();
1969 : m_type(other.m_type)
1994 case value_t::boolean:
2000 case value_t::number_integer:
2006 case value_t::number_unsigned:
2012 case value_t::number_float:
2046 : m_type(
std::
move(other.m_type)),
2047 m_value(
std::
move(other.m_value))
2050 other.assert_invariant();
2053 other.m_type = value_t::null;
2093 swap(m_type, other.m_type);
2094 swap(m_value, other.m_value);
2123 AllocatorType<object_t> alloc;
2124 alloc.destroy(m_value.object);
2125 alloc.deallocate(m_value.object, 1);
2131 AllocatorType<array_t> alloc;
2132 alloc.destroy(m_value.array);
2133 alloc.deallocate(m_value.array, 1);
2139 AllocatorType<string_t> alloc;
2140 alloc.destroy(m_value.string);
2141 alloc.deallocate(m_value.string, 1);
2189 std::stringstream ss;
2197 ss.precision(std::numeric_limits<double>::digits10);
2201 dump(ss,
true, static_cast<unsigned int>(indent));
2261 return is_null() or is_string() or is_boolean() or is_number();
2288 return is_array() or is_object();
2310 return m_type == value_t::null;
2332 return m_type == value_t::boolean;
2362 return is_number_integer() or is_number_float();
2391 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
2419 return m_type == value_t::number_unsigned;
2447 return m_type == value_t::number_float;
2540 return m_type == value_t::discarded;
2574 template<
class T,
typename std::enable_if<
2581 return T(m_value.object->begin(), m_value.object->end());
2585 throw std::domain_error(
"type must be object, but is " + type_name());
2594 return *(m_value.object);
2598 throw std::domain_error(
"type must be object, but is " + type_name());
2603 template<
class T,
typename std::enable_if<
2615 std::inserter(to_vector, to_vector.end()), [](
basic_json i)
2617 return i.
get<
typename T::value_type>();
2623 throw std::domain_error(
"type must be array, but is " + type_name());
2628 template<
class T,
typename std::enable_if<
2635 std::vector<T> to_vector;
2636 to_vector.reserve(m_value.array->size());
2638 std::inserter(to_vector, to_vector.end()), [](
basic_json i)
2646 throw std::domain_error(
"type must be array, but is " + type_name());
2651 template<
class T,
typename std::enable_if<
2653 not has_mapped_type<T>::value,
int>::type = 0>
2658 return T(m_value.array->begin(), m_value.array->end());
2662 throw std::domain_error(
"type must be array, but is " + type_name());
2671 return *(m_value.array);
2675 throw std::domain_error(
"type must be array, but is " + type_name());
2680 template<
typename T,
typename std::enable_if<
2686 return *m_value.string;
2690 throw std::domain_error(
"type must be string, but is " + type_name());
2695 template<
typename T,
typename std::enable_if<
2701 case value_t::number_integer:
2703 return static_cast<T>(m_value.number_integer);
2706 case value_t::number_unsigned:
2708 return static_cast<T>(m_value.number_unsigned);
2711 case value_t::number_float:
2713 return static_cast<T>(m_value.number_float);
2718 throw std::domain_error(
"type must be number, but is " + type_name());
2728 :
throw std::domain_error(
"type must be boolean, but is " + type_name());
2734 return is_object() ? m_value.object :
nullptr;
2740 return is_object() ? m_value.object :
nullptr;
2746 return is_array() ? m_value.array :
nullptr;
2752 return is_array() ? m_value.array :
nullptr;
2758 return is_string() ? m_value.string :
nullptr;
2764 return is_string() ? m_value.string :
nullptr;
2770 return is_boolean() ? &m_value.boolean :
nullptr;
2776 return is_boolean() ? &m_value.boolean :
nullptr;
2782 return is_number_integer() ? &m_value.number_integer :
nullptr;
2788 return is_number_integer() ? &m_value.number_integer :
nullptr;
2794 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2800 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
2806 return is_number_float() ? &m_value.number_float :
nullptr;
2812 return is_number_float() ? &m_value.number_float :
nullptr;
2826 template<
typename ReferenceType,
typename ThisType>
2833 auto ptr = obj.template get_ptr<PointerType>();
2841 throw std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
2885 template<
typename ValueType,
typename std::enable_if<
2887 ValueType
get()
const 2889 return get_impl(static_cast<ValueType*>(
nullptr));
2919 template<
typename PointerType,
typename std::enable_if<
2921 PointerType
get() noexcept
2924 return get_ptr<PointerType>();
2931 template<
typename PointerType,
typename std::enable_if<
2932 std::is_pointer<PointerType>::value,
int>::type = 0>
2933 constexpr
const PointerType
get()
const noexcept
2936 return get_ptr<PointerType>();
2965 template<
typename PointerType,
typename std::enable_if<
2966 std::is_pointer<PointerType>::value,
int>::type = 0>
2970 using pointee_t =
typename std::remove_const<
typename 2971 std::remove_pointer<
typename 2982 ,
"incompatible pointer type");
2985 return get_impl_ptr(static_cast<PointerType>(
nullptr));
2992 template<
typename PointerType,
typename std::enable_if<
2993 std::is_pointer<PointerType>::value and
2995 constexpr
const PointerType
get_ptr() const noexcept
2998 using pointee_t =
typename std::remove_const<
typename 2999 std::remove_pointer<
typename 3010 ,
"incompatible pointer type");
3013 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
3042 template<
typename ReferenceType,
typename std::enable_if<
3047 return get_ref_impl<ReferenceType>(*this);
3054 template<
typename ReferenceType,
typename std::enable_if<
3055 std::is_reference<ReferenceType>::value and
3060 return get_ref_impl<ReferenceType>(*this);
3091 template <
typename ValueType,
typename std::enable_if <
3092 not std::is_pointer<ValueType>::value and
3094 #ifndef _MSC_VER // Fix for issue #167 operator<< abiguity under VS2015 3095 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3098 operator ValueType()
const 3101 return get<ValueType>();
3144 return m_value.
array->
at(idx);
3146 catch (std::out_of_range&)
3149 throw std::out_of_range(
"array index " +
std::to_string(idx) +
" is out of range");
3154 throw std::domain_error(
"cannot use at() with " + type_name());
3187 return m_value.
array->
at(idx);
3189 catch (std::out_of_range&)
3192 throw std::out_of_range(
"array index " +
std::to_string(idx) +
" is out of range");
3197 throw std::domain_error(
"cannot use at() with " + type_name());
3236 catch (std::out_of_range&)
3239 throw std::out_of_range(
"key '" + key +
"' not found");
3244 throw std::domain_error(
"cannot use at() with " + type_name());
3283 catch (std::out_of_range&)
3286 throw std::out_of_range(
"key '" + key +
"' not found");
3291 throw std::domain_error(
"cannot use at() with " + type_name());
3326 m_value.array = create<array_t>();
3334 if (idx >= m_value.array->size())
3336 m_value.array->insert(m_value.array->end(),
3337 idx - m_value.array->size() + 1,
3341 return m_value.array->operator[](
idx);
3345 throw std::domain_error(
"cannot use operator[] with " + type_name());
3373 return m_value.
array->operator[](
idx);
3377 throw std::domain_error(
"cannot use operator[] with " + type_name());
3414 m_value.object = create<object_t>();
3421 return m_value.object->operator[](
key);
3425 throw std::domain_error(
"cannot use operator[] with " + type_name());
3464 assert(m_value.object->find(key) != m_value.object->end());
3465 return m_value.object->find(key)->second;
3469 throw std::domain_error(
"cannot use operator[] with " + type_name());
3500 template<
typename T, std::
size_t n>
3503 return operator[](static_cast<const T>(
key));
3535 template<
typename T, std::
size_t n>
3538 return operator[](static_cast<const T>(
key));
3568 template<
typename T>
3582 return m_value.object->operator[](
key);
3586 throw std::domain_error(
"cannot use operator[] with " + type_name());
3620 template<
typename T>
3626 assert(m_value.object->find(key) != m_value.object->end());
3627 return m_value.object->find(key)->second;
3631 throw std::domain_error(
"cannot use operator[] with " + type_name());
3683 template<
class ValueType,
typename std::enable_if<
3685 ValueType
value(
const typename object_t::key_type&
key, ValueType default_value)
const 3691 const auto it =
find(key);
3698 return default_value;
3703 throw std::domain_error(
"cannot use value() with " + type_name());
3757 template<
class ValueType,
typename std::enable_if<
3758 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
3769 catch (std::out_of_range&)
3771 return default_value;
3776 throw std::domain_error(
"cannot use value() with " + type_name());
3919 template<
class IteratorType,
typename std::enable_if<
3926 if (
this != pos.m_object)
3928 throw std::domain_error(
"iterator does not fit current value");
3935 case value_t::boolean:
3936 case value_t::number_float:
3937 case value_t::number_integer:
3938 case value_t::number_unsigned:
3941 if (not pos.m_it.primitive_iterator.is_begin())
3943 throw std::out_of_range(
"iterator out of range");
3948 AllocatorType<string_t> alloc;
3949 alloc.destroy(m_value.string);
3950 alloc.deallocate(m_value.string, 1);
3951 m_value.string =
nullptr;
3954 m_type = value_t::null;
3961 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
3967 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
3973 throw std::domain_error(
"cannot use erase() with " + type_name());
4026 template<
class IteratorType,
typename std::enable_if<
4028 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
4033 if (
this != first.m_object or
this != last.m_object)
4035 throw std::domain_error(
"iterators do not fit current value");
4042 case value_t::boolean:
4043 case value_t::number_float:
4044 case value_t::number_integer:
4045 case value_t::number_unsigned:
4048 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
4050 throw std::out_of_range(
"iterators out of range");
4055 AllocatorType<string_t> alloc;
4056 alloc.destroy(m_value.string);
4057 alloc.deallocate(m_value.string, 1);
4058 m_value.string =
nullptr;
4061 m_type = value_t::null;
4068 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4069 last.m_it.object_iterator);
4075 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4076 last.m_it.array_iterator);
4082 throw std::domain_error(
"cannot use erase() with " + type_name());
4123 return m_value.object->erase(key);
4127 throw std::domain_error(
"cannot use erase() with " + type_name());
4162 throw std::out_of_range(
"array index " +
std::to_string(idx) +
" is out of range");
4169 throw std::domain_error(
"cannot use erase() with " + type_name());
4207 result.m_it.object_iterator = m_value.object->find(key);
4223 result.m_it.object_iterator = m_value.object->find(key);
4250 return is_object() ? m_value.object->count(key) : 0;
4625 return m_value.array->empty();
4631 return m_value.object->empty();
4693 return m_value.array->size();
4699 return m_value.object->size();
4753 return m_value.array->max_size();
4759 return m_value.object->max_size();
4809 case value_t::number_integer:
4811 m_value.number_integer = 0;
4815 case value_t::number_unsigned:
4817 m_value.number_unsigned = 0;
4821 case value_t::number_float:
4823 m_value.number_float = 0.0;
4827 case value_t::boolean:
4829 m_value.boolean =
false;
4835 m_value.string->clear();
4841 m_value.array->clear();
4847 m_value.object->clear();
4881 if (not(is_null() or is_array()))
4883 throw std::domain_error(
"cannot use push_back() with " + type_name());
4897 val.m_type = value_t::null;
4917 if (not(is_null() or is_array()))
4919 throw std::domain_error(
"cannot use push_back() with " + type_name());
4931 m_value.array->push_back(val);
4967 if (not(is_null() or is_object()))
4969 throw std::domain_error(
"cannot use push_back() with " + type_name());
4981 m_value.object->insert(val);
5021 if (is_object() and init.size() == 2 and init.begin()->is_string())
5024 push_back(
typename object_t::value_type(key, *(init.begin() + 1)));
5063 template<
class... Args>
5067 if (not(is_null() or is_array()))
5069 throw std::domain_error(
"cannot use emplace_back() with " + type_name());
5081 m_value.array->emplace_back(std::forward<Args>(
args)...);
5111 template<
class... Args>
5115 if (not(is_null() or is_object()))
5117 throw std::domain_error(
"cannot use emplace() with " + type_name());
5129 auto res = m_value.object->emplace(std::forward<Args>(
args)...);
5132 it.m_it.object_iterator =
res.first;
5135 return {
it,
res.second};
5168 throw std::domain_error(
"iterator does not fit current value");
5178 throw std::domain_error(
"cannot use insert() with " + type_name());
5188 return insert(pos,
val);
5223 throw std::domain_error(
"iterator does not fit current value");
5233 throw std::domain_error(
"cannot use insert() with " + type_name());
5272 throw std::domain_error(
"cannot use insert() with " + type_name());
5278 throw std::domain_error(
"iterator does not fit current value");
5284 throw std::domain_error(
"iterators do not fit");
5289 throw std::domain_error(
"passed iterators may not belong to container");
5330 throw std::domain_error(
"cannot use insert() with " + type_name());
5336 throw std::domain_error(
"iterator does not fit current value");
5403 throw std::domain_error(
"cannot use swap() with " + type_name());
5436 throw std::domain_error(
"cannot use swap() with " + type_name());
5469 throw std::domain_error(
"cannot use swap() with " + type_name());
5495 static constexpr std::array<uint8_t, 8>
order = {{
5508 if (
lhs == value_t::discarded or rhs == value_t::discarded)
5513 return order[
static_cast<std::size_t
>(
lhs)] < order[static_cast<std::size_t>(rhs)];
5542 const auto lhs_type =
lhs.type();
5543 const auto rhs_type = rhs.type();
5545 if (lhs_type == rhs_type)
5551 return *
lhs.m_value.array == *rhs.m_value.array;
5555 return *
lhs.m_value.object == *rhs.m_value.object;
5563 return *
lhs.m_value.string == *rhs.m_value.string;
5565 case value_t::boolean:
5567 return lhs.m_value.boolean == rhs.m_value.boolean;
5569 case value_t::number_integer:
5571 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5573 case value_t::number_unsigned:
5575 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5577 case value_t::number_float:
5579 return lhs.m_value.number_float == rhs.m_value.number_float;
5587 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5589 return static_cast<number_float_t>(
lhs.m_value.number_integer) == rhs.m_value.number_float;
5591 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5593 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5595 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5597 return static_cast<number_float_t>(
lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5599 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5601 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5603 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5605 return static_cast<number_integer_t>(
lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5607 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5609 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5665 return not (
lhs == rhs);
5697 return not
v.is_null();
5726 const auto lhs_type =
lhs.type();
5727 const auto rhs_type = rhs.type();
5729 if (lhs_type == rhs_type)
5735 return *
lhs.m_value.array < *rhs.m_value.array;
5739 return *
lhs.m_value.object < *rhs.m_value.object;
5747 return *
lhs.m_value.string < *rhs.m_value.string;
5749 case value_t::boolean:
5751 return lhs.m_value.boolean < rhs.m_value.boolean;
5753 case value_t::number_integer:
5755 return lhs.m_value.number_integer < rhs.m_value.number_integer;
5757 case value_t::number_unsigned:
5759 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
5761 case value_t::number_float:
5763 return lhs.m_value.number_float < rhs.m_value.number_float;
5771 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5773 return static_cast<number_float_t>(
lhs.m_value.number_integer) < rhs.m_value.number_float;
5775 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5777 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
5779 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5781 return static_cast<number_float_t>(
lhs.m_value.number_unsigned) < rhs.m_value.number_float;
5783 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5785 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5787 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5789 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5791 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5793 return static_cast<number_integer_t>(
lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
5821 return not (rhs <
lhs);
5843 return not (
lhs <= rhs);
5865 return not (
lhs < rhs);
5907 const bool pretty_print = (o.width() > 0);
5908 const auto indentation = (pretty_print ? o.width() : 0);
5921 const auto old_precision = o.precision(std::numeric_limits<double>::digits10);
5924 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
5927 o.imbue(old_locale);
5928 o.precision(old_precision);
5978 template<
class T, std::
size_t N>
6013 template<
typename CharT,
typename std::enable_if<
6020 return parser(reinterpret_cast<const char*>(s), cb).parse();
6050 return parser(i, cb).parse();
6103 template<
class IteratorType,
typename std::enable_if<
6105 std::random_access_iterator_tag,
6106 typename std::iterator_traits<IteratorType>::iterator_category>
::value,
int>::type = 0>
6112 assert(std::accumulate(first, last, std::make_pair<bool, int>(
true, 0),
6113 [&first](std::pair<bool, int>
res, decltype(*first)
val)
6120 static_assert(
sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
6121 "each element in the iterator range must have the size of 1 byte");
6127 return parser(
"").parse();
6130 return parser(first, last, cb).parse();
6173 template<
class ContiguousContainer,
typename std::enable_if<
6176 std::random_access_iterator_tag,
6177 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::
value 6235 template<
typename T>
6238 assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8);
6244 vec.push_back(static_cast<uint8_t>((number >> 070) & 0xff));
6245 vec.push_back(static_cast<uint8_t>((number >> 060) & 0xff));
6246 vec.push_back(static_cast<uint8_t>((number >> 050) & 0xff));
6247 vec.push_back(static_cast<uint8_t>((number >> 040) & 0xff));
6253 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
6254 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
6260 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6266 vec.push_back(static_cast<uint8_t>(number & 0xff));
6308 template<
typename T>
6311 if (current_index +
sizeof(
T) + 1 > vec.size())
6313 throw std::out_of_range(
"cannot read " +
std::to_string(
sizeof(
T)) +
" bytes from vector");
6318 for (
size_t i = 0;
i <
sizeof(
T); ++
i)
6320 *ptr++ = vec[current_index +
sizeof(
T) -
i];
6346 case value_t::boolean:
6353 case value_t::number_integer:
6425 case value_t::number_unsigned:
6459 case value_t::number_float:
6464 for (
size_t i = 0;
i < 8; ++
i)
6466 v.push_back(helper[7 -
i]);
6477 v.push_back(static_cast<uint8_t>(0xa0 | N));
6483 add_to_vector(v, 1, N);
6485 else if (N <= 65535)
6489 add_to_vector(v, 2, N);
6491 else if (N <= 4294967295)
6495 add_to_vector(v, 4, N);
6500 std::back_inserter(v));
6510 v.push_back(static_cast<uint8_t>(0x90 | N));
6512 else if (N <= 0xffff)
6516 add_to_vector(v, 2, N);
6518 else if (N <= 0xffffffff)
6522 add_to_vector(v, 4, N);
6528 to_msgpack_internal(
el, v);
6539 v.push_back(static_cast<uint8_t>(0x80 | (N & 0xf)));
6541 else if (N <= 65535)
6545 add_to_vector(v, 2, N);
6547 else if (N <= 4294967295)
6551 add_to_vector(v, 4, N);
6557 to_msgpack_internal(
el.first, v);
6558 to_msgpack_internal(
el.second, v);
6590 case value_t::boolean:
6596 case value_t::number_integer:
6639 v.push_back(static_cast<uint8_t>(0x20 + positive_number));
6645 add_to_vector(v, 1, positive_number);
6651 add_to_vector(v, 2, positive_number);
6657 add_to_vector(v, 4, positive_number);
6663 add_to_vector(v, 8, positive_number);
6669 case value_t::number_unsigned:
6702 case value_t::number_float:
6707 for (
size_t i = 0;
i < 8; ++
i)
6709 v.push_back(helper[7 -
i]);
6719 v.push_back(0x60 + N);
6724 add_to_vector(v, 1, N);
6726 else if (N <= 0xffff)
6729 add_to_vector(v, 2, N);
6731 else if (N <= 0xffffffff)
6734 add_to_vector(v, 4, N);
6737 else if (N <= 0xffffffffffffffff)
6740 add_to_vector(v, 8, N);
6746 std::back_inserter(v));
6755 v.push_back(0x80 + N);
6760 add_to_vector(v, 1, N);
6762 else if (N <= 0xffff)
6765 add_to_vector(v, 2, N);
6767 else if (N <= 0xffffffff)
6770 add_to_vector(v, 4, N);
6773 else if (N <= 0xffffffffffffffff)
6776 add_to_vector(v, 8, N);
6783 to_cbor_internal(
el, v);
6793 v.push_back(0xa0 + N);
6798 add_to_vector(v, 1, N);
6800 else if (N <= 0xffff)
6803 add_to_vector(v, 2, N);
6805 else if (N <= 0xffffffff)
6808 add_to_vector(v, 4, N);
6811 else if (N <= 0xffffffffffffffff)
6814 add_to_vector(v, 8, N);
6821 to_cbor_internal(
el.first, v);
6822 to_cbor_internal(
el.second, v);
6851 const size_t current_idx = idx++;
6853 if (v[current_idx] <= 0xbf)
6855 if (v[current_idx] <= 0x7f)
6857 return v[current_idx];
6859 else if (v[current_idx] <= 0x8f)
6862 const size_t len = v[current_idx] & 0x0f;
6863 for (
size_t i = 0;
i <
len; ++
i)
6866 result[
key] = from_msgpack_internal(v, idx);
6870 else if (v[current_idx] <= 0x9f)
6873 const size_t len = v[current_idx] & 0x0f;
6874 for (
size_t i = 0;
i <
len; ++
i)
6876 result.
push_back(from_msgpack_internal(v, idx));
6882 const size_t len = v[current_idx] & 0x1f;
6883 const size_t offset = current_idx + 1;
6885 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
6888 else if (v[current_idx] >= 0xe0)
6890 return static_cast<int8_t>(v[current_idx]);
6894 switch (v[current_idx])
6898 return value_t::null;
6917 reinterpret_cast<uint8_t*
>(&
res)[
sizeof(
float) -
byte - 1] = v[current_idx + 1 +
byte];
6919 idx +=
sizeof(float);
6929 reinterpret_cast<uint8_t*
>(&
res)[
sizeof(
double) -
byte - 1] = v[current_idx + 1 +
byte];
6931 idx +=
sizeof(double);
6938 return get_from_vector<uint8_t>(
v, current_idx);
6944 return get_from_vector<uint16_t>(
v, current_idx);
6950 return get_from_vector<uint32_t>(
v, current_idx);
6956 return get_from_vector<uint64_t>(
v, current_idx);
6962 return get_from_vector<int8_t>(
v, current_idx);
6968 return get_from_vector<int16_t>(
v, current_idx);
6974 return get_from_vector<int32_t>(
v, current_idx);
6980 return get_from_vector<int64_t>(
v, current_idx);
6985 const auto len = get_from_vector<uint8_t>(
v, current_idx);
6986 const size_t offset = current_idx + 2;
6988 return std::string(reinterpret_cast<const char*>(v.data()) + offset,
len);
6993 const auto len = get_from_vector<uint16_t>(
v, current_idx);
6994 const size_t offset = current_idx + 3;
6996 return std::string(reinterpret_cast<const char*>(v.data()) + offset,
len);
7001 const auto len = get_from_vector<uint32_t>(
v, current_idx);
7002 const size_t offset = current_idx + 5;
7004 return std::string(reinterpret_cast<const char*>(v.data()) + offset,
len);
7010 const auto len = get_from_vector<uint16_t>(
v, current_idx);
7012 for (
size_t i = 0;
i <
len; ++
i)
7014 result.
push_back(from_msgpack_internal(v, idx));
7022 const auto len = get_from_vector<uint32_t>(
v, current_idx);
7024 for (
size_t i = 0;
i <
len; ++
i)
7026 result.
push_back(from_msgpack_internal(v, idx));
7034 const auto len = get_from_vector<uint16_t>(
v, current_idx);
7036 for (
size_t i = 0;
i <
len; ++
i)
7039 result[
key] = from_msgpack_internal(v, idx);
7047 const auto len = get_from_vector<uint32_t>(
v, current_idx);
7049 for (
size_t i = 0;
i <
len; ++
i)
7052 result[
key] = from_msgpack_internal(v, idx);
7059 throw std::invalid_argument(
"error parsing a msgpack @ " +
std::to_string(current_idx));
7082 const size_t current_idx = idx++;
7084 switch (v[current_idx])
7112 return v[current_idx];
7118 return get_from_vector<uint8_t>(
v, current_idx);
7124 return get_from_vector<uint16_t>(
v, current_idx);
7130 return get_from_vector<uint32_t>(
v, current_idx);
7136 return get_from_vector<uint64_t>(
v, current_idx);
7165 return static_cast<int8_t>(0x20 - 1 - v[current_idx]);
7172 return static_cast<number_integer_t>(-1) - get_from_vector<uint8_t>(v, current_idx);
7178 return static_cast<number_integer_t>(-1) - get_from_vector<uint16_t>(v, current_idx);
7184 return static_cast<number_integer_t>(-1) - get_from_vector<uint32_t>(v, current_idx);
7190 return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_from_vector<uint64_t>(v, current_idx));
7219 const size_t len = v[current_idx] - 0x60;
7220 const size_t offset = current_idx + 1;
7222 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7227 const auto len = get_from_vector<uint8_t>(
v, current_idx);
7228 const size_t offset = current_idx + 2;
7230 return std::string(reinterpret_cast<const char*>(v.data()) + offset,
len);
7235 const auto len = get_from_vector<uint16_t>(
v, current_idx);
7236 const size_t offset = current_idx + 3;
7238 return std::string(reinterpret_cast<const char*>(v.data()) + offset,
len);
7243 const auto len = get_from_vector<uint32_t>(
v, current_idx);
7244 const size_t offset = current_idx + 5;
7246 return std::string(reinterpret_cast<const char*>(v.data()) + offset,
len);
7251 const auto len = get_from_vector<uint64_t>(
v, current_idx);
7252 const size_t offset = current_idx + 9;
7254 return std::string(reinterpret_cast<const char*>(v.data()) + offset,
len);
7260 while (v[idx] != 0xff)
7262 string_t s = from_cbor_internal(v, idx);
7297 const size_t len = v[current_idx] - 0x80;
7298 for (
size_t i = 0;
i <
len; ++
i)
7300 result.
push_back(from_cbor_internal(v, idx));
7308 const auto len = get_from_vector<uint8_t>(
v, current_idx);
7310 for (
size_t i = 0;
i <
len; ++
i)
7312 result.
push_back(from_cbor_internal(v, idx));
7320 const auto len = get_from_vector<uint16_t>(
v, current_idx);
7322 for (
size_t i = 0;
i <
len; ++
i)
7324 result.
push_back(from_cbor_internal(v, idx));
7332 const auto len = get_from_vector<uint32_t>(
v, current_idx);
7334 for (
size_t i = 0;
i <
len; ++
i)
7336 result.
push_back(from_cbor_internal(v, idx));
7344 const auto len = get_from_vector<uint64_t>(
v, current_idx);
7346 for (
size_t i = 0;
i <
len; ++
i)
7348 result.
push_back(from_cbor_internal(v, idx));
7356 while (v[idx] != 0xff)
7358 result.
push_back(from_cbor_internal(v, idx));
7392 const size_t len = v[current_idx] - 0xa0;
7393 for (
size_t i = 0;
i <
len; ++
i)
7396 result[
key] = from_cbor_internal(v, idx);
7404 const auto len = get_from_vector<uint8_t>(
v, current_idx);
7406 for (
size_t i = 0;
i <
len; ++
i)
7409 result[
key] = from_cbor_internal(v, idx);
7417 const auto len = get_from_vector<uint16_t>(
v, current_idx);
7419 for (
size_t i = 0;
i <
len; ++
i)
7422 result[
key] = from_cbor_internal(v, idx);
7430 const auto len = get_from_vector<uint32_t>(
v, current_idx);
7432 for (
size_t i = 0;
i <
len; ++
i)
7435 result[
key] = from_cbor_internal(v, idx);
7443 const auto len = get_from_vector<uint64_t>(
v, current_idx);
7445 for (
size_t i = 0;
i <
len; ++
i)
7448 result[
key] = from_cbor_internal(v, idx);
7456 while (v[idx] != 0xff)
7459 result[
key] = from_cbor_internal(v, idx);
7478 return value_t::null;
7492 const int half = (v[current_idx + 1] << 8) + v[current_idx + 2];
7493 const int exp = (half >> 10) & 0x1f;
7494 const int mant = half & 0x3ff;
7498 val = std::ldexp(mant, -24);
7502 val = std::ldexp(mant + 1024, exp - 25);
7506 val = mant == 0 ? INFINITY : NAN;
7508 return half & 0x8000 ? -val :
val;
7517 reinterpret_cast<uint8_t*
>(&
res)[
sizeof(
float) -
byte - 1] = v[current_idx + 1 +
byte];
7519 idx +=
sizeof(float);
7529 reinterpret_cast<uint8_t*
>(&
res)[
sizeof(
double) -
byte - 1] = v[current_idx + 1 +
byte];
7531 idx +=
sizeof(double);
7565 std::vector<uint8_t>
result;
7566 to_msgpack_internal(j, result);
7595 return from_msgpack_internal(v, i);
7621 std::vector<uint8_t>
result;
7622 to_cbor_internal(j, result);
7652 return from_cbor_internal(v, i);
7686 case value_t::boolean:
7688 case value_t::discarded:
7705 return std::accumulate(s.begin(), s.end(),
size_t{},
7706 [](
size_t res,
typename string_t::value_type
c)
7724 if (c >= 0x00 and c <= 0x1f)
7753 const auto space = extra_space(s);
7761 std::size_t
pos = 0;
7763 for (
const auto& c : s)
7825 if (c >= 0x00 and c <= 0x1f)
7829 static const char hexify[16] =
7831 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
7832 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f' 7837 {
'u',
'0',
'0', hexify[c >> 4], hexify[c & 0x0f]
7876 const bool pretty_print,
7877 const unsigned int indent_step,
7878 const unsigned int current_indent = 0)
const 7881 unsigned int new_indent = current_indent;
7887 if (m_value.object->empty())
7898 new_indent += indent_step;
7902 for (
auto i = m_value.object->cbegin();
i != m_value.object->cend(); ++
i)
7904 if (
i != m_value.object->cbegin())
7906 o << (pretty_print ?
",\n" :
",");
7908 o <<
string_t(new_indent,
' ') <<
"\"" 7909 << escape_string(
i->first) <<
"\":" 7910 << (pretty_print ?
" " :
"");
7911 i->second.dump(o, pretty_print, indent_step, new_indent);
7917 new_indent -= indent_step;
7921 o <<
string_t(new_indent,
' ') +
"}";
7927 if (m_value.array->empty())
7938 new_indent += indent_step;
7942 for (
auto i = m_value.array->cbegin();
i != m_value.array->cend(); ++
i)
7944 if (
i != m_value.array->cbegin())
7946 o << (pretty_print ?
",\n" :
",");
7949 i->dump(o, pretty_print, indent_step, new_indent);
7955 new_indent -= indent_step;
7959 o <<
string_t(new_indent,
' ') <<
"]";
7965 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
7969 case value_t::boolean:
7971 o << (m_value.boolean ?
"true" :
"false");
7975 case value_t::number_integer:
7977 o << m_value.number_integer;
7981 case value_t::number_unsigned:
7983 o << m_value.number_unsigned;
7987 case value_t::number_float:
7989 if (m_value.number_float == 0)
7992 o << (std::signbit(m_value.number_float) ?
"-0.0" :
"0.0");
7996 o << m_value.number_float;
8001 case value_t::discarded:
8059 return (m_it == begin_value);
8065 return (m_it == end_value);
8106 : object_iterator(), array_iterator(), primitive_iterator()
8111 template<
typename IteratorType>
8122 size_t array_index = 0;
8147 return anchor != o.
anchor;
8153 assert(anchor.m_object !=
nullptr);
8155 switch (anchor.m_object->type())
8166 return anchor.key();
8180 return anchor.value();
8226 template<
typename U>
8227 class iter_impl :
public std::iterator<std::random_access_iterator_tag, U>
8235 "iter_impl only accepts (const) basic_json");
8265 assert(m_object !=
nullptr);
8267 switch (m_object->m_type)
8271 m_it.object_iterator =
typename object_t::iterator();
8277 m_it.array_iterator =
typename array_t::iterator();
8316 : m_object(other.m_object), m_it(other.m_it)
8343 assert(m_object !=
nullptr);
8345 switch (m_object->m_type)
8349 m_it.object_iterator = m_object->m_value.object->begin();
8355 m_it.array_iterator = m_object->m_value.array->begin();
8362 m_it.primitive_iterator.set_end();
8368 m_it.primitive_iterator.set_begin();
8380 assert(m_object !=
nullptr);
8382 switch (m_object->m_type)
8386 m_it.object_iterator = m_object->m_value.object->end();
8392 m_it.array_iterator = m_object->m_value.array->end();
8398 m_it.primitive_iterator.set_end();
8411 assert(m_object !=
nullptr);
8413 switch (m_object->m_type)
8417 assert(m_it.object_iterator != m_object->m_value.object->end());
8418 return m_it.object_iterator->second;
8423 assert(m_it.array_iterator != m_object->m_value.array->end());
8424 return *m_it.array_iterator;
8429 throw std::out_of_range(
"cannot get value");
8434 if (m_it.primitive_iterator.is_begin())
8440 throw std::out_of_range(
"cannot get value");
8452 assert(m_object !=
nullptr);
8454 switch (m_object->m_type)
8458 assert(m_it.object_iterator != m_object->m_value.object->end());
8459 return &(m_it.object_iterator->second);
8464 assert(m_it.array_iterator != m_object->m_value.array->end());
8465 return &*m_it.array_iterator;
8470 if (m_it.primitive_iterator.is_begin())
8476 throw std::out_of_range(
"cannot get value");
8499 assert(m_object !=
nullptr);
8501 switch (m_object->m_type)
8517 ++m_it.primitive_iterator;
8542 assert(m_object !=
nullptr);
8544 switch (m_object->m_type)
8560 --m_it.primitive_iterator;
8577 throw std::domain_error(
"cannot compare iterators of different containers");
8580 assert(m_object !=
nullptr);
8582 switch (m_object->m_type)
8619 throw std::domain_error(
"cannot compare iterators of different containers");
8622 assert(m_object !=
nullptr);
8624 switch (m_object->m_type)
8628 throw std::domain_error(
"cannot compare order of object iterators");
8649 return not other.operator < (*this);
8676 assert(m_object !=
nullptr);
8678 switch (m_object->m_type)
8682 throw std::domain_error(
"cannot use offsets with object iterators");
8693 m_it.primitive_iterator +=
i;
8738 assert(m_object !=
nullptr);
8740 switch (m_object->m_type)
8744 throw std::domain_error(
"cannot use offsets with object iterators");
8765 assert(m_object !=
nullptr);
8767 switch (m_object->m_type)
8771 throw std::domain_error(
"cannot use operator[] for object iterators");
8776 return *
std::next(m_it.array_iterator, n);
8781 throw std::out_of_range(
"cannot get value");
8786 if (m_it.primitive_iterator == -n)
8792 throw std::out_of_range(
"cannot get value");
8802 typename object_t::key_type
key()
const 8804 assert(m_object !=
nullptr);
8806 if (m_object->is_object())
8808 return m_it.object_iterator->first;
8812 throw std::domain_error(
"cannot use key() for non-object iterators");
8849 template<
typename Base>
8884 return base_iterator::operator--(1);
8890 base_iterator::operator--();
8920 return this->base() - other.base();
8930 typename object_t::key_type
key()
const 8932 auto it = --this->base();
8939 auto it = --this->base();
8940 return it.operator * ();
8986 assert(m_content !=
nullptr);
8987 m_start = m_cursor = m_content;
8988 m_limit = m_content +
len;
8993 : m_stream(&s), m_line_buffer()
8998 throw std::invalid_argument(
"stream error: " +
std::string(strerror(errno)));
9005 if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) ==
"\xEF\xBB\xBF")
9007 m_line_buffer[0] =
' ';
9008 m_line_buffer[1] =
' ';
9009 m_line_buffer[2] =
' ';
9042 const std::size_t codepoint2 = 0)
9045 std::size_t codepoint = codepoint1;
9048 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
9051 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
9065 throw std::invalid_argument(
"missing or wrong low surrogate");
9071 if (codepoint < 0x80)
9074 result.append(1, static_cast<typename string_t::value_type>(codepoint));
9076 else if (codepoint <= 0x7ff)
9079 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
9080 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9082 else if (codepoint <= 0xffff)
9085 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
9086 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
9087 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9089 else if (codepoint <= 0x10ffff)
9092 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
9093 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
9094 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
9095 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9099 throw std::out_of_range(
"code points above 0x10FFFF are invalid");
9110 case token_type::uninitialized:
9111 return "<uninitialized>";
9112 case token_type::literal_true:
9113 return "true literal";
9114 case token_type::literal_false:
9115 return "false literal";
9116 case token_type::literal_null:
9117 return "null literal";
9118 case token_type::value_string:
9119 return "string literal";
9120 case token_type::value_number:
9121 return "number literal";
9122 case token_type::begin_array:
9124 case token_type::begin_object:
9126 case token_type::end_array:
9128 case token_type::end_object:
9130 case token_type::name_separator:
9132 case token_type::value_separator:
9134 case token_type::parse_error:
9135 return "<parse error>";
9136 case token_type::end_of_input:
9137 return "end of input";
9141 return "unknown token";
9176 assert(m_start !=
nullptr);
9181 unsigned int yyaccept = 0;
9182 static const unsigned char yybm[] =
9184 0, 0, 0, 0, 0, 0, 0, 0,
9185 0, 32, 32, 0, 0, 32, 0, 0,
9186 0, 0, 0, 0, 0, 0, 0, 0,
9187 0, 0, 0, 0, 0, 0, 0, 0,
9188 160, 128, 0, 128, 128, 128, 128, 128,
9189 128, 128, 128, 128, 128, 128, 128, 128,
9190 192, 192, 192, 192, 192, 192, 192, 192,
9191 192, 192, 128, 128, 128, 128, 128, 128,
9192 128, 128, 128, 128, 128, 128, 128, 128,
9193 128, 128, 128, 128, 128, 128, 128, 128,
9194 128, 128, 128, 128, 128, 128, 128, 128,
9195 128, 128, 128, 128, 0, 128, 128, 128,
9196 128, 128, 128, 128, 128, 128, 128, 128,
9197 128, 128, 128, 128, 128, 128, 128, 128,
9198 128, 128, 128, 128, 128, 128, 128, 128,
9199 128, 128, 128, 128, 128, 128, 128, 128,
9200 0, 0, 0, 0, 0, 0, 0, 0,
9201 0, 0, 0, 0, 0, 0, 0, 0,
9202 0, 0, 0, 0, 0, 0, 0, 0,
9203 0, 0, 0, 0, 0, 0, 0, 0,
9204 0, 0, 0, 0, 0, 0, 0, 0,
9205 0, 0, 0, 0, 0, 0, 0, 0,
9206 0, 0, 0, 0, 0, 0, 0, 0,
9207 0, 0, 0, 0, 0, 0, 0, 0,
9208 0, 0, 0, 0, 0, 0, 0, 0,
9209 0, 0, 0, 0, 0, 0, 0, 0,
9210 0, 0, 0, 0, 0, 0, 0, 0,
9211 0, 0, 0, 0, 0, 0, 0, 0,
9212 0, 0, 0, 0, 0, 0, 0, 0,
9213 0, 0, 0, 0, 0, 0, 0, 0,
9214 0, 0, 0, 0, 0, 0, 0, 0,
9215 0, 0, 0, 0, 0, 0, 0, 0,
9217 if ((m_limit - m_cursor) < 5)
9219 fill_line_buffer(5);
9222 if (yybm[0 + yych] & 32)
9224 goto basic_json_parser_6;
9234 goto basic_json_parser_2;
9238 goto basic_json_parser_4;
9240 goto basic_json_parser_9;
9246 goto basic_json_parser_4;
9250 goto basic_json_parser_10;
9252 goto basic_json_parser_12;
9261 goto basic_json_parser_4;
9265 goto basic_json_parser_13;
9267 goto basic_json_parser_15;
9273 goto basic_json_parser_17;
9277 goto basic_json_parser_4;
9279 goto basic_json_parser_19;
9291 goto basic_json_parser_21;
9293 goto basic_json_parser_4;
9299 goto basic_json_parser_23;
9303 goto basic_json_parser_4;
9305 goto basic_json_parser_24;
9314 goto basic_json_parser_25;
9316 goto basic_json_parser_4;
9322 goto basic_json_parser_26;
9326 goto basic_json_parser_28;
9328 goto basic_json_parser_4;
9332 basic_json_parser_2:
9335 last_token_type = token_type::end_of_input;
9338 basic_json_parser_4:
9340 basic_json_parser_5:
9342 last_token_type = token_type::parse_error;
9345 basic_json_parser_6:
9347 if (m_limit <= m_cursor)
9349 fill_line_buffer(1);
9352 if (yybm[0 + yych] & 32)
9354 goto basic_json_parser_6;
9359 basic_json_parser_9:
9361 yych = *(m_marker = ++m_cursor);
9364 goto basic_json_parser_5;
9368 goto basic_json_parser_31;
9372 goto basic_json_parser_5;
9376 goto basic_json_parser_31;
9378 goto basic_json_parser_5;
9379 basic_json_parser_10:
9382 last_token_type = token_type::value_separator;
9385 basic_json_parser_12:
9389 goto basic_json_parser_5;
9393 goto basic_json_parser_13;
9397 goto basic_json_parser_15;
9399 goto basic_json_parser_5;
9400 basic_json_parser_13:
9402 yych = *(m_marker = ++m_cursor);
9407 goto basic_json_parser_43;
9414 goto basic_json_parser_44;
9418 goto basic_json_parser_44;
9421 basic_json_parser_14:
9423 last_token_type = token_type::value_number;
9426 basic_json_parser_15:
9428 m_marker = ++m_cursor;
9429 if ((m_limit - m_cursor) < 3)
9431 fill_line_buffer(3);
9434 if (yybm[0 + yych] & 64)
9436 goto basic_json_parser_15;
9442 goto basic_json_parser_43;
9444 goto basic_json_parser_14;
9450 goto basic_json_parser_44;
9454 goto basic_json_parser_44;
9456 goto basic_json_parser_14;
9458 basic_json_parser_17:
9461 last_token_type = token_type::name_separator;
9464 basic_json_parser_19:
9467 last_token_type = token_type::begin_array;
9470 basic_json_parser_21:
9473 last_token_type = token_type::end_array;
9476 basic_json_parser_23:
9478 yych = *(m_marker = ++m_cursor);
9481 goto basic_json_parser_45;
9483 goto basic_json_parser_5;
9484 basic_json_parser_24:
9486 yych = *(m_marker = ++m_cursor);
9489 goto basic_json_parser_46;
9491 goto basic_json_parser_5;
9492 basic_json_parser_25:
9494 yych = *(m_marker = ++m_cursor);
9497 goto basic_json_parser_47;
9499 goto basic_json_parser_5;
9500 basic_json_parser_26:
9503 last_token_type = token_type::begin_object;
9506 basic_json_parser_28:
9509 last_token_type = token_type::end_object;
9512 basic_json_parser_30:
9514 if (m_limit <= m_cursor)
9516 fill_line_buffer(1);
9519 basic_json_parser_31:
9520 if (yybm[0 + yych] & 128)
9522 goto basic_json_parser_30;
9530 goto basic_json_parser_32;
9534 goto basic_json_parser_33;
9536 goto basic_json_parser_35;
9542 goto basic_json_parser_32;
9546 goto basic_json_parser_36;
9548 goto basic_json_parser_37;
9557 goto basic_json_parser_39;
9559 goto basic_json_parser_38;
9565 goto basic_json_parser_40;
9569 goto basic_json_parser_41;
9573 goto basic_json_parser_42;
9577 basic_json_parser_32:
9578 m_cursor = m_marker;
9581 goto basic_json_parser_5;
9585 goto basic_json_parser_14;
9587 basic_json_parser_33:
9590 last_token_type = token_type::value_string;
9593 basic_json_parser_35:
9595 if (m_limit <= m_cursor)
9597 fill_line_buffer(1);
9606 goto basic_json_parser_30;
9610 goto basic_json_parser_32;
9612 goto basic_json_parser_30;
9620 goto basic_json_parser_32;
9622 goto basic_json_parser_30;
9628 goto basic_json_parser_30;
9630 goto basic_json_parser_32;
9640 goto basic_json_parser_30;
9644 goto basic_json_parser_30;
9646 goto basic_json_parser_32;
9654 goto basic_json_parser_30;
9656 goto basic_json_parser_32;
9662 goto basic_json_parser_30;
9666 goto basic_json_parser_48;
9668 goto basic_json_parser_32;
9672 basic_json_parser_36:
9674 if (m_limit <= m_cursor)
9676 fill_line_buffer(1);
9681 goto basic_json_parser_32;
9685 goto basic_json_parser_30;
9687 goto basic_json_parser_32;
9688 basic_json_parser_37:
9690 if (m_limit <= m_cursor)
9692 fill_line_buffer(1);
9697 goto basic_json_parser_32;
9701 goto basic_json_parser_36;
9703 goto basic_json_parser_32;
9704 basic_json_parser_38:
9706 if (m_limit <= m_cursor)
9708 fill_line_buffer(1);
9713 goto basic_json_parser_32;
9717 goto basic_json_parser_36;
9719 goto basic_json_parser_32;
9720 basic_json_parser_39:
9722 if (m_limit <= m_cursor)
9724 fill_line_buffer(1);
9729 goto basic_json_parser_32;
9733 goto basic_json_parser_36;
9735 goto basic_json_parser_32;
9736 basic_json_parser_40:
9738 if (m_limit <= m_cursor)
9740 fill_line_buffer(1);
9745 goto basic_json_parser_32;
9749 goto basic_json_parser_38;
9751 goto basic_json_parser_32;
9752 basic_json_parser_41:
9754 if (m_limit <= m_cursor)
9756 fill_line_buffer(1);
9761 goto basic_json_parser_32;
9765 goto basic_json_parser_38;
9767 goto basic_json_parser_32;
9768 basic_json_parser_42:
9770 if (m_limit <= m_cursor)
9772 fill_line_buffer(1);
9777 goto basic_json_parser_32;
9781 goto basic_json_parser_38;
9783 goto basic_json_parser_32;
9784 basic_json_parser_43:
9788 goto basic_json_parser_32;
9792 goto basic_json_parser_49;
9794 goto basic_json_parser_32;
9795 basic_json_parser_44:
9801 goto basic_json_parser_51;
9803 goto basic_json_parser_32;
9809 goto basic_json_parser_51;
9813 goto basic_json_parser_32;
9817 goto basic_json_parser_52;
9819 goto basic_json_parser_32;
9821 basic_json_parser_45:
9825 goto basic_json_parser_54;
9827 goto basic_json_parser_32;
9828 basic_json_parser_46:
9832 goto basic_json_parser_55;
9834 goto basic_json_parser_32;
9835 basic_json_parser_47:
9839 goto basic_json_parser_56;
9841 goto basic_json_parser_32;
9842 basic_json_parser_48:
9844 if (m_limit <= m_cursor)
9846 fill_line_buffer(1);
9853 goto basic_json_parser_32;
9857 goto basic_json_parser_57;
9859 goto basic_json_parser_32;
9865 goto basic_json_parser_57;
9869 goto basic_json_parser_32;
9873 goto basic_json_parser_57;
9875 goto basic_json_parser_32;
9877 basic_json_parser_49:
9879 m_marker = ++m_cursor;
9880 if ((m_limit - m_cursor) < 3)
9882 fill_line_buffer(3);
9889 goto basic_json_parser_14;
9893 goto basic_json_parser_49;
9895 goto basic_json_parser_14;
9901 goto basic_json_parser_44;
9905 goto basic_json_parser_44;
9907 goto basic_json_parser_14;
9909 basic_json_parser_51:
9913 goto basic_json_parser_32;
9917 goto basic_json_parser_32;
9919 basic_json_parser_52:
9921 if (m_limit <= m_cursor)
9923 fill_line_buffer(1);
9928 goto basic_json_parser_14;
9932 goto basic_json_parser_52;
9934 goto basic_json_parser_14;
9935 basic_json_parser_54:
9939 goto basic_json_parser_58;
9941 goto basic_json_parser_32;
9942 basic_json_parser_55:
9946 goto basic_json_parser_59;
9948 goto basic_json_parser_32;
9949 basic_json_parser_56:
9953 goto basic_json_parser_61;
9955 goto basic_json_parser_32;
9956 basic_json_parser_57:
9958 if (m_limit <= m_cursor)
9960 fill_line_buffer(1);
9967 goto basic_json_parser_32;
9971 goto basic_json_parser_63;
9973 goto basic_json_parser_32;
9979 goto basic_json_parser_63;
9983 goto basic_json_parser_32;
9987 goto basic_json_parser_63;
9989 goto basic_json_parser_32;
9991 basic_json_parser_58:
9995 goto basic_json_parser_64;
9997 goto basic_json_parser_32;
9998 basic_json_parser_59:
10001 last_token_type = token_type::literal_null;
10004 basic_json_parser_61:
10007 last_token_type = token_type::literal_true;
10010 basic_json_parser_63:
10012 if (m_limit <= m_cursor)
10014 fill_line_buffer(1);
10021 goto basic_json_parser_32;
10025 goto basic_json_parser_66;
10027 goto basic_json_parser_32;
10033 goto basic_json_parser_66;
10037 goto basic_json_parser_32;
10041 goto basic_json_parser_66;
10043 goto basic_json_parser_32;
10045 basic_json_parser_64:
10048 last_token_type = token_type::literal_false;
10051 basic_json_parser_66:
10053 if (m_limit <= m_cursor)
10055 fill_line_buffer(1);
10062 goto basic_json_parser_32;
10066 goto basic_json_parser_30;
10068 goto basic_json_parser_32;
10074 goto basic_json_parser_30;
10078 goto basic_json_parser_32;
10082 goto basic_json_parser_30;
10084 goto basic_json_parser_32;
10090 return last_token_type;
10124 assert(m_line_buffer.empty()
10125 or m_content ==
reinterpret_cast<const lexer_char_t*
>(m_line_buffer.data()));
10128 assert(m_line_buffer.empty()
10129 or m_limit == m_content + m_line_buffer.size());
10132 assert(m_content <= m_start);
10133 assert(m_start <= m_cursor);
10134 assert(m_cursor <= m_limit);
10135 assert(m_marker ==
nullptr or m_marker <= m_limit);
10138 const size_t num_processed_chars =
static_cast<size_t>(m_start - m_content);
10140 const auto offset_marker = (m_marker ==
nullptr) ? 0 : m_marker - m_start;
10142 const auto offset_cursor = m_cursor - m_start;
10145 if (m_stream ==
nullptr or m_stream->eof())
10150 m_line_buffer.assign(m_start, m_limit);
10154 m_line_buffer.append(1,
'\x00');
10157 m_line_buffer.append(
n - 1,
'\x01');
10163 m_line_buffer.erase(0, num_processed_chars);
10165 m_line_buffer_tmp.clear();
10166 std::getline(*m_stream, m_line_buffer_tmp,
'\n');
10169 m_line_buffer += m_line_buffer_tmp;
10170 m_line_buffer.push_back(
'\n');
10174 m_content =
reinterpret_cast<const lexer_char_t*
>(m_line_buffer.data());
10175 assert(m_content !=
nullptr);
10176 m_start = m_content;
10177 m_marker = m_start + offset_marker;
10178 m_cursor = m_start + offset_cursor;
10179 m_limit = m_start + m_line_buffer.size();
10185 assert(m_start !=
nullptr);
10186 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
10187 static_cast<size_t>(m_cursor - m_start));
10249 assert(m_cursor - m_start >= 2);
10252 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
10262 for (
auto k =
i; k <
e; k++)
10264 result.push_back(static_cast<typename string_t::value_type>(*k));
10322 auto codepoint = std::strtoul(
std::string(reinterpret_cast<typename string_t::const_pointer>(
i + 1),
10323 4).c_str(),
nullptr, 16);
10326 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
10329 if ((
i + 6 >= m_limit) or * (
i + 5) !=
'\\' or * (
i + 6) !=
'u')
10331 throw std::invalid_argument(
"missing low surrogate");
10335 auto codepoint2 = std::strtoul(
std::string(reinterpret_cast<typename string_t::const_pointer>
10336 (
i + 7), 4).c_str(),
nullptr, 16);
10337 result += to_unicode(codepoint, codepoint2);
10341 else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
10344 throw std::invalid_argument(
"missing high surrogate");
10349 result += to_unicode(codepoint);
10378 return strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
10380 return std::strtold(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
10399 return std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
10418 return strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
10420 return std::strtof(reinterpret_cast<typename string_t::const_pointer>(m_start), endptr);
10447 assert(m_start !=
nullptr);
10461 if (*curptr ==
'-')
10463 type = value_t::number_integer;
10464 max =
static_cast<uint64_t>((std::numeric_limits<number_integer_t>::max)()) + 1;
10469 type = value_t::number_unsigned;
10470 max =
static_cast<uint64_t>((std::numeric_limits<number_unsigned_t>::max)());
10474 for (; curptr < m_cursor; curptr++)
10477 if (*curptr < '0' || *curptr >
'9')
10479 if (*curptr ==
'.')
10482 type = value_t::number_float;
10487 type = value_t::number_float;
10492 if (type != value_t::number_float)
10498 if (value > (max - digit) / 10)
10501 type = value_t::number_float;
10506 value = value * 10 + digit;
10512 if (type == value_t::number_unsigned)
10516 else if (type == value_t::number_integer)
10543 type = value_t::null;
10554 std::istream* m_stream =
nullptr;
10584 m_lexer(reinterpret_cast<const typename
lexer::lexer_char_t*>(buff),
std::strlen(buff))
10593 template<
class IteratorType,
typename std::enable_if<
10594 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>
::value 10599 m_lexer(reinterpret_cast<const typename
lexer::lexer_char_t*>(&(*first)),
10612 expect(lexer::token_type::end_of_input);
10625 switch (last_token)
10627 case lexer::token_type::begin_object:
10641 if (last_token == lexer::token_type::end_object)
10652 unexpect(lexer::token_type::value_separator);
10658 if (last_token == lexer::token_type::value_separator)
10664 expect(lexer::token_type::value_string);
10665 const auto key = m_lexer.get_string();
10667 bool keep_tag =
false;
10683 expect(lexer::token_type::name_separator);
10687 auto value = parse_internal(keep);
10688 if (keep and keep_tag and not
value.is_discarded())
10693 while (last_token == lexer::token_type::value_separator);
10696 expect(lexer::token_type::end_object);
10706 case lexer::token_type::begin_array:
10720 if (last_token == lexer::token_type::end_array)
10731 unexpect(lexer::token_type::value_separator);
10737 if (last_token == lexer::token_type::value_separator)
10743 auto value = parse_internal(keep);
10744 if (keep and not
value.is_discarded())
10749 while (last_token == lexer::token_type::value_separator);
10752 expect(lexer::token_type::end_array);
10762 case lexer::token_type::literal_null:
10765 result.m_type = value_t::null;
10769 case lexer::token_type::value_string:
10771 const auto s = m_lexer.get_string();
10777 case lexer::token_type::literal_true:
10780 result.m_type = value_t::boolean;
10785 case lexer::token_type::literal_false:
10788 result.m_type = value_t::boolean;
10793 case lexer::token_type::value_number:
10795 m_lexer.get_number(
result);
10803 unexpect(last_token);
10817 last_token = m_lexer.scan();
10823 if (t != last_token)
10825 std::string error_msg =
"parse error - unexpected ";
10826 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token_string() +
10828 lexer::token_type_name(last_token));
10829 error_msg +=
"; expected " + lexer::token_type_name(t);
10830 throw std::invalid_argument(error_msg);
10836 if (t == last_token)
10838 std::string error_msg =
"parse error - unexpected ";
10839 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token_string() +
10841 lexer::token_type_name(last_token));
10842 throw std::invalid_argument(error_msg);
10898 : reference_tokens(
split(s))
10918 return std::accumulate(reference_tokens.begin(),
10922 return a +
"/" + escape(
b);
10938 throw std::domain_error(
"JSON pointer has no parent");
10941 auto last = reference_tokens.back();
10942 reference_tokens.pop_back();
10949 return reference_tokens.empty();
10956 throw std::domain_error(
"JSON pointer has no parent");
10975 for (
const auto& reference_token : reference_tokens)
10977 switch (result->m_type)
10979 case value_t::null:
10981 if (reference_token ==
"0")
10984 result = &result->operator[](0);
10989 result = &result->operator[](reference_token);
10997 result = &result->operator[](reference_token);
11017 throw std::domain_error(
"invalid value to unflatten");
11046 for (
const auto& reference_token : reference_tokens)
11049 if (ptr->m_type == value_t::null)
11052 const bool nums = std::all_of(reference_token.begin(),
11053 reference_token.end(),
11056 return std::isdigit(
x);
11061 if (nums or reference_token ==
"-")
11071 switch (ptr->m_type)
11076 ptr = &ptr->operator[](reference_token);
11083 if (reference_token.size() > 1 and reference_token[0] ==
'0')
11085 throw std::domain_error(
"array index must not begin with '0'");
11088 if (reference_token ==
"-")
11091 ptr = &ptr->operator[](ptr->m_value.array->size());
11103 throw std::out_of_range(
"unresolved reference token '" + reference_token +
"'");
11113 for (
const auto& reference_token : reference_tokens)
11115 switch (ptr->m_type)
11120 ptr = &ptr->at(reference_token);
11126 if (reference_token ==
"-")
11129 throw std::out_of_range(
"array index '-' (" +
11131 ") is out of range");
11135 if (reference_token.size() > 1 and reference_token[0] ==
'0')
11137 throw std::domain_error(
"array index must not begin with '0'");
11141 ptr = &ptr->at(static_cast<size_type>(
std::stoi(reference_token)));
11147 throw std::out_of_range(
"unresolved reference token '" + reference_token +
"'");
11165 for (
const auto& reference_token : reference_tokens)
11167 switch (ptr->m_type)
11172 ptr = &ptr->operator[](reference_token);
11178 if (reference_token ==
"-")
11181 throw std::out_of_range(
"array index '-' (" +
11183 ") is out of range");
11187 if (reference_token.size() > 1 and reference_token[0] ==
'0')
11189 throw std::domain_error(
"array index must not begin with '0'");
11199 throw std::out_of_range(
"unresolved reference token '" + reference_token +
"'");
11209 for (
const auto& reference_token : reference_tokens)
11211 switch (ptr->m_type)
11216 ptr = &ptr->at(reference_token);
11222 if (reference_token ==
"-")
11225 throw std::out_of_range(
"array index '-' (" +
11227 ") is out of range");
11231 if (reference_token.size() > 1 and reference_token[0] ==
'0')
11233 throw std::domain_error(
"array index must not begin with '0'");
11237 ptr = &ptr->at(static_cast<size_type>(
std::stoi(reference_token)));
11243 throw std::out_of_range(
"unresolved reference token '" + reference_token +
"'");
11254 std::vector<std::string>
result;
11257 if (reference_string.empty())
11263 if (reference_string[0] !=
'/')
11265 throw std::domain_error(
"JSON pointer must be empty or begin with '/'");
11273 size_t slash = reference_string.find_first_of(
"/", 1),
11282 slash = reference_string.find_first_of(
"/",
start))
11286 auto reference_token = reference_string.substr(
start, slash -
start);
11289 for (
size_t pos = reference_token.find_first_of(
"~");
11290 pos != std::string::npos;
11291 pos = reference_token.find_first_of(
"~",
pos + 1))
11296 if (
pos == reference_token.size() - 1 or
11297 (reference_token[
pos + 1] !=
'0' and
11298 reference_token[
pos + 1] !=
'1'))
11300 throw std::domain_error(
"escape error: '~' must be followed with '0' or '1'");
11305 unescape(reference_token);
11306 result.push_back(reference_token);
11332 size_t pos = s.find(f);
11333 pos != std::string::npos;
11334 s.replace(
pos, f.size(),
t),
11335 pos = s.find(f,
pos + t.size())
11343 replace_substring(s,
"~",
"~0");
11344 replace_substring(s,
"/",
"~1");
11352 replace_substring(s,
"~1",
"/");
11354 replace_substring(s,
"~0",
"~");
11375 result[reference_string] =
nullptr;
11394 result[reference_string] =
nullptr;
11401 flatten(reference_string +
"/" + escape(element.first),
11402 element.second, result);
11411 result[reference_string] =
value;
11426 throw std::domain_error(
"only objects can be unflattened");
11434 if (not element.second.is_primitive())
11436 throw std::domain_error(
"values in object must be primitive");
11452 std::vector<std::string> reference_tokens {};
11602 json_pointer::flatten(
"", *
this, result);
11635 return json_pointer::unflatten(*
this);
11689 enum class patch_operations {add,
remove, replace,
move,
copy,
test, invalid};
11695 return patch_operations::add;
11697 if (op ==
"remove")
11699 return patch_operations::remove;
11701 if (op ==
"replace")
11703 return patch_operations::replace;
11715 return patch_operations::test;
11718 return patch_operations::invalid;
11733 if (top_pointer != ptr)
11735 result.
at(top_pointer);
11739 const auto last_path = ptr.
pop_back();
11744 case value_t::null:
11748 parent[last_path] =
val;
11754 if (last_path ==
"-")
11762 if (static_cast<size_type>(
idx) > parent.
size())
11765 throw std::out_of_range(
"array index " +
std::to_string(
idx) +
" is out of range");
11789 const auto last_path = ptr.
pop_back();
11796 auto it = parent.
find(last_path);
11797 if (
it != parent.
end())
11803 throw std::out_of_range(
"key '" + last_path +
"' not found");
11817 throw std::invalid_argument(
"JSON patch must be an array of objects");
11821 for (
const auto&
val : json_patch)
11829 auto it =
val.m_value.object->find(member);
11832 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
11835 if (
it ==
val.m_value.object->end())
11837 throw std::invalid_argument(error_msg +
" must have member '" + member +
"'");
11841 if (string_type and not
it->second.is_string())
11843 throw std::invalid_argument(error_msg +
" must have string member '" + member +
"'");
11851 if (not
val.is_object())
11853 throw std::invalid_argument(
"JSON patch must be an array of objects");
11857 const std::string op = get_value(
"op",
"op",
true);
11861 switch (get_op(op))
11863 case patch_operations::add:
11865 operation_add(ptr, get_value(
"add",
"value",
false));
11869 case patch_operations::remove:
11871 operation_remove(ptr);
11875 case patch_operations::replace:
11878 result.
at(ptr) = get_value(
"replace",
"value",
false);
11884 const std::string from_path = get_value(
"move",
"from",
true);
11894 operation_remove(from_ptr);
11895 operation_add(ptr, v);
11901 const std::string from_path = get_value(
"copy",
"from",
true);;
11905 result[ptr] = result.
at(from_ptr);
11909 case patch_operations::test:
11916 success = (result.
at(ptr) == get_value(
"test",
"value",
false));
11918 catch (std::out_of_range&)
11926 throw std::domain_error(
"unsuccessful: " +
val.dump());
11932 case patch_operations::invalid:
11936 throw std::invalid_argument(
"operation value '" + op +
"' is invalid");
11984 if (source == target)
11989 if (source.
type() != target.
type())
12001 switch (source.
type())
12007 while (i < source.
size() and i < target.
size())
12011 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
12020 while (i < source.
size())
12033 while (i < target.
size())
12039 {
"value", target[
i]}
12053 const auto key = json_pointer::escape(
it.key());
12055 if (target.
find(
it.key()) != target.
end())
12058 auto temp_diff = diff(
it.value(), target[
it.key()],
path +
"/" +
key);
12059 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
12075 if (source.
find(
it.key()) == source.
end())
12078 const auto key = json_pointer::escape(
it.key());
12083 {
"value",
it.value()}
12162 const auto&
h = hash<nlohmann::json::string_t>();
12163 return h(j.
dump());
12205 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 12206 #pragma GCC diagnostic pop
json_value(const object_t &value)
constructor for objects
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
std::string type_name() const
return the type as string
json_reverse_iterator & operator--()
pre-decrement (–it)
void swap(string_t &other)
exchanges the values
json_value(const array_t &value)
constructor for arrays
const_iterator end() const noexcept
returns a const iterator to one past the last element
size_type max_size() const noexcept
returns the maximum possible number of elements
object_t::iterator object_iterator
iterator for JSON objects
BOOST_FORCEINLINE T * addressof(T &v)
iter_impl & operator+=(difference_type i)
add to iterator
iter_impl & operator--()
pre-decrement (–it)
std::bidirectional_iterator_tag iterator_category
the category of the iterator
const value_type & const_reference
the type of an element const reference
GLboolean GLboolean GLboolean b
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
object_t::key_type key() const
return the key of an object iterator
difference_type operator-(const json_reverse_iterator &other) const
return difference
GLenum GLsizei const void * pointer
constexpr bool is_structured() const noexcept
return whether type is structured
bool is_root() const
return whether pointer points to the root document
json_reverse_iterator operator--(int)
post-decrement (it–)
#define expect(expr, value)
iterator insert(const_iterator pos, const basic_json &val)
inserts element
number_integer_t number_integer
number (integer)
reference operator[](difference_type n) const
access to successor
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
parser(const char *buff, const parser_callback_t cb=nullptr)
a parser reading from a string literal
void assert_invariant() const
checks the class invariants
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
std::ptrdiff_t difference_type
a type to represent differences between iterators
basic_json unflatten() const
unflatten a previously flattened JSON value
an iterator for primitive JSON types
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
GLdouble GLdouble GLint GLint order
std::pair< iterator, bool > emplace(Args &&...args)
add an object to an object if key does not exist
double str_to_float_t(double *, char **endptr) const
parse floating point number
reference get_and_create(reference j) const
create and return a reference to the pointed to value
bool operator==(const plane &lhs, const plane &rhs)
json_value(const string_t &value)
constructor for strings
bool operator!=(failed, failed)
const_reference front() const
access the first element
constexpr bool is_primitive() const noexcept
return whether type is primitive
number_float_t number_float
number (floating-point)
ValueType get() const
get a value (explicit)
lexer(const lexer_char_t *buff, const size_t len) noexcept
a lexer from a buffer with given length
static basic_json unflatten(const basic_json &value)
static basic_json parse(T(&array)[N], const parser_callback_t cb=nullptr)
deserialize from an array
AllocatorType< basic_json > allocator_type
the allocator type
void push_back(const basic_json &val)
add an object to an array
basic_json(const number_float_t val) noexcept
create a floating-point number (explicit)
static basic_json parse(const CharT s, const parser_callback_t cb=nullptr)
deserialize from string literal
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
const_reference back() const
access the last element
std::vector< uint32_t > split(const std::string &s, char delim)
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
static basic_json from_msgpack_internal(const std::vector< uint8_t > &v, size_t &idx)
create a JSON value from a given MessagePack vector
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
helper class for iteration
const_iterator cend() const noexcept
returns a const iterator to one past the last element
string_t * string
string (stored with pointer to save storage)
std::string hexify(unsigned char n)
a class to store JSON values
GLsizei const GLchar *const * path
basic_json(const CompatibleStringType &val)
create a string (implicit)
iter_impl operator-(difference_type i)
subtract from iterator
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
ImVec4 operator*(const ImVec4 &color, float t)
constexpr bool is_discarded() const noexcept
return whether value is discarded
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
constexpr bool is_object() const noexcept
return whether value is an object
typename basic_json::difference_type difference_type
a type to represent differences between iterators
typename std::conditional< std::is_const< U >::value, typename basic_json::const_reference, typename basic_json::reference >::type reference
defines a reference to the type iterated over (value_type)
static void flatten(const std::string &reference_string, const basic_json &value, basic_json &result)
Easylogging++ entry namespace.
PointerType get_ptr() noexcept
get a pointer value (implicit)
GLint GLint GLsizei GLsizei GLsizei depth
object_t get_impl(object_t *) const
get an object (explicit)
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json >>> object_t
a type for an object
static void add_to_vector(std::vector< uint8_t > &vec, size_t bytes, const T number)
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
reference get_unchecked(pointer ptr) const
return a reference to the pointed to value
GLsizei const GLchar *const * string
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
size_type size() const noexcept
returns the number of elements
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
copy assignment
static allocator_type get_allocator()
returns the allocator associated with the container
constexpr bool is_array() const noexcept
return whether value is an array
std::array< point3d, 4 > object
basic_json(const CompatibleObjectType &val)
create an object (implicit)
json_value(boolean_t v) noexcept
constructor for booleans
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
basic_json(const CompatibleNumberFloatType val) noexcept
create an floating-point number (implicit)
iter_impl & operator=(iter_impl other) noexcept(std::is_nothrow_move_constructible< pointer >::value andstd::is_nothrow_move_assignable< pointer >::value andstd::is_nothrow_move_constructible< internal_iterator >::value andstd::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
GLfloat GLfloat GLfloat GLfloat h
friend bool operator==(const_reference v, std::nullptr_t) noexcept
comparison: equal
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
IteratorType::reference value() const
return value of the iterator
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value andstd::is_nothrow_move_assignable< value_t >::value andstd::is_nothrow_move_constructible< json_value >::value andstd::is_nothrow_move_assignable< json_value >::value)
exchanges the values
void emplace_back(Args &&...args)
add an object to an array
GLsizei GLsizei GLfloat distance
iter_impl(pointer object) noexcept
constructor for a given JSON instance
void set_end() noexcept
set the iterator past the last value
reference operator+=(std::initializer_list< basic_json > init)
add an object to an object
static void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
iterator end() noexcept
returns an iterator to one past the last element
basic_json(const int val) noexcept
create an integer number from an enum type (explicit)
basic_json(const CompatibleArrayType &val)
create an array (implicit)
reference back()
access the last element
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
bool operator>(const iter_impl &other) const
comparison: greater than
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
GLboolean GLboolean GLboolean GLboolean a
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
basic_json flatten() const
return flattened JSON value
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
reference operator+=(const basic_json &val)
add an object to an array
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
iter_impl operator++(int)
post-increment (it++)
NumberFloatType number_float_t
a type for a number (floating-point)
static basic_json parse(std::istream &&i, const parser_callback_t cb=nullptr)
deserialize from stream
void set_end() noexcept
set iterator to a defined past the end
json_reverse_iterator operator+(difference_type i) const
add to iterator
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
static constexpr bool value
static T parse(const mxArray *cell)
basic_json(const value_t value_type)
create an empty value with a given type
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
reference operator*() const
return a reference to the value pointed to by the iterator
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
bool operator==(const iter_impl &other) const
comparison: equal
string_t get_string() const
return string value for string tokens
static basic_json from_cbor_internal(const std::vector< uint8_t > &v, size_t &idx)
create a JSON value from a given CBOR vector
static basic_json parse(const ContiguousContainer &c, const parser_callback_t cb=nullptr)
deserialize from a container with contiguous storage
iter_impl & operator-=(difference_type i)
subtract from iterator
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
friend class basic_json
allow basic_json to access private members
iter_impl operator--(int)
post-decrement (it–)
json_reverse_iterator & operator+=(difference_type i)
add to iterator
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
static T * create(Args &&...args)
helper for exception-safe object creation
static void unescape(std::string &s)
unescape tilde and slash
difference_type operator-(const iter_impl &other) const
return difference
number_unsigned_t number_unsigned
number (unsigned integer)
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
basic_json(const object_t &val)
create an object (explicit)
ImVec4 operator+(const ImVec4 &c, float v)
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
parser(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr)
a parser reading from an iterator range with contiguous storage
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
basic_json(const string_t &val)
create a string (explicit)
basic_json::string_t key() const
return key of the iterator
unsigned char lexer_char_t
the char type to use in the lexer
bool operator!=(const iter_impl &other) const
comparison: not equal
static std::size_t extra_space(const string_t &s) noexcept
calculates the extra space to escape a JSON string
iterator find(typename object_t::key_type key)
find an element in a JSON object
constexpr bool is_number() const noexcept
return whether value is a number
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
reference get_checked(pointer ptr) const
array_t get_impl(array_t *) const
get an array (explicit)
void set_begin() noexcept
set iterator to a defined beginning
lexer(std::istream &s)
a lexer from an input stream
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
static std::string token_type_name(const token_type t)
return name of values of type token_type (only used for errors)
void swap(object_t &other)
exchanges the values
BooleanType boolean_t
a type for a boolean
reference operator[](T *(&key)[n])
access specified object element
void unexpect(typename lexer::token_type t) const
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
array_t::iterator array_iterator
iterator for JSON arrays
json_reverse_iterator & operator++()
pre-increment (++it)
namespace for Niels Lohmann
parse_event_t
JSON callback events.
constexpr bool is_end() const noexcept
return whether the iterator is at end
bool operator<(failed, failed)
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
internal_iterator() noexcept
create an uninitialized internal_iterator
constexpr bool is_string() const noexcept
return whether value is a string
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
pointer operator->() const
dereference the iterator
basic_json value_type
the type of elements in a basic_json container
basic_json(boolean_t val) noexcept
create a boolean (explicit)
unsigned __int64 uint64_t
std::vector< std::string > reference_tokens
the reference tokens
IteratorType anchor
the iterator
json_value(value_t t)
constructor for empty values of a given type
std::string to_string() const noexcept
return a string representation of the JSON pointer
basic_json(basic_json &&other) noexcept
move constructor
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
basic_json(const typename string_t::value_type *val)
create a string (explicit)
object_t::key_type key() const
return the key of an object iterator
ValueType value(const json_pointer &ptr, ValueType default_value) const
access specified object element via JSON Pointer with default value
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
internal_iterator m_it
the actual iterator of the associated instance
std::vector< T > get_impl(std::vector< T > *) const
get an array (explicit)
const_reference at(size_type idx) const
access specified array element with bounds checking
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
reference operator+=(const typename object_t::value_type &val)
add an object to an object
std::size_t size_type
a type to represent container sizes
reference value() const
return the value of an iterator
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
reference operator+=(basic_json &&val)
add an object to an array
const_reference get_unchecked(const_pointer ptr) const
return a const reference to the pointed to value
json_value m_value
the value of the current element
void dump(std::ostream &o, const bool pretty_print, const unsigned int indent_step, const unsigned int current_indent=0) const
internal implementation of the serialization function
reference operator[](size_type idx)
access specified array element
const_iterator begin() const noexcept
returns a const iterator to the first element
friend bool operator!=(const_reference v, std::nullptr_t) noexcept
comparison: not equal
primitive_iterator_t primitive_iterator
generic iterator for all other types
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value andis_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
const_iterator cbegin() const noexcept
returns a const iterator to the first element
token_type
token types for the parser
array (ordered collection of values)
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
value_t m_type
the type of the current element
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
basic_json(const CompatibleNumberUnsignedType val) noexcept
create an unsigned number (implicit)
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
json_reverse_iterator operator++(int)
post-increment (it++)
auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &
static void to_cbor_internal(const basic_json &j, std::vector< uint8_t > &v)
create a CBOR serialization of a given JSON value
constexpr bool is_boolean() const noexcept
return whether value is a boolean
std::string pop_back()
remove and return last reference pointer
void push_back(basic_json &&val)
add an object to an array
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
ReferenceType get_ref()
get a reference value (implicit)
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
NumberIntegerType number_integer_t
a type for a number (integer)
lexer::token_type get_token()
get next token from lexer
basic_json(const number_unsigned_t val) noexcept
create an unsigned integer number (explicit)
iterator insert(const_iterator pos, basic_json &&val)
inserts element
bool empty() const noexcept
checks whether the container is empty
bool operator<=(const iter_impl &other) const
comparison: less than or equal
JSON_DEPRECATED basic_json(std::istream &i, const parser_callback_t cb=nullptr)
construct a JSON value given an input stream
basic_json(const number_integer_t val) noexcept
create an integer number (explicit)
void next(auto_any_t cur, type2type< T, C > *)
constexpr bool is_null() const noexcept
return whether value is null
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
typename std::conditional< std::is_const< U >::value, typename basic_json::const_pointer, typename basic_json::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
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
void get_number(basic_json &result) const
return number value for number tokens
const_reference operator[](T *key) const
read-only access specified object element
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
pointer m_object
associated JSON instance
static void to_msgpack_internal(const basic_json &j, std::vector< uint8_t > &v)
create a MessagePack serialization of a given JSON value
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
proxy class for the iterator_wrapper functions
value_t
the JSON type enumeration
basic_json parse_internal(bool keep)
the actual parser
IteratorType erase(IteratorType pos)
remove element given an iterator
const_reference get_checked(const_pointer ptr) const
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
json_pointer(const std::string &s="")
create JSON pointer
reference at(size_type idx)
access specified array element with bounds checking
static string_t escape_string(const string_t &s)
escape a string
constexpr boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
static basic_json from_msgpack(const std::vector< uint8_t > &v)
create a JSON value from a byte vector in MessagePack format
basic_json(const CompatibleNumberIntegerType val) noexcept
create an integer number (implicit)
void push_back(const typename object_t::value_type &val)
add an object to an object
string_t dump(const int indent=-1) const
serialization
void expect(typename lexer::token_type t) const
reference value() const
return the value of an iterator
static basic_json parse(std::istream &i, const parser_callback_t cb=nullptr)
deserialize from stream
object (unordered set of name/value pairs)
IteratorType::reference container
the container to iterate
ReferenceType get_ref() const
get a reference value (implicit)
friend bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
basic_json(const array_t &val)
create an array (explicit)
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a MessagePack serialization of a given JSON value
GLsizei GLsizei GLchar * source
iteration_proxy(typename IteratorType::reference cont)
construct iteration proxy from a container
iter_impl operator+(difference_type i)
add to iterator
int stoi(const std::string &value)
T * array_end(T BOOST_RANGE_ARRAY_REF()[sz])
object_t * object
object (stored with pointer to save storage)
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
iter_impl(const iter_impl &other) noexcept
copy constructor
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
reference operator[](difference_type n) const
access to successor
static std::string escape(std::string s)
escape tilde and slash
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
GLuint GLenum GLenum transform
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
void erase(const size_type idx)
remove element from a JSON array given an index
static string_t to_unicode(const std::size_t codepoint1, const std::size_t codepoint2=0)
create a string from one or two Unicode code points
void clear() noexcept
clears the contents
a template for a reverse iterator class
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
T get_impl(T *) const
get an object (explicit)
static T get_from_vector(const std::vector< uint8_t > &vec, const size_t current_index)
take sufficient bytes from a vector to fill an integer variable
static basic_json from_cbor(const std::vector< uint8_t > &v)
create a JSON value from a byte vector in CBOR format
long double str_to_float_t(long double *, char **endptr) const
parse floating point number
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
iteration_proxy_internal(IteratorType it) noexcept
reference operator[](T *key)
access specified object element
iter_impl & operator++()
pre-increment (++it)
friend bool operator!=(std::nullptr_t, const_reference v) noexcept
comparison: not equal
typename Base::reference reference
the reference type for the pointed-to element
boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type operator++(iterator_facade< I, V, TC, R, D > &i, int)
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
void fill_line_buffer(size_t n=0)
append data from the stream to the line buffer
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: not equal
basic_json parse()
public parser interface
bool operator<(const iter_impl &other) const
comparison: smaller
iterator begin() noexcept
returns an iterator to the first element
GLint GLint GLint GLint j2
GeneratorWrapper< T > map(Func &&function, GeneratorWrapper< U > &&generator)
float str_to_float_t(float *, char **endptr) const
parse floating point number
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
StringType string_t
a type for a string
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
static basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr)
deserialize from an iterator range with contiguous storage
reference front()
access the first element
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
void set_begin() noexcept
set the iterator to the first value
friend bool operator==(std::nullptr_t, const_reference v) noexcept
comparison: equal
basic_json(const basic_json &other)
copy constructor
a template for a random access iterator for the basic_json class
string_t get_token_string() const
return string representation of last read token
parser(std::istream &is, const parser_callback_t cb=nullptr)
a parser reading from an input stream
ArrayType< basic_json, AllocatorType< basic_json >> array_t
a type for an array
void copy(void *dst, void const *src, size_t size)
const_reference operator[](size_type idx) const
access specified array element
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
bool operator<=(failed, failed)
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
array_t * array
array (stored with pointer to save storage)
void push_back(std::initializer_list< basic_json > init)
add an object to an object
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
void swap(array_t &other)
exchanges the values
std::string to_string(T value)
reference operator[](const typename object_t::key_type &key)
access specified object element