29 #ifndef NLOHMANN_JSON_HPP 30 #define NLOHMANN_JSON_HPP 42 #include <forward_list> 44 #include <initializer_list> 56 #include <type_traits> 61 #if defined(__clang__) 62 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 63 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" 65 #elif defined(__GNUC__) 66 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900 72 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 73 #pragma GCC diagnostic push 74 #pragma GCC diagnostic ignored "-Wfloat-equal" 78 #if defined(__clang__) 79 #pragma GCC diagnostic push 80 #pragma GCC diagnostic ignored "-Wdocumentation" 84 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 85 #define JSON_DEPRECATED __attribute__((deprecated)) 86 #elif defined(_MSC_VER) 87 #define JSON_DEPRECATED __declspec(deprecated) 89 #define JSON_DEPRECATED 93 #if not defined(JSON_NOEXCEPTION) || defined(__EXCEPTIONS) 94 #define JSON_THROW(exception) throw exception 96 #define JSON_CATCH(exception) catch(exception) 98 #define JSON_THROW(exception) std::abort() 99 #define JSON_TRY if(true) 100 #define JSON_CATCH(exception) if(false) 173 static constexpr std::array<uint8_t, 8> order = {{
191 return order[
static_cast<std::size_t
>(lhs)] <
192 order[static_cast<std::size_t>(rhs)];
201 template<
bool B,
typename T =
void>
210 std::integral_constant<bool, std::is_convertible<T, int>::value and
211 std::is_enum<T>::value>;
228 template<
class B1,
class... Bn>
229 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
231 template<
class B>
struct negation : std::integral_constant < bool, !B::value > {};
247 template<
typename BasicJsonType>
248 static void construct(BasicJsonType& j,
typename BasicJsonType::boolean_t
b) noexcept
252 j.assert_invariant();
259 template<
typename BasicJsonType>
260 static void construct(BasicJsonType& j,
const typename BasicJsonType::string_t&
s)
264 j.assert_invariant();
271 template<
typename BasicJsonType>
272 static void construct(BasicJsonType& j,
typename BasicJsonType::number_float_t val) noexcept
275 if (not std::isfinite(val))
284 j.assert_invariant();
291 template<
typename BasicJsonType>
292 static void construct(BasicJsonType& j,
typename BasicJsonType::number_unsigned_t val) noexcept
296 j.assert_invariant();
303 template<
typename BasicJsonType>
304 static void construct(BasicJsonType& j,
typename BasicJsonType::number_integer_t val) noexcept
308 j.assert_invariant();
315 template<
typename BasicJsonType>
316 static void construct(BasicJsonType& j,
const typename BasicJsonType::array_t& arr)
320 j.assert_invariant();
323 template<
typename BasicJsonType,
typename CompatibleArrayType,
325 typename BasicJsonType::array_t>::value,
327 static void construct(BasicJsonType& j,
const CompatibleArrayType& arr)
332 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
333 j.assert_invariant();
340 template<
typename BasicJsonType>
341 static void construct(BasicJsonType& j,
const typename BasicJsonType::object_t& obj)
345 j.assert_invariant();
348 template<
typename BasicJsonType,
typename CompatibleObjectType,
350 typename BasicJsonType::object_t>::value,
352 static void construct(BasicJsonType& j,
const CompatibleObjectType& obj)
358 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
359 j.assert_invariant();
378 #define NLOHMANN_JSON_HAS_HELPER(type) \ 379 template<typename T> struct has_##type { \ 381 template<typename U, typename = typename U::type> \ 382 static int detect(U &&); \ 383 static void detect(...); \ 385 static constexpr bool value = \ 386 std::is_integral<decltype(detect(std::declval<T>()))>::value; \ 394 #undef NLOHMANN_JSON_HAS_HELPER 397 template<
bool B,
class RealType,
class CompatibleObjectType>
400 template<
class RealType,
class CompatibleObjectType>
403 static constexpr
auto value =
404 std::is_constructible<
typename RealType::key_type,
405 typename CompatibleObjectType::key_type>::value and
406 std::is_constructible<
typename RealType::mapped_type,
407 typename CompatibleObjectType::mapped_type>::value;
410 template<
class BasicJsonType,
class CompatibleObjectType>
415 has_mapped_type<CompatibleObjectType>,
416 has_key_type<CompatibleObjectType>>::value,
417 typename BasicJsonType::object_t, CompatibleObjectType >::value;
420 template<
typename BasicJsonType,
typename T>
423 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
424 std::is_same<T, typename BasicJsonType::const_iterator>::value or
425 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
426 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value or
427 std::is_same<T, typename BasicJsonType::json_pointer>::value;
430 template<
class BasicJsonType,
class CompatibleArrayType>
433 static auto constexpr value =
436 BasicJsonType, CompatibleArrayType>>,
437 negation<std::is_constructible<
typename BasicJsonType::string_t,
438 CompatibleArrayType>>,
440 has_value_type<CompatibleArrayType>,
441 has_iterator<CompatibleArrayType>>::value;
444 template<
bool,
typename,
typename>
447 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
454 static constexpr
auto value =
455 std::is_constructible<RealIntegerType,
456 CompatibleNumberIntegerType>::value and
457 CompatibleLimits::is_integer and
458 RealLimits::is_signed == CompatibleLimits::is_signed;
461 template<
typename RealIntegerType,
typename CompatibleNumberIntegerType>
464 static constexpr
auto value =
466 std::is_integral<CompatibleNumberIntegerType>::value and
467 not std::is_same<bool, CompatibleNumberIntegerType>::value,
468 RealIntegerType, CompatibleNumberIntegerType > ::value;
473 template<
typename BasicJsonType,
typename T>
479 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
480 static int detect(U&&);
481 static void detect(...);
484 static constexpr
bool value = std::is_integral<decltype(
485 detect(std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
490 template<
typename BasicJsonType,
typename T>
498 static int detect(U&&);
499 static void detect(...);
502 static constexpr
bool value = std::is_integral<decltype(detect(
503 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
507 template<
typename BasicJsonType,
typename T>
512 std::declval<BasicJsonType&>(), std::declval<T>()))>
513 static int detect(U&&);
514 static void detect(...);
517 static constexpr
bool value = std::is_integral<decltype(detect(
518 std::declval<
typename BasicJsonType::template json_serializer<T, void>>()))>::value;
526 template<
typename BasicJsonType,
typename T,
enable_if_t<
527 std::is_same<T, typename BasicJsonType::boolean_t>::value,
int> = 0>
533 template<
typename BasicJsonType,
typename CompatibleString,
534 enable_if_t<std::is_constructible<
typename BasicJsonType::string_t,
535 CompatibleString>::value,
int> = 0>
536 void to_json(BasicJsonType& j,
const CompatibleString&
s)
541 template<
typename BasicJsonType,
typename FloatType,
543 void to_json(BasicJsonType& j, FloatType val) noexcept
549 typename BasicJsonType,
typename CompatibleNumberUnsignedType,
551 CompatibleNumberUnsignedType>::value,
int> = 0 >
552 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
558 typename BasicJsonType,
typename CompatibleNumberIntegerType,
560 CompatibleNumberIntegerType>::value,
int> = 0 >
561 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
566 template<
typename BasicJsonType,
typename UnscopedEnumType,
568 void to_json(BasicJsonType& j, UnscopedEnumType
e) noexcept
574 typename BasicJsonType,
typename CompatibleArrayType,
577 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
579 void to_json(BasicJsonType& j,
const CompatibleArrayType& arr)
585 typename BasicJsonType,
typename CompatibleObjectType,
588 void to_json(BasicJsonType& j,
const CompatibleObjectType& arr)
599 template<
typename BasicJsonType,
typename ArithmeticType,
601 not std::is_same<ArithmeticType,
602 typename BasicJsonType::boolean_t>::value,
606 switch (static_cast<value_t>(j))
610 val =
static_cast<ArithmeticType
>(
611 *j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
616 val =
static_cast<ArithmeticType
>(
617 *j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
622 val =
static_cast<ArithmeticType
>(
623 *j.template get_ptr<const typename BasicJsonType::number_float_t*>());
629 std::domain_error(
"type must be number, but is " + j.type_name()));
634 template<
typename BasicJsonType>
635 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t&
b)
637 if (not j.is_boolean())
639 JSON_THROW(std::domain_error(
"type must be boolean, but is " + j.type_name()));
641 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
644 template<
typename BasicJsonType>
645 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t&
s)
647 if (not j.is_string())
649 JSON_THROW(std::domain_error(
"type must be string, but is " + j.type_name()));
651 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
654 template<
typename BasicJsonType>
655 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
660 template<
typename BasicJsonType>
661 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
666 template<
typename BasicJsonType>
667 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
672 template<
typename BasicJsonType,
typename UnscopedEnumType,
673 enable_if_t<is_unscoped_enum<UnscopedEnumType>::value,
int> = 0>
678 e =
static_cast<UnscopedEnumType
>(val);
681 template<
typename BasicJsonType>
682 void from_json(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr)
684 if (not j.is_array())
686 JSON_THROW(std::domain_error(
"type must be array, but is " + j.type_name()));
688 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
692 template<
typename BasicJsonType,
typename T,
typename Allocator>
693 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>&
l)
699 JSON_THROW(std::domain_error(
"type must be array, but is " + j.type_name()));
701 if (not std::is_same<T, BasicJsonType>::value)
703 if (not j.is_array())
705 JSON_THROW(std::domain_error(
"type must be array, but is " + j.type_name()));
708 for (
auto it = j.rbegin(), end = j.rend(); it != end; ++it)
710 l.push_front(it->template get<T>());
714 template<
typename BasicJsonType,
typename CompatibleArrayType>
720 std::transform(j.begin(), j.end(),
721 std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
725 return i.template get<typename CompatibleArrayType::value_type>();
729 template<
typename BasicJsonType,
typename CompatibleArrayType>
732 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
738 arr.reserve(j.size());
740 j.begin(), j.end(), std::inserter(arr, end(arr)), [](
const BasicJsonType & i)
744 return i.template get<typename CompatibleArrayType::value_type>();
748 template<
typename BasicJsonType,
typename CompatibleArrayType,
750 not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
int> = 0>
751 void from_json(
const BasicJsonType& j, CompatibleArrayType& arr)
755 JSON_THROW(std::domain_error(
"type must be array, but is " + j.type_name()));
759 if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
761 if (not j.is_array())
763 JSON_THROW(std::domain_error(
"type must be array, but is " + j.type_name()));
769 template<
typename BasicJsonType,
typename CompatibleObjectType,
770 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
int> = 0>
771 void from_json(
const BasicJsonType& j, CompatibleObjectType& obj)
773 if (not j.is_object())
775 JSON_THROW(std::domain_error(
"type must be object, but is " + j.type_name()));
778 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
784 obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
791 template<
typename BasicJsonType,
typename ArithmeticType,
793 std::is_arithmetic<ArithmeticType>::value and
794 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
795 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
796 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
797 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
799 void from_json(
const BasicJsonType& j, ArithmeticType& val)
801 switch (static_cast<value_t>(j))
805 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
810 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
815 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
820 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
825 JSON_THROW(std::domain_error(
"type must be number, but is " + j.type_name()));
833 template<
typename BasicJsonType,
typename T>
835 -> decltype(
to_json(j, std::forward<T>(val)),
void())
837 return to_json(j, std::forward<T>(val));
840 template<
typename BasicJsonType,
typename T>
843 static_assert(
sizeof(BasicJsonType) == 0,
844 "could not find to_json() method in T's namespace");
848 template<
typename BasicJsonType,
typename T>
850 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val),
priority_tag<1> {})))
859 template<
typename BasicJsonType,
typename T>
867 template<
typename BasicJsonType,
typename T>
870 static_assert(
sizeof(BasicJsonType) == 0,
871 "could not find from_json() method in T's namespace");
875 template<
typename BasicJsonType,
typename T>
877 noexcept(noexcept(std::declval<from_json_fn>().call(j, val,
priority_tag<1> {})))
887 static constexpr T value{};
910 template<
typename =
void,
typename =
void>
922 template<
typename BasicJsonType,
typename ValueType>
923 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
938 template<
typename BasicJsonType,
typename ValueType>
939 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
1029 template<
typename U,
typename V,
typename... Args>
class ObjectType = std::map,
1030 template<
typename U,
typename... Args>
class ArrayType = std::vector,
1032 class BooleanType = bool,
1033 class NumberIntegerType = std::int64_t,
1034 class NumberUnsignedType = std::uint64_t,
1035 class NumberFloatType = double,
1036 template<
typename U>
class AllocatorType = std::allocator,
1037 template<
typename T,
typename SFINAE =
void>
class JSONSerializer =
adl_serializer 1045 BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
1046 AllocatorType, JSONSerializer>;
1054 template<
typename T,
typename SFINAE>
1083 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
1085 using const_pointer =
typename std::allocator_traits<allocator_type>::const_pointer;
1134 result[
"copyright"] =
"(C) 2013-2017 Niels Lohmann";
1135 result[
"name"] =
"JSON for Modern C++";
1136 result[
"url"] =
"https://github.com/nlohmann/json";
1139 {
"string",
"2.1.1"},
1146 result[
"platform"] =
"win32";
1147 #elif defined __linux__ 1148 result[
"platform"] =
"linux";
1149 #elif defined __APPLE__ 1150 result[
"platform"] =
"apple";
1151 #elif defined __unix__ 1152 result[
"platform"] =
"unix";
1154 result[
"platform"] =
"unknown";
1157 #if defined(__clang__) 1158 result[
"compiler"] = {{
"family",
"clang"}, {
"version", __clang_version__}};
1159 #elif defined(__ICC) || defined(__INTEL_COMPILER) 1160 result[
"compiler"] = {{
"family",
"icc"}, {
"version", __INTEL_COMPILER}};
1161 #elif defined(__GNUC__) || defined(__GNUG__) 1162 result[
"compiler"] = {{
"family",
"gcc"}, {
"version", std::to_string(__GNUC__) +
"." + std::to_string(__GNUC_MINOR__) +
"." + std::to_string(__GNUC_PATCHLEVEL__)}};
1163 #elif defined(__HP_cc) || defined(__HP_aCC) 1164 result[
"compiler"] =
"hp" 1165 #elif defined(__IBMCPP__) 1166 result[
"compiler"] = {{
"family",
"ilecpp"}, {
"version", __IBMCPP__}};
1167 #elif defined(_MSC_VER) 1168 result[
"compiler"] = {{
"family",
"msvc"}, {
"version", _MSC_VER}};
1169 #elif defined(__PGI) 1170 result[
"compiler"] = {{
"family",
"pgcpp"}, {
"version", __PGI}};
1171 #elif defined(__SUNPRO_CC) 1172 result[
"compiler"] = {{
"family",
"sunpro"}, {
"version", __SUNPRO_CC}};
1174 result[
"compiler"] = {{
"family",
"unknown"}, {
"version",
"unknown"}};
1178 result[
"compiler"][
"c++"] = std::to_string(__cplusplus);
1180 result[
"compiler"][
"c++"] =
"unknown";
1278 using object_t = ObjectType<StringType,
1280 std::less<StringType>,
1281 AllocatorType<std::pair<
const StringType,
1328 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
1625 template<
typename T,
typename... Args>
1628 AllocatorType<T> alloc;
1629 auto deleter = [&](T *
object)
1631 alloc.deallocate(
object, 1);
1633 std::unique_ptr<T, decltype(deleter)>
object(alloc.allocate(1), deleter);
1634 alloc.construct(
object.
get(), std::forward<Args>(args)...);
1635 assert(
object !=
nullptr);
1636 return object.release();
1701 object = create<object_t>();
1707 array = create<array_t>();
1713 string = create<string_t>(
"");
1750 JSON_THROW(std::domain_error(
"961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1"));
1760 string = create<string_t>(value);
1766 object = create<object_t>(value);
1772 array = create<array_t>(value);
1877 basic_json& parsed)>;
1917 : m_type(value_type), m_value(value_type)
1999 template<
typename CompatibleType,
typename U = detail::uncvref_t<CompatibleType>,
2000 detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
2001 not std::is_same<U, basic_json_t>::value and
2002 not detail::is_basic_json_nested_type<
2003 basic_json_t, U>::value and
2004 detail::has_to_json<basic_json, U>::value,
2007 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
2083 bool type_deduction =
true,
2088 bool is_an_object = std::all_of(init.begin(), init.end(),
2091 return element.is_array() and element.size() == 2 and element[0].is_string();
2095 if (not type_deduction)
2100 is_an_object =
false;
2106 JSON_THROW(std::domain_error(
"cannot create object from initializer list"));
2116 std::for_each(init.begin(), init.end(), [
this](
const basic_json & element)
2118 m_value.object->emplace(*(element[0].m_value.string), element[1]);
2125 m_value.array = create<array_t>(
init);
2166 std::initializer_list<basic_json>())
2206 std::initializer_list<basic_json>())
2232 m_value.array = create<array_t>(
cnt, val);
2273 template<
class InputIT,
typename std::enable_if<
2274 std::is_same<InputIT, typename basic_json_t::iterator>::value or
2275 std::is_same<InputIT, typename basic_json_t::const_iterator>::value,
int>::type = 0>
2278 assert(first.m_object !=
nullptr);
2279 assert(last.m_object !=
nullptr);
2282 if (first.m_object != last.m_object)
2284 JSON_THROW(std::domain_error(
"iterators are not compatible"));
2288 m_type = first.m_object->m_type;
2299 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
2301 JSON_THROW(std::out_of_range(
"iterators out of range"));
2316 m_value.number_integer = first.m_object->m_value.number_integer;
2322 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
2328 m_value.number_float = first.m_object->m_value.number_float;
2334 m_value.boolean = first.m_object->m_value.boolean;
2340 m_value = *first.m_object->m_value.string;
2346 m_value.object = create<object_t>(first.m_it.object_iterator,
2347 last.m_it.object_iterator);
2353 m_value.array = create<array_t>(first.m_it.array_iterator,
2354 last.m_it.array_iterator);
2360 JSON_THROW(std::domain_error(
"cannot use construct with iterators from " + first.m_object->type_name()));
2429 : m_type(other.m_type)
2506 : m_type(std::move(other.m_type)),
2507 m_value(std::move(other.m_value))
2510 other.assert_invariant();
2543 std::is_nothrow_move_constructible<value_t>::value and
2544 std::is_nothrow_move_assignable<value_t>::value and
2545 std::is_nothrow_move_constructible<json_value>::value and
2546 std::is_nothrow_move_assignable<json_value>::value
2553 swap(m_type, other.m_type);
2554 swap(m_value, other.m_value);
2583 AllocatorType<object_t> alloc;
2584 alloc.destroy(m_value.object);
2585 alloc.deallocate(m_value.object, 1);
2591 AllocatorType<array_t> alloc;
2592 alloc.destroy(m_value.array);
2593 alloc.deallocate(m_value.array, 1);
2599 AllocatorType<string_t> alloc;
2600 alloc.destroy(m_value.string);
2601 alloc.deallocate(m_value.string, 1);
2649 std::stringstream ss;
2653 dump(ss,
true, static_cast<unsigned int>(indent));
2713 return is_null() or is_string() or is_boolean() or is_number();
2740 return is_array() or is_object();
2814 return is_number_integer() or is_number_float();
3030 return m_value.boolean;
3033 JSON_THROW(std::domain_error(
"type must be boolean, but is " + type_name()));
3039 return is_object() ? m_value.object :
nullptr;
3045 return is_object() ? m_value.object :
nullptr;
3051 return is_array() ? m_value.array :
nullptr;
3057 return is_array() ? m_value.array :
nullptr;
3063 return is_string() ? m_value.string :
nullptr;
3069 return is_string() ? m_value.string :
nullptr;
3075 return is_boolean() ? &m_value.boolean :
nullptr;
3081 return is_boolean() ? &m_value.boolean :
nullptr;
3087 return is_number_integer() ? &m_value.number_integer :
nullptr;
3093 return is_number_integer() ? &m_value.number_integer :
nullptr;
3099 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
3105 return is_number_unsigned() ? &m_value.number_unsigned :
nullptr;
3111 return is_number_float() ? &m_value.number_float :
nullptr;
3117 return is_number_float() ? &m_value.number_float :
nullptr;
3131 template<
typename ReferenceType,
typename ThisType>
3138 auto ptr = obj.template get_ptr<PointerType>();
3145 JSON_THROW(std::domain_error(
"incompatible ReferenceType for get_ref, actual type is " +
3169 typename BasicJsonType,
3218 typename ValueTypeCV,
3221 not std::is_same<basic_json_t, ValueType>::value and
3225 ValueType
get()
const noexcept(noexcept(
3231 static_assert(not std::is_reference<ValueTypeCV>::value,
3232 "get() cannot be used with reference types, you might want to use get_ref()");
3233 static_assert(std::is_default_constructible<ValueType>::value,
3234 "types must be DefaultConstructible when used with get()");
3273 typename ValueTypeCV,
3277 ValueType>::value,
int> = 0 >
3278 ValueType
get()
const noexcept(noexcept(
3281 static_assert(not std::is_reference<ValueTypeCV>::value,
3282 "get() cannot be used with reference types, you might want to use get_ref()");
3313 template<
typename PointerType,
typename std::enable_if<
3314 std::is_pointer<PointerType>::value,
int>::type = 0>
3315 PointerType
get() noexcept
3318 return get_ptr<PointerType>();
3325 template<
typename PointerType,
typename std::enable_if<
3326 std::is_pointer<PointerType>::value,
int>::type = 0>
3327 constexpr
const PointerType
get()
const noexcept
3330 return get_ptr<PointerType>();
3359 template<
typename PointerType,
typename std::enable_if<
3360 std::is_pointer<PointerType>::value,
int>::type = 0>
3364 using pointee_t =
typename std::remove_const<
typename 3365 std::remove_pointer<
typename 3369 std::is_same<object_t, pointee_t>::value
3370 or std::is_same<array_t, pointee_t>::value
3371 or std::is_same<string_t, pointee_t>::value
3372 or std::is_same<boolean_t, pointee_t>::value
3373 or std::is_same<number_integer_t, pointee_t>::value
3374 or std::is_same<number_unsigned_t, pointee_t>::value
3375 or std::is_same<number_float_t, pointee_t>::value
3376 ,
"incompatible pointer type");
3379 return get_impl_ptr(static_cast<PointerType>(
nullptr));
3386 template<
typename PointerType,
typename std::enable_if<
3387 std::is_pointer<PointerType>::value and
3389 constexpr
const PointerType
get_ptr() const noexcept
3392 using pointee_t =
typename std::remove_const<
typename 3393 std::remove_pointer<
typename 3397 std::is_same<object_t, pointee_t>::value
3398 or std::is_same<array_t, pointee_t>::value
3399 or std::is_same<string_t, pointee_t>::value
3400 or std::is_same<boolean_t, pointee_t>::value
3401 or std::is_same<number_integer_t, pointee_t>::value
3402 or std::is_same<number_unsigned_t, pointee_t>::value
3403 or std::is_same<number_float_t, pointee_t>::value
3404 ,
"incompatible pointer type");
3407 return get_impl_ptr(static_cast<const PointerType>(
nullptr));
3436 template<
typename ReferenceType,
typename std::enable_if<
3437 std::is_reference<ReferenceType>::value,
int>::type = 0>
3441 return get_ref_impl<ReferenceType>(*this);
3448 template<
typename ReferenceType,
typename std::enable_if<
3449 std::is_reference<ReferenceType>::value and
3454 return get_ref_impl<ReferenceType>(*this);
3485 template <
typename ValueType,
typename std::enable_if <
3486 not std::is_pointer<ValueType>::value and
3487 not std::is_same<ValueType, typename string_t::value_type>::value
3488 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 3489 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3492 operator ValueType()
const 3495 return get<ValueType>();
3538 return m_value.array->at(idx);
3543 JSON_THROW(std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range"));
3548 JSON_THROW(std::domain_error(
"cannot use at() with " + type_name()));
3581 return m_value.array->at(idx);
3586 JSON_THROW(std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range"));
3591 JSON_THROW(std::domain_error(
"cannot use at() with " + type_name()));
3628 return m_value.object->at(key);
3633 JSON_THROW(std::out_of_range(
"key '" + key +
"' not found"));
3638 JSON_THROW(std::domain_error(
"cannot use at() with " + type_name()));
3675 return m_value.object->at(key);
3680 JSON_THROW(std::out_of_range(
"key '" + key +
"' not found"));
3685 JSON_THROW(std::domain_error(
"cannot use at() with " + type_name()));
3720 m_value.array = create<array_t>();
3728 if (idx >= m_value.array->size())
3730 m_value.array->insert(m_value.array->end(),
3731 idx - m_value.array->size() + 1,
3735 return m_value.array->operator[](idx);
3738 JSON_THROW(std::domain_error(
"cannot use operator[] with " + type_name()));
3765 return m_value.
array->operator[](idx);
3768 JSON_THROW(std::domain_error(
"cannot use operator[] with " + type_name()));
3804 m_value.object = create<object_t>();
3811 return m_value.object->operator[](key);
3814 JSON_THROW(std::domain_error(
"cannot use operator[] with " + type_name()));
3852 assert(m_value.object->find(key) != m_value.object->end());
3856 JSON_THROW(std::domain_error(
"cannot use operator[] with " + type_name()));
3886 template<
typename T, std::
size_t n>
3889 return operator[](static_cast<const T>(key));
3921 template<
typename T, std::
size_t n>
3924 return operator[](static_cast<const T>(key));
3954 template<
typename T>
3968 return m_value.object->operator[](key);
3971 JSON_THROW(std::domain_error(
"cannot use operator[] with " + type_name()));
4004 template<
typename T>
4010 assert(m_value.object->find(key) != m_value.object->end());
4014 JSON_THROW(std::domain_error(
"cannot use operator[] with " + type_name()));
4065 template<
class ValueType,
typename std::enable_if<
4066 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
4067 ValueType
value(
const typename object_t::key_type& key, ValueType default_value)
const 4073 const auto it = find(key);
4079 return default_value;
4083 JSON_THROW(std::domain_error(
"cannot use value() with " + type_name()));
4091 string_t value(
const typename object_t::key_type& key,
const char* default_value)
const 4093 return value(key,
string_t(default_value));
4137 template<
class ValueType,
typename std::enable_if<
4138 std::is_convertible<basic_json_t, ValueType>::value,
int>::type = 0>
4151 return default_value;
4155 JSON_THROW(std::domain_error(
"cannot use value() with " + type_name()));
4164 return value(ptr,
string_t(default_value));
4297 template<
class IteratorType,
typename std::enable_if<
4298 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4299 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
4304 if (
this != pos.m_object)
4306 JSON_THROW(std::domain_error(
"iterator does not fit current value"));
4309 IteratorType result = end();
4319 if (not pos.m_it.primitive_iterator.is_begin())
4321 JSON_THROW(std::out_of_range(
"iterator out of range"));
4326 AllocatorType<string_t> alloc;
4327 alloc.destroy(m_value.string);
4328 alloc.deallocate(m_value.string, 1);
4329 m_value.string =
nullptr;
4339 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
4345 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
4351 JSON_THROW(std::domain_error(
"cannot use erase() with " + type_name()));
4404 template<
class IteratorType,
typename std::enable_if<
4405 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4406 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value,
int>::type
4411 if (
this != first.m_object or
this != last.m_object)
4413 JSON_THROW(std::domain_error(
"iterators do not fit current value"));
4416 IteratorType result = end();
4426 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
4428 JSON_THROW(std::out_of_range(
"iterators out of range"));
4433 AllocatorType<string_t> alloc;
4434 alloc.destroy(m_value.string);
4435 alloc.deallocate(m_value.string, 1);
4436 m_value.string =
nullptr;
4446 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4447 last.m_it.object_iterator);
4453 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4454 last.m_it.array_iterator);
4460 JSON_THROW(std::domain_error(
"cannot use erase() with " + type_name()));
4501 return m_value.object->erase(key);
4504 JSON_THROW(std::domain_error(
"cannot use erase() with " + type_name()));
4538 JSON_THROW(std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range"));
4541 m_value.array->erase(m_value.array->begin() +
static_cast<difference_type>(idx));
4545 JSON_THROW(std::domain_error(
"cannot use erase() with " + type_name()));
4583 auto result = end();
4587 result.m_it.object_iterator = m_value.object->find(key);
4599 auto result = cend();
4603 result.m_it.object_iterator = m_value.object->find(key);
4633 return is_object() ? m_value.object->count(key) : 0;
5008 return m_value.array->empty();
5014 return m_value.object->empty();
5076 return m_value.array->size();
5082 return m_value.object->size();
5136 return m_value.array->max_size();
5142 return m_value.object->max_size();
5191 m_value.number_integer = 0;
5197 m_value.number_unsigned = 0;
5203 m_value.number_float = 0.0;
5209 m_value.boolean =
false;
5215 m_value.string->clear();
5221 m_value.array->clear();
5227 m_value.object->clear();
5261 if (not(is_null() or is_array()))
5263 JSON_THROW(std::domain_error(
"cannot use push_back() with " + type_name()));
5275 m_value.array->push_back(std::move(val));
5286 push_back(std::move(val));
5297 if (not(is_null() or is_array()))
5299 JSON_THROW(std::domain_error(
"cannot use push_back() with " + type_name()));
5311 m_value.array->push_back(val);
5347 if (not(is_null() or is_object()))
5349 JSON_THROW(std::domain_error(
"cannot use push_back() with " + type_name()));
5361 m_value.object->insert(val);
5401 if (is_object() and init.size() == 2 and init.begin()->is_string())
5403 const string_t key = *init.begin();
5404 push_back(
typename object_t::value_type(key, *(init.begin() + 1)));
5443 template<
class... Args>
5447 if (not(is_null() or is_array()))
5449 JSON_THROW(std::domain_error(
"cannot use emplace_back() with " + type_name()));
5461 m_value.array->emplace_back(std::forward<Args>(args)...);
5491 template<
class... Args>
5492 std::pair<iterator, bool>
emplace(Args&& ... args)
5495 if (not(is_null() or is_object()))
5497 JSON_THROW(std::domain_error(
"cannot use emplace() with " + type_name()));
5509 auto res = m_value.object->emplace(std::forward<Args>(args)...);
5512 it.m_it.object_iterator = res.first;
5515 return {it, res.second};
5548 JSON_THROW(std::domain_error(
"iterator does not fit current value"));
5557 JSON_THROW(std::domain_error(
"cannot use insert() with " + type_name()));
5566 return insert(pos, val);
5601 JSON_THROW(std::domain_error(
"iterator does not fit current value"));
5610 JSON_THROW(std::domain_error(
"cannot use insert() with " + type_name()));
5648 JSON_THROW(std::domain_error(
"cannot use insert() with " + type_name()));
5654 JSON_THROW(std::domain_error(
"iterator does not fit current value"));
5660 JSON_THROW(std::domain_error(
"iterators do not fit"));
5665 JSON_THROW(std::domain_error(
"passed iterators may not belong to container"));
5706 JSON_THROW(std::domain_error(
"cannot use insert() with " + type_name()));
5712 JSON_THROW(std::domain_error(
"iterator does not fit current value"));
5739 std::is_nothrow_move_constructible<value_t>::value and
5740 std::is_nothrow_move_assignable<value_t>::value and
5741 std::is_nothrow_move_constructible<json_value>::value and
5742 std::is_nothrow_move_assignable<json_value>::value
5745 std::swap(m_type, other.m_type);
5746 std::swap(m_value, other.m_value);
5775 std::swap(*(m_value.array), other);
5779 JSON_THROW(std::domain_error(
"cannot use swap() with " + type_name()));
5808 std::swap(*(m_value.object), other);
5812 JSON_THROW(std::domain_error(
"cannot use swap() with " + type_name()));
5841 std::swap(*(m_value.string), other);
5845 JSON_THROW(std::domain_error(
"cannot use swap() with " + type_name()));
5884 const auto lhs_type = lhs.type();
5885 const auto rhs_type = rhs.type();
5887 if (lhs_type == rhs_type)
5893 return *lhs.m_value.array == *rhs.m_value.array;
5897 return *lhs.m_value.object == *rhs.m_value.object;
5905 return *lhs.m_value.string == *rhs.m_value.string;
5909 return lhs.m_value.boolean == rhs.m_value.boolean;
5913 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5917 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5921 return lhs.m_value.number_float == rhs.m_value.number_float;
5931 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5935 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_integer);
5939 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5943 return lhs.m_value.number_float ==
static_cast<number_float_t>(rhs.m_value.number_unsigned);
5947 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5951 return lhs.m_value.number_integer ==
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5961 template<
typename ScalarType,
typename std::enable_if<
5962 std::is_scalar<ScalarType>::value,
int>::type = 0>
5972 template<
typename ScalarType,
typename std::enable_if<
5973 std::is_scalar<ScalarType>::value,
int>::type = 0>
5997 return not (lhs == rhs);
6004 template<
typename ScalarType,
typename std::enable_if<
6005 std::is_scalar<ScalarType>::value,
int>::type = 0>
6015 template<
typename ScalarType,
typename std::enable_if<
6016 std::is_scalar<ScalarType>::value,
int>::type = 0>
6048 const auto lhs_type = lhs.type();
6049 const auto rhs_type = rhs.type();
6051 if (lhs_type == rhs_type)
6057 return *lhs.m_value.array < *rhs.m_value.array;
6061 return *lhs.m_value.object < *rhs.m_value.object;
6069 return *lhs.m_value.string < *rhs.m_value.string;
6073 return lhs.m_value.boolean < rhs.m_value.boolean;
6077 return lhs.m_value.number_integer < rhs.m_value.number_integer;
6081 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
6085 return lhs.m_value.number_float < rhs.m_value.number_float;
6095 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
6099 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_integer);
6103 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
6107 return lhs.m_value.number_float <
static_cast<number_float_t>(rhs.m_value.number_unsigned);
6111 return lhs.m_value.number_integer <
static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6115 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
6143 return not (rhs < lhs);
6165 return not (lhs <= rhs);
6187 return not (lhs < rhs);
6225 const bool pretty_print = (o.width() > 0);
6226 const auto indentation = (pretty_print ? o.width() : 0);
6232 j.
dump(o, pretty_print, static_cast<unsigned int>(indentation));
6283 template<
class T, std::
size_t N>
6288 return parse(std::begin(
array), std::end(
array), cb);
6318 template<
typename CharT,
typename std::enable_if<
6319 std::is_pointer<CharT>::value and
6325 return parser(reinterpret_cast<const char*>(s), cb).
parse();
6408 template<
class IteratorType,
typename std::enable_if<
6410 std::random_access_iterator_tag,
6411 typename std::iterator_traits<IteratorType>::iterator_category>::value,
int>::type = 0>
6417 assert(std::accumulate(first, last, std::pair<bool, int>(
true, 0),
6418 [&first](std::pair<bool, int> res, decltype(*first) val)
6420 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
6425 static_assert(
sizeof(
typename std::iterator_traits<IteratorType>::value_type) == 1,
6426 "each element in the iterator range must have the size of 1 byte");
6430 if (std::distance(first, last) <= 0)
6478 template<
class ContiguousContainer,
typename std::enable_if<
6479 not std::is_pointer<ContiguousContainer>::value and
6481 std::random_access_iterator_tag,
6482 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
6488 return parse(std::begin(c), std::end(c), cb);
6545 template<
typename T>
6546 static void add_to_vector(std::vector<uint8_t>& vec,
size_t bytes,
const T number)
6548 assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8);
6554 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 070) & 0xff));
6555 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 060) & 0xff));
6556 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 050) & 0xff));
6557 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 040) & 0xff));
6558 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
6559 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
6560 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6561 vec.push_back(static_cast<uint8_t>(number & 0xff));
6567 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
6568 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
6569 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6570 vec.push_back(static_cast<uint8_t>(number & 0xff));
6576 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6577 vec.push_back(static_cast<uint8_t>(number & 0xff));
6583 vec.push_back(static_cast<uint8_t>(number & 0xff));
6625 template<
typename T>
6628 if (current_index +
sizeof(T) + 1 > vec.size())
6630 JSON_THROW(std::out_of_range(
"cannot read " + std::to_string(
sizeof(T)) +
" bytes from vector"));
6634 auto* ptr =
reinterpret_cast<uint8_t*
>(&result);
6635 for (
size_t i = 0; i <
sizeof(
T); ++i)
6637 *ptr++ = vec[current_index +
sizeof(
T) - i];
6782 for (
size_t i = 0; i < 8; ++i)
6784 v.push_back(helper[7 - i]);
6795 v.push_back(static_cast<uint8_t>(0xa0 |
N));
6801 add_to_vector(v, 1,
N);
6803 else if (
N <= 65535)
6807 add_to_vector(v, 2,
N);
6809 else if (
N <= 4294967295)
6813 add_to_vector(v, 4,
N);
6818 std::back_inserter(v));
6828 v.push_back(static_cast<uint8_t>(0x90 |
N));
6830 else if (
N <= 0xffff)
6834 add_to_vector(v, 2,
N);
6836 else if (
N <= 0xffffffff)
6840 add_to_vector(v, 4,
N);
6846 to_msgpack_internal(el, v);
6857 v.push_back(static_cast<uint8_t>(0x80 | (
N & 0xf)));
6859 else if (
N <= 65535)
6863 add_to_vector(v, 2,
N);
6865 else if (
N <= 4294967295)
6869 add_to_vector(v, 4,
N);
6875 to_msgpack_internal(el.first, v);
6876 to_msgpack_internal(el.second, v);
6957 v.push_back(static_cast<uint8_t>(0x20 + positive_number));
6959 else if (positive_number <= std::numeric_limits<uint8_t>::max())
6963 add_to_vector(v, 1, positive_number);
6965 else if (positive_number <= std::numeric_limits<uint16_t>::max())
6969 add_to_vector(v, 2, positive_number);
6971 else if (positive_number <= std::numeric_limits<uint32_t>::max())
6975 add_to_vector(v, 4, positive_number);
6981 add_to_vector(v, 8, positive_number);
7025 for (
size_t i = 0; i < 8; ++i)
7027 v.push_back(helper[7 - i]);
7037 v.push_back(0x60 + static_cast<uint8_t>(
N));
7042 add_to_vector(v, 1,
N);
7044 else if (
N <= 0xffff)
7047 add_to_vector(v, 2,
N);
7049 else if (
N <= 0xffffffff)
7052 add_to_vector(v, 4,
N);
7055 else if (
N <= 0xffffffffffffffff)
7058 add_to_vector(v, 8,
N);
7064 std::back_inserter(v));
7073 v.push_back(0x80 + static_cast<uint8_t>(
N));
7078 add_to_vector(v, 1,
N);
7080 else if (
N <= 0xffff)
7083 add_to_vector(v, 2,
N);
7085 else if (
N <= 0xffffffff)
7088 add_to_vector(v, 4,
N);
7091 else if (
N <= 0xffffffffffffffff)
7094 add_to_vector(v, 8,
N);
7101 to_cbor_internal(el, v);
7111 v.push_back(0xa0 + static_cast<uint8_t>(
N));
7116 add_to_vector(v, 1,
N);
7118 else if (
N <= 0xffff)
7121 add_to_vector(v, 2,
N);
7123 else if (
N <= 0xffffffff)
7126 add_to_vector(v, 4,
N);
7129 else if (
N <= 0xffffffffffffffff)
7132 add_to_vector(v, 8,
N);
7139 to_cbor_internal(el.first, v);
7140 to_cbor_internal(el.second, v);
7175 static void check_length(
const size_t size,
const size_t len,
const size_t offset)
7178 if (len > size or offset > size)
7180 JSON_THROW(std::out_of_range(
"len out of range"));
7184 if ((size > (std::numeric_limits<size_t>::max() - offset)))
7186 JSON_THROW(std::out_of_range(
"len+offset out of range"));
7190 if (len + offset > size)
7192 JSON_THROW(std::out_of_range(
"len+offset out of range"));
7213 check_length(v.size(), 1, idx);
7216 const size_t current_idx = idx++;
7218 if (v[current_idx] <= 0xbf)
7220 if (v[current_idx] <= 0x7f)
7222 return v[current_idx];
7224 if (v[current_idx] <= 0x8f)
7227 const size_t len = v[current_idx] & 0x0f;
7228 for (
size_t i = 0; i < len; ++i)
7231 result[key] = from_msgpack_internal(v, idx);
7235 else if (v[current_idx] <= 0x9f)
7238 const size_t len = v[current_idx] & 0x0f;
7239 for (
size_t i = 0; i < len; ++i)
7241 result.
push_back(from_msgpack_internal(v, idx));
7247 const size_t len = v[current_idx] & 0x1f;
7248 const size_t offset = current_idx + 1;
7250 check_length(v.size(), len, offset);
7251 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7254 else if (v[current_idx] >= 0xe0)
7256 return static_cast<int8_t
>(v[current_idx]);
7260 switch (v[current_idx])
7283 reinterpret_cast<uint8_t*
>(&res)[
sizeof(
float) -
byte - 1] = v.at(current_idx + 1 +
byte);
7285 idx +=
sizeof(float);
7295 reinterpret_cast<uint8_t*
>(&res)[
sizeof(
double) -
byte - 1] = v.at(current_idx + 1 +
byte);
7297 idx +=
sizeof(double);
7304 return get_from_vector<uint8_t>(
v, current_idx);
7310 return get_from_vector<uint16_t>(
v, current_idx);
7316 return get_from_vector<uint32_t>(
v, current_idx);
7322 return get_from_vector<uint64_t>(
v, current_idx);
7328 return get_from_vector<int8_t>(
v, current_idx);
7334 return get_from_vector<int16_t>(
v, current_idx);
7340 return get_from_vector<int32_t>(
v, current_idx);
7346 return get_from_vector<int64_t>(
v, current_idx);
7351 const auto len =
static_cast<size_t>(get_from_vector<uint8_t>(
v, current_idx));
7352 const size_t offset = current_idx + 2;
7354 check_length(v.size(), len, offset);
7355 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7360 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(
v, current_idx));
7361 const size_t offset = current_idx + 3;
7363 check_length(v.size(), len, offset);
7364 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7369 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(
v, current_idx));
7370 const size_t offset = current_idx + 5;
7372 check_length(v.size(), len, offset);
7373 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7379 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(
v, current_idx));
7381 for (
size_t i = 0; i < len; ++i)
7383 result.
push_back(from_msgpack_internal(v, idx));
7391 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(
v, current_idx));
7393 for (
size_t i = 0; i < len; ++i)
7395 result.
push_back(from_msgpack_internal(v, idx));
7403 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(
v, current_idx));
7405 for (
size_t i = 0; i < len; ++i)
7408 result[key] = from_msgpack_internal(v, idx);
7416 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(
v, current_idx));
7418 for (
size_t i = 0; i < len; ++i)
7421 result[key] = from_msgpack_internal(v, idx);
7428 JSON_THROW(std::invalid_argument(
"error parsing a msgpack @ " + std::to_string(current_idx) +
": " + std::to_string(static_cast<int>(v[current_idx]))));
7451 const size_t current_idx = idx++;
7453 switch (v.at(current_idx))
7481 return v[current_idx];
7487 return get_from_vector<uint8_t>(
v, current_idx);
7493 return get_from_vector<uint16_t>(
v, current_idx);
7499 return get_from_vector<uint32_t>(
v, current_idx);
7505 return get_from_vector<uint64_t>(
v, current_idx);
7534 return static_cast<int8_t
>(0x20 - 1 - v[current_idx]);
7541 return static_cast<number_integer_t>(-1) - get_from_vector<uint8_t>(v, current_idx);
7547 return static_cast<number_integer_t>(-1) - get_from_vector<uint16_t>(v, current_idx);
7553 return static_cast<number_integer_t>(-1) - get_from_vector<uint32_t>(v, current_idx);
7559 return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_from_vector<uint64_t>(v, current_idx));
7588 const auto len =
static_cast<size_t>(v[current_idx] - 0x60);
7589 const size_t offset = current_idx + 1;
7591 check_length(v.size(), len, offset);
7592 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7597 const auto len =
static_cast<size_t>(get_from_vector<uint8_t>(
v, current_idx));
7598 const size_t offset = current_idx + 2;
7600 check_length(v.size(), len, offset);
7601 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7606 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(
v, current_idx));
7607 const size_t offset = current_idx + 3;
7609 check_length(v.size(), len, offset);
7610 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7615 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(
v, current_idx));
7616 const size_t offset = current_idx + 5;
7618 check_length(v.size(), len, offset);
7619 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7624 const auto len =
static_cast<size_t>(get_from_vector<uint64_t>(
v, current_idx));
7625 const size_t offset = current_idx + 9;
7627 check_length(v.size(), len, offset);
7628 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7634 while (v.at(idx) != 0xff)
7636 string_t s = from_cbor_internal(v, idx);
7671 const auto len =
static_cast<size_t>(v[current_idx] - 0x80);
7672 for (
size_t i = 0; i < len; ++i)
7674 result.
push_back(from_cbor_internal(v, idx));
7682 const auto len =
static_cast<size_t>(get_from_vector<uint8_t>(
v, current_idx));
7684 for (
size_t i = 0; i < len; ++i)
7686 result.
push_back(from_cbor_internal(v, idx));
7694 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(
v, current_idx));
7696 for (
size_t i = 0; i < len; ++i)
7698 result.
push_back(from_cbor_internal(v, idx));
7706 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(
v, current_idx));
7708 for (
size_t i = 0; i < len; ++i)
7710 result.
push_back(from_cbor_internal(v, idx));
7718 const auto len =
static_cast<size_t>(get_from_vector<uint64_t>(
v, current_idx));
7720 for (
size_t i = 0; i < len; ++i)
7722 result.
push_back(from_cbor_internal(v, idx));
7730 while (v.at(idx) != 0xff)
7732 result.
push_back(from_cbor_internal(v, idx));
7766 const auto len =
static_cast<size_t>(v[current_idx] - 0xa0);
7767 for (
size_t i = 0; i < len; ++i)
7770 result[key] = from_cbor_internal(v, idx);
7778 const auto len =
static_cast<size_t>(get_from_vector<uint8_t>(
v, current_idx));
7780 for (
size_t i = 0; i < len; ++i)
7783 result[key] = from_cbor_internal(v, idx);
7791 const auto len =
static_cast<size_t>(get_from_vector<uint16_t>(
v, current_idx));
7793 for (
size_t i = 0; i < len; ++i)
7796 result[key] = from_cbor_internal(v, idx);
7804 const auto len =
static_cast<size_t>(get_from_vector<uint32_t>(
v, current_idx));
7806 for (
size_t i = 0; i < len; ++i)
7809 result[key] = from_cbor_internal(v, idx);
7817 const auto len =
static_cast<size_t>(get_from_vector<uint64_t>(
v, current_idx));
7819 for (
size_t i = 0; i < len; ++i)
7822 result[key] = from_cbor_internal(v, idx);
7830 while (v.at(idx) != 0xff)
7833 result[key] = from_cbor_internal(v, idx);
7866 const int half = (v.at(current_idx + 1) << 8) + v.at(current_idx + 2);
7867 const int exp = (half >> 10) & 0x1f;
7868 const int mant = half & 0x3ff;
7881 ? std::numeric_limits<double>::infinity()
7882 : std::numeric_limits<double>::quiet_NaN();
7884 return (half & 0x8000) != 0 ? -val : val;
7893 reinterpret_cast<uint8_t*
>(&res)[
sizeof(
float) -
byte - 1] = v.at(current_idx + 1 +
byte);
7895 idx +=
sizeof(float);
7905 reinterpret_cast<uint8_t*
>(&res)[
sizeof(
double) -
byte - 1] = v.at(current_idx + 1 +
byte);
7907 idx +=
sizeof(double);
7913 JSON_THROW(std::invalid_argument(
"error parsing a CBOR @ " + std::to_string(current_idx) +
": " + std::to_string(static_cast<int>(v[current_idx]))));
7943 std::vector<uint8_t> result;
7944 to_msgpack_internal(j, result);
7975 const size_t start_index = 0)
7977 size_t i = start_index;
7978 return from_msgpack_internal(v, i);
8006 std::vector<uint8_t> result;
8007 to_cbor_internal(j, result);
8038 const size_t start_index = 0)
8040 size_t i = start_index;
8041 return from_cbor_internal(v, i);
8099 return std::accumulate(s.begin(), s.end(),
size_t{},
8100 [](
size_t res,
typename string_t::value_type
c)
8118 if (c >= 0x00 and c <= 0x1f)
8145 const auto space = extra_space(s);
8152 string_t result(s.size() + space,
'\\');
8153 std::size_t pos = 0;
8155 for (
const auto& c : s)
8162 result[pos + 1] =
'"';
8178 result[pos + 1] =
'b';
8186 result[pos + 1] =
'f';
8194 result[pos + 1] =
'n';
8202 result[pos + 1] =
'r';
8210 result[pos + 1] =
't';
8217 if (c >= 0x00 and c <= 0x1f)
8221 static const char hexify[16] =
8223 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
8224 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f' 8229 {
'u',
'0',
'0', hexify[c >> 4], hexify[c & 0x0f]
8257 template<
typename NumberType>
8260 x_write(value, std::is_integral<NumberType>());
8265 return m_buf.data();
8270 std::array < char, 64 > m_buf{{}};
8272 template<
typename NumberType>
8282 const bool is_negative = x < 0;
8286 while (x != 0 and i < m_buf.size() - 1)
8288 const auto digit = std::labs(static_cast<long>(x % 10));
8289 m_buf[i++] =
static_cast<char>(
'0' + digit);
8299 assert(i < m_buf.size() - 2);
8303 std::reverse(m_buf.begin(), m_buf.begin() + i);
8306 template<
typename NumberType>
8313 if (std::signbit(x))
8324 static constexpr
auto d = std::numeric_limits<NumberType>::digits10;
8327 const auto written_bytes =
snprintf(m_buf.data(), m_buf.size(),
"%.*g",
d,
x);
8330 assert(written_bytes > 0);
8332 assert(static_cast<size_t>(written_bytes) < m_buf.size());
8335 const auto loc = localeconv();
8336 assert(loc !=
nullptr);
8337 const char thousands_sep = !loc->thousands_sep ?
'\0' 8338 : loc->thousands_sep[0];
8340 const char decimal_point = !loc->decimal_point ?
'\0' 8341 : loc->decimal_point[0];
8344 if (thousands_sep !=
'\0')
8346 const auto end = std::remove(m_buf.begin(), m_buf.begin() + written_bytes, thousands_sep);
8351 if (decimal_point !=
'\0' and decimal_point !=
'.')
8353 for (
auto& c : m_buf)
8355 if (c == decimal_point)
8365 bool value_is_int_like =
true;
8366 for (i = 0; i < m_buf.size(); ++i)
8369 if (m_buf[i] ==
'\0')
8375 value_is_int_like = value_is_int_like and m_buf[i] !=
'.' and
8376 m_buf[i] !=
'e' and m_buf[i] !=
'E';
8379 if (value_is_int_like)
8382 assert((i + 2) < m_buf.size());
8384 assert(m_buf[i] ==
'\0');
8385 assert(m_buf[i - 1] !=
'\0');
8392 assert(m_buf[i + 2] ==
'\0');
8416 const bool pretty_print,
8417 const unsigned int indent_step,
8418 const unsigned int current_indent = 0)
const 8421 unsigned int new_indent = current_indent;
8427 if (m_value.object->empty())
8438 new_indent += indent_step;
8442 for (
auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
8444 if (i != m_value.object->cbegin())
8446 o << (pretty_print ?
",\n" :
",");
8448 o <<
string_t(new_indent,
' ') <<
"\"" 8449 << escape_string(i->first) <<
"\":" 8450 << (pretty_print ?
" " :
"");
8451 i->second.dump(o, pretty_print, indent_step, new_indent);
8457 new_indent -= indent_step;
8461 o <<
string_t(new_indent,
' ') +
"}";
8467 if (m_value.array->empty())
8478 new_indent += indent_step;
8482 for (
auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
8484 if (i != m_value.array->cbegin())
8486 o << (pretty_print ?
",\n" :
",");
8489 i->dump(o, pretty_print, indent_step, new_indent);
8495 new_indent -= indent_step;
8499 o <<
string_t(new_indent,
' ') <<
"]";
8505 o <<
string_t(
"\"") << escape_string(*m_value.string) <<
"\"";
8511 o << (m_value.boolean ?
"true" :
"false");
8596 return (m_it == begin_value);
8602 return (m_it == end_value);
8607 return lhs.m_it == rhs.m_it;
8612 return !(lhs == rhs);
8617 return lhs.m_it < rhs.m_it;
8622 return lhs.m_it <= rhs.m_it;
8627 return lhs.m_it > rhs.m_it;
8632 return lhs.m_it >= rhs.m_it;
8637 auto result = *
this;
8644 return lhs.m_it - rhs.m_it;
8649 return os << it.
m_it;
8660 auto result = *
this;
8673 auto result = *
this;
8716 : object_iterator(), array_iterator(), primitive_iterator()
8721 template<
typename IteratorType>
8732 size_t array_index = 0;
8757 return anchor != o.
anchor;
8763 assert(anchor.m_object !=
nullptr);
8765 switch (anchor.m_object->type())
8770 return std::to_string(array_index);
8776 return anchor.key();
8788 typename IteratorType::reference
value()
const 8790 return anchor.value();
8836 template<
typename U>
8837 class iter_impl :
public std::iterator<std::random_access_iterator_tag, U>
8843 static_assert(std::is_same<U, basic_json>::value
8844 or std::is_same<U, const basic_json>::value,
8845 "iter_impl only accepts (const) basic_json");
8853 using pointer =
typename std::conditional<std::is_const<U>::value,
8857 using reference =
typename std::conditional<std::is_const<U>::value,
8875 assert(m_object !=
nullptr);
8877 switch (m_object->m_type)
8881 m_it.object_iterator =
typename object_t::iterator();
8887 m_it.array_iterator =
typename array_t::iterator();
8926 : m_object(other.m_object), m_it(other.m_it)
8935 std::is_nothrow_move_constructible<pointer>::value and
8936 std::is_nothrow_move_assignable<pointer>::value and
8937 std::is_nothrow_move_constructible<internal_iterator>::value and
8938 std::is_nothrow_move_assignable<internal_iterator>::value
8941 std::swap(m_object, other.m_object);
8942 std::swap(m_it, other.m_it);
8953 assert(m_object !=
nullptr);
8955 switch (m_object->m_type)
8959 m_it.object_iterator = m_object->m_value.object->begin();
8965 m_it.array_iterator = m_object->m_value.array->begin();
8972 m_it.primitive_iterator.set_end();
8978 m_it.primitive_iterator.set_begin();
8990 assert(m_object !=
nullptr);
8992 switch (m_object->m_type)
8996 m_it.object_iterator = m_object->m_value.object->end();
9002 m_it.array_iterator = m_object->m_value.array->end();
9008 m_it.primitive_iterator.set_end();
9021 assert(m_object !=
nullptr);
9023 switch (m_object->m_type)
9027 assert(m_it.object_iterator != m_object->m_value.object->end());
9028 return m_it.object_iterator->second;
9033 assert(m_it.array_iterator != m_object->m_value.array->end());
9034 return *m_it.array_iterator;
9039 JSON_THROW(std::out_of_range(
"cannot get value"));
9044 if (m_it.primitive_iterator.is_begin())
9049 JSON_THROW(std::out_of_range(
"cannot get value"));
9060 assert(m_object !=
nullptr);
9062 switch (m_object->m_type)
9066 assert(m_it.object_iterator != m_object->m_value.object->end());
9067 return &(m_it.object_iterator->second);
9072 assert(m_it.array_iterator != m_object->m_value.array->end());
9073 return &*m_it.array_iterator;
9078 if (m_it.primitive_iterator.is_begin())
9083 JSON_THROW(std::out_of_range(
"cannot get value"));
9094 auto result = *
this;
9105 assert(m_object !=
nullptr);
9107 switch (m_object->m_type)
9111 std::advance(m_it.object_iterator, 1);
9117 std::advance(m_it.array_iterator, 1);
9123 ++m_it.primitive_iterator;
9137 auto result = *
this;
9148 assert(m_object !=
nullptr);
9150 switch (m_object->m_type)
9154 std::advance(m_it.object_iterator, -1);
9160 std::advance(m_it.array_iterator, -1);
9166 --m_it.primitive_iterator;
9183 JSON_THROW(std::domain_error(
"cannot compare iterators of different containers"));
9186 assert(m_object !=
nullptr);
9188 switch (m_object->m_type)
9225 JSON_THROW(std::domain_error(
"cannot compare iterators of different containers"));
9228 assert(m_object !=
nullptr);
9230 switch (m_object->m_type)
9234 JSON_THROW(std::domain_error(
"cannot compare order of object iterators"));
9255 return not other.operator < (*this);
9282 assert(m_object !=
nullptr);
9284 switch (m_object->m_type)
9288 JSON_THROW(std::domain_error(
"cannot use offsets with object iterators"));
9293 std::advance(m_it.array_iterator, i);
9299 m_it.primitive_iterator += i;
9322 auto result = *
this;
9333 auto result = *
this;
9344 assert(m_object !=
nullptr);
9346 switch (m_object->m_type)
9350 JSON_THROW(std::domain_error(
"cannot use offsets with object iterators"));
9371 assert(m_object !=
nullptr);
9373 switch (m_object->m_type)
9377 JSON_THROW(std::domain_error(
"cannot use operator[] for object iterators"));
9382 return *std::next(m_it.array_iterator, n);
9387 JSON_THROW(std::out_of_range(
"cannot get value"));
9392 if (m_it.primitive_iterator.get_value() == -
n)
9397 JSON_THROW(std::out_of_range(
"cannot get value"));
9406 typename object_t::key_type
key()
const 9408 assert(m_object !=
nullptr);
9410 if (m_object->is_object())
9412 return m_it.object_iterator->first;
9415 JSON_THROW(std::domain_error(
"cannot use key() for non-object iterators"));
9451 template<
typename Base>
9473 return base_iterator::operator++(1);
9479 base_iterator::operator++();
9486 return base_iterator::operator--(1);
9492 base_iterator::operator--();
9506 auto result = *
this;
9514 auto result = *
this;
9522 return this->base() - other.base();
9532 typename object_t::key_type
key()
const 9534 auto it = --this->base();
9541 auto it = --this->base();
9542 return it.operator * ();
9590 assert(m_content !=
nullptr);
9591 m_start = m_cursor = m_content;
9592 m_limit = m_content + len;
9597 : m_stream(&s), m_line_buffer()
9602 JSON_THROW(std::invalid_argument(
"stream error"));
9609 if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) ==
"\xEF\xBB\xBF")
9611 m_line_buffer[0] =
' ';
9612 m_line_buffer[1] =
' ';
9613 m_line_buffer[2] =
' ';
9646 const std::size_t codepoint2 = 0)
9649 std::size_t codepoint = codepoint1;
9652 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
9655 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
9669 JSON_THROW(std::invalid_argument(
"missing or wrong low surrogate"));
9675 if (codepoint < 0x80)
9678 result.append(1, static_cast<typename string_t::value_type>(codepoint));
9680 else if (codepoint <= 0x7ff)
9683 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
9684 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9686 else if (codepoint <= 0xffff)
9689 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
9690 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
9691 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9693 else if (codepoint <= 0x10ffff)
9696 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
9697 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
9698 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
9699 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9703 JSON_THROW(std::out_of_range(
"code points above 0x10FFFF are invalid"));
9714 case token_type::uninitialized:
9715 return "<uninitialized>";
9716 case token_type::literal_true:
9717 return "true literal";
9718 case token_type::literal_false:
9719 return "false literal";
9720 case token_type::literal_null:
9721 return "null literal";
9722 case token_type::value_string:
9723 return "string literal";
9724 case lexer::token_type::value_unsigned:
9725 case lexer::token_type::value_integer:
9726 case lexer::token_type::value_float:
9727 return "number literal";
9728 case token_type::begin_array:
9730 case token_type::begin_object:
9732 case token_type::end_array:
9734 case token_type::end_object:
9736 case token_type::name_separator:
9738 case token_type::value_separator:
9740 case token_type::parse_error:
9741 return "<parse error>";
9742 case token_type::end_of_input:
9743 return "end of input";
9747 return "unknown token";
9782 assert(m_start !=
nullptr);
9787 unsigned int yyaccept = 0;
9788 static const unsigned char yybm[] =
9790 0, 0, 0, 0, 0, 0, 0, 0,
9791 0, 32, 32, 0, 0, 32, 0, 0,
9792 0, 0, 0, 0, 0, 0, 0, 0,
9793 0, 0, 0, 0, 0, 0, 0, 0,
9794 160, 128, 0, 128, 128, 128, 128, 128,
9795 128, 128, 128, 128, 128, 128, 128, 128,
9796 192, 192, 192, 192, 192, 192, 192, 192,
9797 192, 192, 128, 128, 128, 128, 128, 128,
9798 128, 128, 128, 128, 128, 128, 128, 128,
9799 128, 128, 128, 128, 128, 128, 128, 128,
9800 128, 128, 128, 128, 128, 128, 128, 128,
9801 128, 128, 128, 128, 0, 128, 128, 128,
9802 128, 128, 128, 128, 128, 128, 128, 128,
9803 128, 128, 128, 128, 128, 128, 128, 128,
9804 128, 128, 128, 128, 128, 128, 128, 128,
9805 128, 128, 128, 128, 128, 128, 128, 128,
9806 0, 0, 0, 0, 0, 0, 0, 0,
9807 0, 0, 0, 0, 0, 0, 0, 0,
9808 0, 0, 0, 0, 0, 0, 0, 0,
9809 0, 0, 0, 0, 0, 0, 0, 0,
9810 0, 0, 0, 0, 0, 0, 0, 0,
9811 0, 0, 0, 0, 0, 0, 0, 0,
9812 0, 0, 0, 0, 0, 0, 0, 0,
9813 0, 0, 0, 0, 0, 0, 0, 0,
9814 0, 0, 0, 0, 0, 0, 0, 0,
9815 0, 0, 0, 0, 0, 0, 0, 0,
9816 0, 0, 0, 0, 0, 0, 0, 0,
9817 0, 0, 0, 0, 0, 0, 0, 0,
9818 0, 0, 0, 0, 0, 0, 0, 0,
9819 0, 0, 0, 0, 0, 0, 0, 0,
9820 0, 0, 0, 0, 0, 0, 0, 0,
9821 0, 0, 0, 0, 0, 0, 0, 0,
9823 if ((m_limit - m_cursor) < 5)
9825 fill_line_buffer(5);
9828 if (yybm[0 + yych] & 32)
9830 goto basic_json_parser_6;
9840 goto basic_json_parser_2;
9844 goto basic_json_parser_4;
9846 goto basic_json_parser_9;
9852 goto basic_json_parser_4;
9856 goto basic_json_parser_10;
9858 goto basic_json_parser_12;
9867 goto basic_json_parser_4;
9871 goto basic_json_parser_13;
9873 goto basic_json_parser_15;
9879 goto basic_json_parser_17;
9883 goto basic_json_parser_4;
9885 goto basic_json_parser_19;
9897 goto basic_json_parser_21;
9899 goto basic_json_parser_4;
9905 goto basic_json_parser_23;
9909 goto basic_json_parser_4;
9911 goto basic_json_parser_24;
9920 goto basic_json_parser_25;
9922 goto basic_json_parser_4;
9928 goto basic_json_parser_26;
9932 goto basic_json_parser_28;
9934 goto basic_json_parser_4;
9938 basic_json_parser_2:
9941 last_token_type = token_type::end_of_input;
9944 basic_json_parser_4:
9946 basic_json_parser_5:
9948 last_token_type = token_type::parse_error;
9951 basic_json_parser_6:
9953 if (m_limit <= m_cursor)
9955 fill_line_buffer(1);
9958 if (yybm[0 + yych] & 32)
9960 goto basic_json_parser_6;
9965 basic_json_parser_9:
9967 yych = *(m_marker = ++m_cursor);
9970 goto basic_json_parser_5;
9974 goto basic_json_parser_31;
9978 goto basic_json_parser_5;
9982 goto basic_json_parser_31;
9984 goto basic_json_parser_5;
9985 basic_json_parser_10:
9988 last_token_type = token_type::value_separator;
9991 basic_json_parser_12:
9995 goto basic_json_parser_5;
9999 goto basic_json_parser_43;
10003 goto basic_json_parser_45;
10005 goto basic_json_parser_5;
10006 basic_json_parser_13:
10008 yych = *(m_marker = ++m_cursor);
10013 goto basic_json_parser_47;
10017 goto basic_json_parser_48;
10026 goto basic_json_parser_51;
10033 goto basic_json_parser_51;
10037 basic_json_parser_14:
10039 last_token_type = token_type::value_unsigned;
10042 basic_json_parser_15:
10044 m_marker = ++m_cursor;
10045 if ((m_limit - m_cursor) < 3)
10047 fill_line_buffer(3);
10050 if (yybm[0 + yych] & 64)
10052 goto basic_json_parser_15;
10058 goto basic_json_parser_47;
10060 goto basic_json_parser_14;
10066 goto basic_json_parser_51;
10070 goto basic_json_parser_51;
10072 goto basic_json_parser_14;
10074 basic_json_parser_17:
10077 last_token_type = token_type::name_separator;
10080 basic_json_parser_19:
10083 last_token_type = token_type::begin_array;
10086 basic_json_parser_21:
10089 last_token_type = token_type::end_array;
10092 basic_json_parser_23:
10094 yych = *(m_marker = ++m_cursor);
10097 goto basic_json_parser_52;
10099 goto basic_json_parser_5;
10100 basic_json_parser_24:
10102 yych = *(m_marker = ++m_cursor);
10105 goto basic_json_parser_53;
10107 goto basic_json_parser_5;
10108 basic_json_parser_25:
10110 yych = *(m_marker = ++m_cursor);
10113 goto basic_json_parser_54;
10115 goto basic_json_parser_5;
10116 basic_json_parser_26:
10119 last_token_type = token_type::begin_object;
10122 basic_json_parser_28:
10125 last_token_type = token_type::end_object;
10128 basic_json_parser_30:
10130 if (m_limit <= m_cursor)
10132 fill_line_buffer(1);
10135 basic_json_parser_31:
10136 if (yybm[0 + yych] & 128)
10138 goto basic_json_parser_30;
10146 goto basic_json_parser_32;
10150 goto basic_json_parser_33;
10152 goto basic_json_parser_35;
10158 goto basic_json_parser_32;
10162 goto basic_json_parser_36;
10164 goto basic_json_parser_37;
10173 goto basic_json_parser_39;
10175 goto basic_json_parser_38;
10181 goto basic_json_parser_40;
10185 goto basic_json_parser_41;
10189 goto basic_json_parser_42;
10193 basic_json_parser_32:
10194 m_cursor = m_marker;
10199 goto basic_json_parser_5;
10203 goto basic_json_parser_14;
10210 goto basic_json_parser_44;
10214 goto basic_json_parser_58;
10217 basic_json_parser_33:
10220 last_token_type = token_type::value_string;
10223 basic_json_parser_35:
10225 if (m_limit <= m_cursor)
10227 fill_line_buffer(1);
10236 goto basic_json_parser_30;
10240 goto basic_json_parser_32;
10242 goto basic_json_parser_30;
10250 goto basic_json_parser_32;
10252 goto basic_json_parser_30;
10258 goto basic_json_parser_30;
10260 goto basic_json_parser_32;
10270 goto basic_json_parser_30;
10274 goto basic_json_parser_30;
10276 goto basic_json_parser_32;
10284 goto basic_json_parser_30;
10286 goto basic_json_parser_32;
10292 goto basic_json_parser_30;
10296 goto basic_json_parser_55;
10298 goto basic_json_parser_32;
10302 basic_json_parser_36:
10304 if (m_limit <= m_cursor)
10306 fill_line_buffer(1);
10311 goto basic_json_parser_32;
10315 goto basic_json_parser_30;
10317 goto basic_json_parser_32;
10318 basic_json_parser_37:
10320 if (m_limit <= m_cursor)
10322 fill_line_buffer(1);
10327 goto basic_json_parser_32;
10331 goto basic_json_parser_36;
10333 goto basic_json_parser_32;
10334 basic_json_parser_38:
10336 if (m_limit <= m_cursor)
10338 fill_line_buffer(1);
10343 goto basic_json_parser_32;
10347 goto basic_json_parser_36;
10349 goto basic_json_parser_32;
10350 basic_json_parser_39:
10352 if (m_limit <= m_cursor)
10354 fill_line_buffer(1);
10359 goto basic_json_parser_32;
10363 goto basic_json_parser_36;
10365 goto basic_json_parser_32;
10366 basic_json_parser_40:
10368 if (m_limit <= m_cursor)
10370 fill_line_buffer(1);
10375 goto basic_json_parser_32;
10379 goto basic_json_parser_38;
10381 goto basic_json_parser_32;
10382 basic_json_parser_41:
10384 if (m_limit <= m_cursor)
10386 fill_line_buffer(1);
10391 goto basic_json_parser_32;
10395 goto basic_json_parser_38;
10397 goto basic_json_parser_32;
10398 basic_json_parser_42:
10400 if (m_limit <= m_cursor)
10402 fill_line_buffer(1);
10407 goto basic_json_parser_32;
10411 goto basic_json_parser_38;
10413 goto basic_json_parser_32;
10414 basic_json_parser_43:
10416 yych = *(m_marker = ++m_cursor);
10421 goto basic_json_parser_47;
10425 goto basic_json_parser_48;
10434 goto basic_json_parser_51;
10441 goto basic_json_parser_51;
10445 basic_json_parser_44:
10447 last_token_type = token_type::value_integer;
10450 basic_json_parser_45:
10452 m_marker = ++m_cursor;
10453 if ((m_limit - m_cursor) < 3)
10455 fill_line_buffer(3);
10462 goto basic_json_parser_47;
10466 goto basic_json_parser_44;
10468 goto basic_json_parser_45;
10476 goto basic_json_parser_44;
10478 goto basic_json_parser_51;
10484 goto basic_json_parser_51;
10486 goto basic_json_parser_44;
10489 basic_json_parser_47:
10490 yych = *++m_cursor;
10493 goto basic_json_parser_32;
10497 goto basic_json_parser_56;
10499 goto basic_json_parser_32;
10500 basic_json_parser_48:
10502 if (m_limit <= m_cursor)
10504 fill_line_buffer(1);
10509 goto basic_json_parser_50;
10513 goto basic_json_parser_48;
10515 basic_json_parser_50:
10517 last_token_type = token_type::parse_error;
10520 basic_json_parser_51:
10521 yych = *++m_cursor;
10526 goto basic_json_parser_59;
10528 goto basic_json_parser_32;
10534 goto basic_json_parser_59;
10538 goto basic_json_parser_32;
10542 goto basic_json_parser_60;
10544 goto basic_json_parser_32;
10546 basic_json_parser_52:
10547 yych = *++m_cursor;
10550 goto basic_json_parser_62;
10552 goto basic_json_parser_32;
10553 basic_json_parser_53:
10554 yych = *++m_cursor;
10557 goto basic_json_parser_63;
10559 goto basic_json_parser_32;
10560 basic_json_parser_54:
10561 yych = *++m_cursor;
10564 goto basic_json_parser_64;
10566 goto basic_json_parser_32;
10567 basic_json_parser_55:
10569 if (m_limit <= m_cursor)
10571 fill_line_buffer(1);
10578 goto basic_json_parser_32;
10582 goto basic_json_parser_65;
10584 goto basic_json_parser_32;
10590 goto basic_json_parser_65;
10594 goto basic_json_parser_32;
10598 goto basic_json_parser_65;
10600 goto basic_json_parser_32;
10602 basic_json_parser_56:
10604 m_marker = ++m_cursor;
10605 if ((m_limit - m_cursor) < 3)
10607 fill_line_buffer(3);
10614 goto basic_json_parser_58;
10618 goto basic_json_parser_56;
10625 goto basic_json_parser_51;
10629 goto basic_json_parser_51;
10632 basic_json_parser_58:
10634 last_token_type = token_type::value_float;
10637 basic_json_parser_59:
10638 yych = *++m_cursor;
10641 goto basic_json_parser_32;
10645 goto basic_json_parser_32;
10647 basic_json_parser_60:
10649 if (m_limit <= m_cursor)
10651 fill_line_buffer(1);
10656 goto basic_json_parser_58;
10660 goto basic_json_parser_60;
10662 goto basic_json_parser_58;
10663 basic_json_parser_62:
10664 yych = *++m_cursor;
10667 goto basic_json_parser_66;
10669 goto basic_json_parser_32;
10670 basic_json_parser_63:
10671 yych = *++m_cursor;
10674 goto basic_json_parser_67;
10676 goto basic_json_parser_32;
10677 basic_json_parser_64:
10678 yych = *++m_cursor;
10681 goto basic_json_parser_69;
10683 goto basic_json_parser_32;
10684 basic_json_parser_65:
10686 if (m_limit <= m_cursor)
10688 fill_line_buffer(1);
10695 goto basic_json_parser_32;
10699 goto basic_json_parser_71;
10701 goto basic_json_parser_32;
10707 goto basic_json_parser_71;
10711 goto basic_json_parser_32;
10715 goto basic_json_parser_71;
10717 goto basic_json_parser_32;
10719 basic_json_parser_66:
10720 yych = *++m_cursor;
10723 goto basic_json_parser_72;
10725 goto basic_json_parser_32;
10726 basic_json_parser_67:
10729 last_token_type = token_type::literal_null;
10732 basic_json_parser_69:
10735 last_token_type = token_type::literal_true;
10738 basic_json_parser_71:
10740 if (m_limit <= m_cursor)
10742 fill_line_buffer(1);
10749 goto basic_json_parser_32;
10753 goto basic_json_parser_74;
10755 goto basic_json_parser_32;
10761 goto basic_json_parser_74;
10765 goto basic_json_parser_32;
10769 goto basic_json_parser_74;
10771 goto basic_json_parser_32;
10773 basic_json_parser_72:
10776 last_token_type = token_type::literal_false;
10779 basic_json_parser_74:
10781 if (m_limit <= m_cursor)
10783 fill_line_buffer(1);
10790 goto basic_json_parser_32;
10794 goto basic_json_parser_30;
10796 goto basic_json_parser_32;
10802 goto basic_json_parser_30;
10806 goto basic_json_parser_32;
10810 goto basic_json_parser_30;
10812 goto basic_json_parser_32;
10818 return last_token_type;
10852 assert(m_line_buffer.empty()
10853 or m_content ==
reinterpret_cast<const lexer_char_t*
>(m_line_buffer.data()));
10856 assert(m_line_buffer.empty()
10857 or m_limit == m_content + m_line_buffer.size());
10860 assert(m_content <= m_start);
10861 assert(m_start <= m_cursor);
10862 assert(m_cursor <= m_limit);
10863 assert(m_marker ==
nullptr or m_marker <= m_limit);
10866 const auto num_processed_chars =
static_cast<size_t>(m_start - m_content);
10868 const auto offset_marker = (m_marker ==
nullptr) ? 0 : m_marker - m_start;
10870 const auto offset_cursor = m_cursor - m_start;
10873 if (m_stream ==
nullptr or m_stream->eof())
10878 m_line_buffer.assign(m_start, m_limit);
10882 m_line_buffer.append(1,
'\x00');
10885 m_line_buffer.append(
n - 1,
'\x01');
10891 m_line_buffer.erase(0, num_processed_chars);
10893 m_line_buffer_tmp.clear();
10894 std::getline(*m_stream, m_line_buffer_tmp,
'\n');
10897 m_line_buffer += m_line_buffer_tmp;
10898 m_line_buffer.push_back(
'\n');
10902 m_content =
reinterpret_cast<const lexer_char_t*
>(m_line_buffer.data());
10903 assert(m_content !=
nullptr);
10904 m_start = m_content;
10905 m_marker = m_start + offset_marker;
10906 m_cursor = m_start + offset_cursor;
10907 m_limit = m_start + m_line_buffer.size();
10913 assert(m_start !=
nullptr);
10914 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
10915 static_cast<size_t>(m_cursor - m_start));
10977 assert(m_cursor - m_start >= 2);
10980 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
10983 for (
const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
10986 auto e = std::find(i, m_cursor - 1,
'\\');
10990 for (
auto k = i; k <
e; k++)
10992 result.push_back(static_cast<typename string_t::value_type>(*k));
11050 auto codepoint = std::strtoul(
std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
11051 4).c_str(),
nullptr, 16);
11054 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
11057 if ((i + 6 >= m_limit) or * (i + 5) !=
'\\' or * (i + 6) !=
'u')
11059 JSON_THROW(std::invalid_argument(
"missing low surrogate"));
11063 auto codepoint2 = std::strtoul(
std::string(reinterpret_cast<typename string_t::const_pointer>
11064 (i + 7), 4).c_str(),
nullptr, 16);
11065 result += to_unicode(codepoint, codepoint2);
11069 else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
11072 JSON_THROW(std::invalid_argument(
"missing high surrogate"));
11077 result += to_unicode(codepoint);
11104 : m_start(start), m_end(end)
11113 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
11116 return parse(val, std::is_integral<T>());
11120 const char*
const m_start =
nullptr;
11121 const char*
const m_end =
nullptr;
11127 static void strtof(
float&
f,
const char* str,
char** endptr)
11129 f = std::strtof(str, endptr);
11132 static void strtof(
double&
f,
const char* str,
char** endptr)
11134 f = std::strtod(str, endptr);
11137 static void strtof(
long double&
f,
const char* str,
char** endptr)
11139 f = std::strtold(str, endptr);
11142 template<
typename T>
11149 std::array<char, 64> buf;
11150 const size_t len =
static_cast<size_t>(m_end - m_start);
11158 const auto loc = localeconv();
11159 assert(loc !=
nullptr);
11160 const char decimal_point_char = (loc->decimal_point ==
nullptr) ?
'.' : loc->decimal_point[0];
11162 const char*
data = m_start;
11164 if (decimal_point_char !=
'.')
11166 const size_t ds_pos =
static_cast<size_t>(std::find(m_start, m_end,
'.') - m_start);
11173 if ((len + 1) < buf.size())
11175 std::copy(m_start, m_end, buf.begin());
11177 buf[ds_pos] = decimal_point_char;
11182 tempstr.assign(m_start, m_end);
11183 tempstr[ds_pos] = decimal_point_char;
11184 data = tempstr.c_str();
11189 char* endptr =
nullptr;
11192 strtof(value,
data, &endptr);
11196 const bool ok = (endptr == (
data + len));
11198 if (ok and (value == static_cast<T>(0.0)) and (*
data ==
'-'))
11211 return std::strtoll(m_start, endptr, 10);
11216 return std::strtoull(m_start, endptr, 10);
11219 template<
typename T>
11222 char* endptr =
nullptr;
11224 const auto x = parse_integral(&endptr, std::is_signed<T>());
11227 static_assert(std::is_signed<T>() == std::is_signed<decltype(
x)>(),
"");
11229 value =
static_cast<T
>(
x);
11231 return (
x ==
static_cast<decltype(
x)
>(value))
11232 and (
x < 0) == (value < 0)
11235 and (m_start < m_end)
11236 and (endptr == m_end);
11261 assert(m_start !=
nullptr);
11262 assert(m_start < m_cursor);
11263 assert((token == token_type::value_unsigned) or
11264 (token == token_type::value_integer) or
11265 (token == token_type::value_float));
11267 strtonum num_converter(reinterpret_cast<const char*>(m_start),
11268 reinterpret_cast<const char*>(m_cursor));
11272 case lexer::token_type::value_unsigned:
11275 if (num_converter.
to(val))
11285 case lexer::token_type::value_integer:
11288 if (num_converter.
to(val))
11307 if (num_converter.
to(val))
11329 std::istream* m_stream =
nullptr;
11359 m_lexer(reinterpret_cast<const typename
lexer::lexer_char_t*>(buff),
std::strlen(buff))
11364 : callback(cb), m_lexer(is)
11368 template<
class IteratorType,
typename std::enable_if<
11369 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
11374 m_lexer(reinterpret_cast<const typename
lexer::lexer_char_t*>(&(*first)),
11375 static_cast<size_t>(
std::distance(first, last)))
11387 expect(lexer::token_type::end_of_input);
11400 switch (last_token)
11402 case lexer::token_type::begin_object:
11404 if (keep and (not callback
11405 or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
11416 if (last_token == lexer::token_type::end_object)
11419 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
11427 unexpect(lexer::token_type::value_separator);
11433 if (last_token == lexer::token_type::value_separator)
11439 expect(lexer::token_type::value_string);
11440 const auto key = m_lexer.get_string();
11442 bool keep_tag =
false;
11448 keep_tag = callback(depth, parse_event_t::key, k);
11458 expect(lexer::token_type::name_separator);
11462 auto value = parse_internal(keep);
11463 if (keep and keep_tag and not value.is_discarded())
11465 result[key] = std::move(value);
11468 while (last_token == lexer::token_type::value_separator);
11471 expect(lexer::token_type::end_object);
11473 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
11481 case lexer::token_type::begin_array:
11483 if (keep and (not callback
11484 or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
11495 if (last_token == lexer::token_type::end_array)
11498 if (callback and not callback(--depth, parse_event_t::array_end, result))
11506 unexpect(lexer::token_type::value_separator);
11512 if (last_token == lexer::token_type::value_separator)
11518 auto value = parse_internal(keep);
11519 if (keep and not value.is_discarded())
11521 result.push_back(std::move(value));
11524 while (last_token == lexer::token_type::value_separator);
11527 expect(lexer::token_type::end_array);
11529 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
11537 case lexer::token_type::literal_null:
11544 case lexer::token_type::value_string:
11546 const auto s = m_lexer.get_string();
11552 case lexer::token_type::literal_true:
11556 result.m_value =
true;
11560 case lexer::token_type::literal_false:
11564 result.m_value =
false;
11568 case lexer::token_type::value_unsigned:
11569 case lexer::token_type::value_integer:
11570 case lexer::token_type::value_float:
11572 m_lexer.get_number(result, last_token);
11580 unexpect(last_token);
11584 if (keep and callback and not callback(depth, parse_event_t::value, result))
11594 last_token = m_lexer.scan();
11600 if (t != last_token)
11602 std::string error_msg =
"parse error - unexpected ";
11603 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token_string() +
11605 lexer::token_type_name(last_token));
11606 error_msg +=
"; expected " + lexer::token_type_name(t);
11607 JSON_THROW(std::invalid_argument(error_msg));
11613 if (t == last_token)
11615 std::string error_msg =
"parse error - unexpected ";
11616 error_msg += (last_token == lexer::token_type::parse_error ? (
"'" + m_lexer.get_token_string() +
11618 lexer::token_type_name(last_token));
11619 JSON_THROW(std::invalid_argument(error_msg));
11675 : reference_tokens(split(s))
11695 return std::accumulate(reference_tokens.begin(),
11699 return a +
"/" + escape(
b);
11706 return to_string();
11715 JSON_THROW(std::domain_error(
"JSON pointer has no parent"));
11718 auto last = reference_tokens.back();
11719 reference_tokens.pop_back();
11726 return reference_tokens.empty();
11733 JSON_THROW(std::domain_error(
"JSON pointer has no parent"));
11752 for (
const auto& reference_token : reference_tokens)
11754 switch (result->m_type)
11758 if (reference_token ==
"0")
11761 result = &result->operator[](0);
11766 result = &result->operator[](reference_token);
11774 result = &result->operator[](reference_token);
11781 result = &result->operator[](
static_cast<size_type>(std::stoi(reference_token)));
11794 JSON_THROW(std::domain_error(
"invalid value to unflatten"));
11823 for (
const auto& reference_token : reference_tokens)
11829 const bool nums = std::all_of(reference_token.begin(),
11830 reference_token.end(),
11833 return std::isdigit(
x);
11838 if (nums or reference_token ==
"-")
11848 switch (ptr->m_type)
11853 ptr = &ptr->operator[](reference_token);
11860 if (reference_token.size() > 1 and reference_token[0] ==
'0')
11862 JSON_THROW(std::domain_error(
"array index must not begin with '0'"));
11865 if (reference_token ==
"-")
11868 ptr = &ptr->operator[](ptr->m_value.array->size());
11873 ptr = &ptr->operator[](
static_cast<size_type>(std::stoi(reference_token)));
11880 JSON_THROW(std::out_of_range(
"unresolved reference token '" + reference_token +
"'"));
11890 for (
const auto& reference_token : reference_tokens)
11892 switch (ptr->m_type)
11897 ptr = &ptr->at(reference_token);
11903 if (reference_token ==
"-")
11906 JSON_THROW(std::out_of_range(
"array index '-' (" +
11907 std::to_string(ptr->m_value.array->size()) +
11908 ") is out of range"));
11912 if (reference_token.size() > 1 and reference_token[0] ==
'0')
11914 JSON_THROW(std::domain_error(
"array index must not begin with '0'"));
11918 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
11924 JSON_THROW(std::out_of_range(
"unresolved reference token '" + reference_token +
"'"));
11942 for (
const auto& reference_token : reference_tokens)
11944 switch (ptr->m_type)
11949 ptr = &ptr->operator[](reference_token);
11955 if (reference_token ==
"-")
11958 JSON_THROW(std::out_of_range(
"array index '-' (" +
11959 std::to_string(ptr->m_value.array->size()) +
11960 ") is out of range"));
11964 if (reference_token.size() > 1 and reference_token[0] ==
'0')
11966 JSON_THROW(std::domain_error(
"array index must not begin with '0'"));
11970 ptr = &ptr->operator[](
static_cast<size_type>(std::stoi(reference_token)));
11976 JSON_THROW(std::out_of_range(
"unresolved reference token '" + reference_token +
"'"));
11986 for (
const auto& reference_token : reference_tokens)
11988 switch (ptr->m_type)
11993 ptr = &ptr->at(reference_token);
11999 if (reference_token ==
"-")
12002 JSON_THROW(std::out_of_range(
"array index '-' (" +
12003 std::to_string(ptr->m_value.array->size()) +
12004 ") is out of range"));
12008 if (reference_token.size() > 1 and reference_token[0] ==
'0')
12010 JSON_THROW(std::domain_error(
"array index must not begin with '0'"));
12014 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
12020 JSON_THROW(std::out_of_range(
"unresolved reference token '" + reference_token +
"'"));
12031 std::vector<std::string> result;
12034 if (reference_string.empty())
12040 if (reference_string[0] !=
'/')
12042 JSON_THROW(std::domain_error(
"JSON pointer must be empty or begin with '/'"));
12050 size_t slash = reference_string.find_first_of(
'/', 1),
12059 slash = reference_string.find_first_of(
'/', start))
12063 auto reference_token = reference_string.substr(start, slash - start);
12066 for (
size_t pos = reference_token.find_first_of(
'~');
12067 pos != std::string::npos;
12068 pos = reference_token.find_first_of(
'~', pos + 1))
12070 assert(reference_token[pos] ==
'~');
12073 if (pos == reference_token.size() - 1 or
12074 (reference_token[pos + 1] !=
'0' and
12075 reference_token[pos + 1] !=
'1'))
12077 JSON_THROW(std::domain_error(
"escape error: '~' must be followed with '0' or '1'"));
12082 unescape(reference_token);
12083 result.push_back(reference_token);
12106 assert(not f.empty());
12109 size_t pos = s.find(f);
12110 pos != std::string::npos;
12111 s.replace(pos, f.size(), t),
12112 pos = s.find(f, pos + t.size())
12120 replace_substring(s,
"~",
"~0");
12121 replace_substring(s,
"/",
"~1");
12129 replace_substring(s,
"~1",
"/");
12131 replace_substring(s,
"~0",
"~");
12152 result[reference_string] =
nullptr;
12157 for (
size_t i = 0; i < value.
m_value.
array->size(); ++i)
12159 flatten(reference_string +
"/" + std::to_string(i),
12171 result[reference_string] =
nullptr;
12178 flatten(reference_string +
"/" + escape(element.first),
12179 element.second, result);
12188 result[reference_string] = value;
12203 JSON_THROW(std::domain_error(
"only objects can be unflattened"));
12211 if (not element.second.is_primitive())
12213 JSON_THROW(std::domain_error(
"values in object must be primitive"));
12231 return lhs.reference_tokens == rhs.reference_tokens;
12237 return !(lhs == rhs);
12241 std::vector<std::string> reference_tokens {};
12391 json_pointer::flatten(
"", *
this, result);
12424 return json_pointer::unflatten(*
this);
12478 enum class patch_operations {add,
remove, replace, move, copy,
test, invalid};
12484 return patch_operations::add;
12486 if (op ==
"remove")
12488 return patch_operations::remove;
12490 if (op ==
"replace")
12492 return patch_operations::replace;
12496 return patch_operations::move;
12500 return patch_operations::copy;
12504 return patch_operations::test;
12507 return patch_operations::invalid;
12522 if (top_pointer != ptr)
12524 result.
at(top_pointer);
12528 const auto last_path = ptr.
pop_back();
12537 parent[last_path] = val;
12543 if (last_path ==
"-")
12550 const auto idx = std::stoi(last_path);
12551 if (static_cast<size_type>(idx) > parent.
size())
12554 JSON_THROW(std::out_of_range(
"array index " + std::to_string(idx) +
" is out of range"));
12575 const auto operation_remove = [&result](
json_pointer & ptr)
12578 const auto last_path = ptr.
pop_back();
12585 auto it = parent.
find(last_path);
12586 if (it != parent.
end())
12592 JSON_THROW(std::out_of_range(
"key '" + last_path +
"' not found"));
12598 parent.
erase(static_cast<size_type>(std::stoi(last_path)));
12606 JSON_THROW(std::invalid_argument(
"JSON patch must be an array of objects"));
12610 for (
const auto& val : json_patch)
12613 const auto get_value = [&val](
const std::string & op,
12621 const auto error_msg = (op ==
"op") ?
"operation" :
"operation '" + op +
"'";
12624 if (it == val.m_value.object->end())
12626 JSON_THROW(std::invalid_argument(error_msg +
" must have member '" + member +
"'"));
12630 if (string_type and not it->second.is_string())
12632 JSON_THROW(std::invalid_argument(error_msg +
" must have string member '" + member +
"'"));
12640 if (not val.is_object())
12642 JSON_THROW(std::invalid_argument(
"JSON patch must be an array of objects"));
12646 const std::string op = get_value(
"op",
"op",
true);
12647 const std::string path = get_value(op,
"path",
true);
12650 switch (get_op(op))
12652 case patch_operations::add:
12654 operation_add(ptr, get_value(
"add",
"value",
false));
12658 case patch_operations::remove:
12660 operation_remove(ptr);
12664 case patch_operations::replace:
12667 result.
at(ptr) = get_value(
"replace",
"value",
false);
12671 case patch_operations::move:
12673 const std::string from_path = get_value(
"move",
"from",
true);
12683 operation_remove(from_ptr);
12684 operation_add(ptr, v);
12688 case patch_operations::copy:
12690 const std::string from_path = get_value(
"copy",
"from",
true);;
12694 result[ptr] = result.
at(from_ptr);
12698 case patch_operations::test:
12700 bool success =
false;
12705 success = (result.
at(ptr) == get_value(
"test",
"value",
false));
12715 JSON_THROW(std::domain_error(
"unsuccessful: " + val.dump()));
12721 case patch_operations::invalid:
12725 JSON_THROW(std::invalid_argument(
"operation value '" + op +
"' is invalid"));
12773 if (source == target)
12778 if (source.
type() != target.
type())
12790 switch (source.
type())
12796 while (i < source.
size() and i < target.
size())
12799 auto temp_diff = diff(source[i], target[i], path +
"/" + std::to_string(i));
12800 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
12809 while (i < source.
size())
12816 {
"path", path +
"/" + std::to_string(i)}
12822 while (i < target.
size())
12827 {
"path", path +
"/" + std::to_string(i)},
12828 {
"value", target[i]}
12839 for (
auto it = source.
begin(); it != source.
end(); ++it)
12842 const auto key = json_pointer::escape(it.key());
12844 if (target.
find(it.key()) != target.
end())
12847 auto temp_diff = diff(it.value(), target[it.key()], path +
"/" + key);
12848 result.
insert(result.
end(), temp_diff.begin(), temp_diff.end());
12856 {
"path", path +
"/" + key}
12862 for (
auto it = target.
begin(); it != target.
end(); ++it)
12864 if (source.
find(it.key()) == source.
end())
12867 const auto key = json_pointer::escape(it.key());
12871 {
"path", path +
"/" + key},
12872 {
"value", it.value()}
12931 is_nothrow_move_constructible<nlohmann::json>::value and
12932 is_nothrow_move_assignable<nlohmann::json>::value
12950 const auto&
h = hash<nlohmann::json::string_t>();
12951 return h(j.
dump());
12993 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) 12994 #pragma GCC diagnostic pop 12999 #undef JSON_DEPRECATED friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
object_t * object
object (stored with pointer to save storage)
reference operator+=(const basic_json &val)
add an object to an array
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
unsigned char lexer_char_t
the char type to use in the lexer
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
static void to_msgpack_internal(const basic_json &j, std::vector< uint8_t > &v)
create a MessagePack serialization of a given JSON value
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
json_reverse_iterator operator++(int)
post-increment (it++)
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
void emplace_back(Args &&... args)
add an object to an array
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
void set_end() noexcept
set iterator to a defined past the end
void set_begin() noexcept
set the iterator to the first value
friend std::ostream & operator<<(std::ostream &os, primitive_iterator_t it)
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
size_type max_size() const noexcept
returns the maximum possible number of elements
parser(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr)
a parser reading from an iterator range with contiguous storage
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
parser(std::istream &is, const parser_callback_t cb=nullptr)
a parser reading from an input stream
std::numeric_limits< RealIntegerType > RealLimits
basic_json(basic_json &&other) noexcept
move constructor
#define JSON_CATCH(exception)
NumberFloatType number_float_t
a type for a number (floating-point)
strtonum(const char *start, const char *end)
basic_json parse_internal(bool keep)
the actual parser
iter_impl operator--(int)
post-decrement (it–)
difference_type operator-(const iter_impl &other) const
return difference
an iterator for primitive JSON types
primitive_iterator_t primitive_iterator
generic iterator for all other types
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
void expect(typename lexer::token_type t) const
reference get_checked(pointer ptr) const
number value (unsigned integer)
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
iter_impl operator+(difference_type i)
add to iterator
static basic_json parse(std::istream &&i, const parser_callback_t cb=nullptr)
deserialize from stream
IteratorType erase(IteratorType pos)
remove element given an iterator
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
void operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(std::declval< from_json_fn >().call(j, val, priority_tag< 1 > {})))
array_t * array
array (stored with pointer to save storage)
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
string_t * string
string (stored with pointer to save storage)
lexer(const lexer_char_t *buff, const size_t len) noexcept
a lexer from a buffer with given length
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
locale-independent serialization for built-in arithmetic types
basic_json parse()
public parser interface
json_value(const string_t &value)
constructor for strings
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
primitive_iterator_t & operator+=(difference_type n)
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
static basic_json parse(std::istream &i, const parser_callback_t cb=nullptr)
deserialize from stream
std::string to_string() const noexcept
return a string representation of the JSON pointer
token_type scan()
This function implements a scanner for JSON.
helper class for iteration
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
json_value(value_t t)
constructor for empty values of a given type
NumberIntegerType number_integer_t
a type for a number (integer)
reference operator[](const typename object_t::key_type &key)
access specified object element
constexpr bool is_primitive() const noexcept
return whether type is primitive
static void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
a class to store JSON values
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag< 0 >)
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)
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
iterator insert(const_iterator pos, basic_json &&val)
inserts element
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
default JSONSerializer template argument
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
typename basic_json::difference_type difference_type
a type to represent differences between iterators
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
constexpr bool is_structured() const noexcept
return whether type is structured
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
static allocator_type get_allocator()
returns the allocator associated with the container
StringType string_t
a type for a string
friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
iterator end() noexcept
returns an iterator to one past the last element
void set_end() noexcept
set the iterator past the last value
static string_t escape_string(const string_t &s)
escape a string
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
static void strtof(float &f, const char *str, char **endptr)
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
reference operator[](T *(&key)[n])
access specified object element
basic_json flatten() const
return flattened JSON value
iterator begin() noexcept
returns an iterator to the first element
iter_impl & operator--()
pre-decrement (–it)
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
static void check_length(const size_t size, const size_t len, const size_t offset)
std::bidirectional_iterator_tag iterator_category
the category of the iterator
std::ptrdiff_t difference_type
a type to represent differences between iterators
static void unescape(std::string &s)
unescape tilde and slash
reference operator+=(const typename object_t::value_type &val)
add an object to an object
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
signed long long parse_integral(char **endptr, std::true_type) const
reference value() const
return the value of an iterator
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
number_unsigned_t number_unsigned
number (unsigned integer)
number_float_t number_float
number (floating-point)
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
static basic_json from_cbor(const std::vector< uint8_t > &v, const size_t start_index=0)
create a JSON value from a byte vector in CBOR format
static std::size_t extra_space(const string_t &s) noexcept
calculates the extra space to escape a JSON string
static basic_json parse(const CharT s, const parser_callback_t cb=nullptr)
deserialize from string literal
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
const value_type & const_reference
the type of an element const reference
constexpr bool is_object() const noexcept
return whether value is an object
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
array (ordered collection of values)
json_reverse_iterator operator+(difference_type i) const
add to iterator
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)
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
json_reverse_iterator & operator++()
pre-increment (++it)
IteratorType::reference value() const
return value of the iterator
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
iter_impl(pointer object) noexcept
constructor for a given JSON instance
unsigned long long parse_integral(char **endptr, std::false_type) const
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
void to_json(BasicJsonType &j, T b) noexcept
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
const_reference operator[](T *key) const
read-only access specified object element
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
static std::string escape(std::string s)
escape tilde and slash
typename Base::reference reference
the reference type for the pointed-to element
static basic_json parse(const ContiguousContainer &c, const parser_callback_t cb=nullptr)
deserialize from a container with contiguous storage
NLOHMANN_JSON_HAS_HELPER(mapped_type)
constexpr bool is_null() const noexcept
return whether value is null
iteration_proxy_internal(IteratorType it) noexcept
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
bool operator!=(const iter_impl &other) const
comparison: not equal
JSONSerializer< T, SFINAE > json_serializer
const_reference get_checked(const_pointer ptr) const
static basic_json unflatten(const basic_json &value)
discarded by the the parser callback function
reference at(size_type idx)
access specified array element with bounds checking
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
iter_impl & operator-=(difference_type i)
subtract from iterator
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
basic_json(const basic_json &other)
copy constructor
ValueType value(const json_pointer &ptr, ValueType default_value) const
access specified object element via JSON Pointer with default value
void push_back(std::initializer_list< basic_json > init)
add an object to an object
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
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
void clear() noexcept
clears the contents
primitive_iterator_t & operator--()
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
std::vector< std::string > reference_tokens
the reference tokens
std::string type_name() const
return the type as string
static void strtof(double &f, const char *str, char **endptr)
constexpr bool is_number() const noexcept
return whether value is a number
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
reference operator[](T *key)
access specified object element
friend class basic_json
allow basic_json to access private members
internal_iterator m_it
the actual iterator of the associated instance
#define JSON_THROW(exception)
basic_json::string_t key() const
return key of the iterator
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
reference get_and_create(reference j) const
create and return a reference to the pointed to value
string_t get_token_string() const
return string representation of last read token
json_reverse_iterator & operator+=(difference_type i)
add to iterator
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Bool_t operator!=(const TDatime &d1, const TDatime &d2)
TString operator+(const TString &s1, const TString &s2)
Use the special concatenation constructor.
reference operator*() const
return a reference to the value pointed to by the iterator
parse string into a built-in arithmetic type as if the current locale is POSIX.
static void to_cbor_internal(const basic_json &j, std::vector< uint8_t > &v)
create a CBOR serialization of a given JSON value
bool get_number(basic_json &result, const token_type token) const
return number value for number tokens
size_type size() const noexcept
returns the number of elements
difference_type get_value() const noexcept
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
string_t get_string() const
return string value for string tokens
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a MessagePack serialization of a given JSON value
auto call(const BasicJsonType &j, T &val, priority_tag< 1 >) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
reference back()
access the last element
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
bool operator<(const iter_impl &other) const
comparison: smaller
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
iter_impl(const iter_impl &other) noexcept
copy constructor
iter_impl operator++(int)
post-increment (it++)
reference operator[](difference_type n) const
access to successor
const_iterator begin() const noexcept
returns a const iterator to the first element
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
constexpr bool is_boolean() const noexcept
return whether value is a boolean
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
namespace for Niels Lohmann
parse_event_t
JSON callback events.
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
static void flatten(const std::string &reference_string, const basic_json &value, basic_json &result)
object (unordered set of name/value pairs)
constexpr bool is_string() const noexcept
return whether value is a string
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
ReferenceType get_ref()
get a reference value (implicit)
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
typename std::enable_if< B, T >::type enable_if_t
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
primitive_iterator_t operator--(int)
lexer(std::istream &s)
a lexer from an input stream
void x_write(NumberType x, std::true_type)
value_t m_type
the type of the current element
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
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
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
object_t::iterator object_iterator
iterator for JSON objects
static basic_json from_msgpack(const std::vector< uint8_t > &v, const size_t start_index=0)
create a JSON value from a byte vector in MessagePack format
TTime operator*(const TTime &t1, const TTime &t2)
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
PointerType get_ptr() noexcept
get a pointer value (implicit)
value_t
the JSON type enumeration
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
json_reverse_iterator & operator--()
pre-decrement (–it)
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
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
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
void push_back(const basic_json &val)
add an object to an array
bool operator<=(const iter_impl &other) const
comparison: less than or equal
static void strtof(long double &f, const char *str, char **endptr)
primitive_iterator_t & operator-=(difference_type n)
difference_type m_it
iterator as signed integer type
bool parse(T &value, std::false_type) const
void x_write(NumberType x, std::false_type)
static std::string token_type_name(const token_type t)
return name of values of type token_type (only used for errors)
iter_impl & operator=(iter_impl other) noexcept(std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
static T * create(Args &&... args)
helper for exception-safe object creation
static basic_json from_cbor_internal(const std::vector< uint8_t > &v, size_t &idx)
create a JSON value from a given CBOR vector
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
token_type
token types for the parser
object_t::key_type key() const
return the key of an object iterator
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
const_reference back() const
access the last element
constexpr bool is_discarded() const noexcept
return whether value is discarded
JSON_DEPRECATED basic_json(std::istream &i, const parser_callback_t cb=nullptr)
construct a JSON value given an input stream
array_t::iterator array_iterator
iterator for JSON arrays
BooleanType boolean_t
a type for a boolean
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
void from_json(const BasicJsonType &j, ArithmeticType &val)
bool operator==(const iter_impl &other) const
comparison: equal
static basic_json parse(T(&array)[N], const parser_callback_t cb=nullptr)
deserialize from an array
const char * c_str() const
reference operator+=(basic_json &&val)
add an object to an array
bool operator>(const iter_impl &other) const
comparison: greater than
void unexpect(typename lexer::token_type t) const
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
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
lexer::token_type get_token()
get next token from lexer
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
primitive_iterator_t operator++(int)
void set_begin() noexcept
set iterator to a defined beginning
const_iterator cbegin() const noexcept
returns a const iterator to the first element
void swap(array_t &other)
exchanges the values
const_reference at(size_type idx) const
access specified array element with bounds checking
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
iteration_proxy(typename IteratorType::reference cont)
construct iteration proxy from a container
basic_json(const value_t value_type)
create an empty value with a given type
primitive_iterator_t operator+(difference_type i)
reference operator[](difference_type n) const
access to successor
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
proxy class for the iterator_wrapper functions
number_integer_t number_integer
number (integer)
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
static constexpr double s
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
void swap(string_t &other)
exchanges the values
internal_iterator() noexcept
create an uninitialized internal_iterator
bool parse(T &value, std::true_type) const
constexpr bool is_end() const noexcept
return whether the iterator is at end
json_value(const array_t &value)
constructor for arrays
parser(const char *buff, const parser_callback_t cb=nullptr)
a parser reading from a string literal
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
const_reference get_unchecked(const_pointer ptr) const
return a const reference to the pointed to value
iterator insert(const_iterator pos, const basic_json &val)
inserts element
constexpr bool is_array() const noexcept
return whether value is an array
const_iterator end() const noexcept
returns a const iterator to one past the last element
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Binding & operator=(OUT(*fun)(void))
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
std::integral_constant< bool, std::is_convertible< T, int >::value and std::is_enum< T >::value > is_unscoped_enum
numtostr(NumberType value)
friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
json_value(boolean_t v) noexcept
constructor for booleans
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t &>(), std::forward< CompatibleType >(val))))
create a JSON value
typedef void((*Func_t)())
static basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr)
deserialize from an iterator range with contiguous storage
reference operator[](size_type idx)
access specified array element
Bool_t operator==(const TDatime &d1, const TDatime &d2)
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
void push_back(basic_json &&val)
add an object to an array
reference front()
access the first element
IteratorType::reference container
the container to iterate
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
ReferenceType get_ref() const
get a reference value (implicit)
std::size_t size_type
a type to represent container sizes
reference value() const
return the value of an iterator
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
json_reverse_iterator operator--(int)
post-decrement (it–)
iter_impl & operator+=(difference_type i)
add to iterator
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
const_reference operator[](size_type idx) const
access specified array element
void assert_invariant() const
checks the class invariants
void call(BasicJsonType &, T &&, priority_tag< 0 >) const noexcept
iter_impl operator-(difference_type i)
subtract from iterator
void operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(std::declval< to_json_fn >().call(j, std::forward< T >(val), priority_tag< 1 > {})))
iter_impl & operator++()
pre-increment (++it)
basic_json<> json
default JSON class
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
pointer operator->() const
dereference the iterator
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
static void add_to_vector(std::vector< uint8_t > &vec, size_t bytes, const T number)
void fill_line_buffer(size_t n=0)
append data from the stream to the line buffer
json_pointer(const std::string &s="")
create JSON pointer
void swap(object_t &other)
exchanges the values
json_value(const object_t &value)
constructor for objects
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
a template for a reverse iterator class
void call(const BasicJsonType &, T &, priority_tag< 0 >) const noexcept
void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b)
const_iterator cend() const noexcept
returns a const iterator to one past the last element
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
basic_json value_type
the type of elements in a basic_json container
void push_back(const typename object_t::value_type &val)
add an object to an object
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
iterator find(typename object_t::key_type key)
find an element in a JSON object
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
basic_json unflatten() const
unflatten a previously flattened JSON value
auto call(BasicJsonType &j, T &&val, priority_tag< 1 >) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
void erase(const size_type idx)
remove element from a JSON array given an index
number value (signed integer)
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
pointer m_object
associated JSON instance
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
reference get_unchecked(pointer ptr) const
return a reference to the pointed to value
bool is_root() const
return whether pointer points to the root document
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
reference operator+=(std::initializer_list< basic_json > init)
add an object to an object
primitive_iterator_t & operator++()
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
std::string pop_back()
remove and return last reference pointer
IteratorType anchor
the iterator
void to_json(BasicJsonType &j, const CompatibleObjectType &arr)
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
object_t::key_type key() const
return the key of an object iterator
AllocatorType< basic_json > allocator_type
the allocator type
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
const_reference front() const
access the first element
a template for a random access iterator for the basic_json class
difference_type operator-(const json_reverse_iterator &other) const
return difference
number value (floating-point)
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
json_value m_value
the value of the current element
string_t dump(const int indent=-1) const
serialization
double ldexp(double, int)
const_reference at(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
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
bool empty() const noexcept
checks whether the container is empty
std::string & operator+=(std::string &left, const TString &right)
static basic_json meta()
returns version information on the library
Bool_t operator<=(const TDatime &d1, const TDatime &d2)
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type