3 __| | __| | | | JSON for Modern C++
\r
4 | | |__ | | | | | | version 2.1.1
\r
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
\r
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
\r
8 Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
\r
10 Permission is hereby granted, free of charge, to any person obtaining a copy
\r
11 of this software and associated documentation files (the "Software"), to deal
\r
12 in the Software without restriction, including without limitation the rights
\r
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
14 copies of the Software, and to permit persons to whom the Software is
\r
15 furnished to do so, subject to the following conditions:
\r
17 The above copyright notice and this permission notice shall be included in all
\r
18 copies or substantial portions of the Software.
\r
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
29 #ifndef NLOHMANN_JSON_HPP
\r
30 #define NLOHMANN_JSON_HPP
\r
32 #include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
\r
33 #include <array> // array
\r
34 #include <cassert> // assert
\r
35 #include <cctype> // isdigit
\r
36 #include <ciso646> // and, not, or
\r
37 #include <cmath> // isfinite, labs, ldexp, signbit
\r
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
\r
39 #include <cstdint> // int64_t, uint64_t
\r
40 #include <cstdlib> // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull
\r
41 #include <cstring> // strlen
\r
42 #include <forward_list> // forward_list
\r
43 #include <functional> // function, hash, less
\r
44 #include <initializer_list> // initializer_list
\r
45 #include <iomanip> // setw
\r
46 #include <iostream> // istream, ostream
\r
47 #include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
\r
48 #include <limits> // numeric_limits
\r
49 #include <locale> // locale
\r
50 #include <map> // map
\r
51 #include <memory> // addressof, allocator, allocator_traits, unique_ptr
\r
52 #include <numeric> // accumulate
\r
53 #include <sstream> // stringstream
\r
54 #include <stdexcept> // domain_error, invalid_argument, out_of_range
\r
55 #include <string> // getline, stoi, string, to_string
\r
56 #include <type_traits> // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type
\r
57 #include <utility> // declval, forward, make_pair, move, pair, swap
\r
58 #include <vector> // vector
\r
60 // allow for portable deprecation warnings
\r
61 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
\r
62 #define JSON_DEPRECATED __attribute__((deprecated))
\r
63 #elif defined(_MSC_VER)
\r
64 #define JSON_DEPRECATED __declspec(deprecated)
\r
66 #define JSON_DEPRECATED
\r
69 // allow to disable exceptions
\r
70 #if not defined(JSON_NOEXCEPTION) || defined(__EXCEPTIONS)
\r
71 #define JSON_THROW(exception) throw exception
\r
72 #define JSON_TRY try
\r
73 #define JSON_CATCH(exception) catch(exception)
\r
75 #define JSON_THROW(exception) std::abort()
\r
76 #define JSON_TRY if(true)
\r
77 #define JSON_CATCH(exception) if(false)
\r
81 @brief namespace for Niels Lohmann
\r
82 @see https://github.com/nlohmann
\r
83 @since version 1.0.0
\r
89 @brief unnamed namespace with internal helper functions
\r
91 This namespace collects some functions that could not be defined inside the
\r
92 @ref basic_json class.
\r
94 @since version 2.1.0
\r
98 ///////////////////////////
\r
99 // JSON type enumeration //
\r
100 ///////////////////////////
\r
103 @brief the JSON type enumeration
\r
105 This enumeration collects the different JSON types. It is internally used to
\r
106 distinguish the stored values, and the functions @ref basic_json::is_null(),
\r
107 @ref basic_json::is_object(), @ref basic_json::is_array(),
\r
108 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
\r
109 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
\r
110 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
\r
111 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
\r
112 @ref basic_json::is_structured() rely on it.
\r
114 @note There are three enumeration entries (number_integer, number_unsigned, and
\r
115 number_float), because the library distinguishes these three types for numbers:
\r
116 @ref basic_json::number_unsigned_t is used for unsigned integers,
\r
117 @ref basic_json::number_integer_t is used for signed integers, and
\r
118 @ref basic_json::number_float_t is used for floating-point numbers or to
\r
119 approximate integers which do not fit in the limits of their respective type.
\r
121 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
\r
122 value with the default value for a given type
\r
124 @since version 1.0.0
\r
126 enum class value_t : uint8_t
\r
128 null, ///< null value
\r
129 object, ///< object (unordered set of name/value pairs)
\r
130 array, ///< array (ordered collection of values)
\r
131 string, ///< string value
\r
132 boolean, ///< boolean value
\r
133 number_integer, ///< number value (signed integer)
\r
134 number_unsigned, ///< number value (unsigned integer)
\r
135 number_float, ///< number value (floating-point)
\r
136 discarded ///< discarded by the the parser callback function
\r
140 @brief comparison operator for JSON types
\r
142 Returns an ordering that is similar to Python:
\r
143 - order: null < boolean < number < object < array < string
\r
144 - furthermore, each type is not smaller than itself
\r
146 @since version 1.0.0
\r
148 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
\r
150 static constexpr std::array<uint8_t, 8> order = {{
\r
162 // discarded values are not comparable
\r
163 if (lhs == value_t::discarded or rhs == value_t::discarded)
\r
168 return order[static_cast<std::size_t>(lhs)] <
\r
169 order[static_cast<std::size_t>(rhs)];
\r
177 // alias templates to reduce boilerplate
\r
178 template<bool B, typename T = void>
\r
179 using enable_if_t = typename std::enable_if<B, T>::type;
\r
181 template<typename T>
\r
182 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
\r
184 // taken from http://stackoverflow.com/a/26936864/266378
\r
185 template<typename T>
\r
186 using is_unscoped_enum =
\r
187 std::integral_constant<bool, std::is_convertible<T, int>::value and
\r
188 std::is_enum<T>::value>;
\r
191 Implementation of two C++17 constructs: conjunction, negation. This is needed
\r
192 to avoid evaluating all the traits in a condition
\r
194 For example: not std::is_same<void, T>::value and has_value_type<T>::value
\r
195 will not compile when T = void (on MSVC at least). Whereas
\r
196 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
\r
197 stop evaluating if negation<...>::value == false
\r
199 Please note that those constructs must be used with caution, since symbols can
\r
200 become very long quickly (which can slow down compilation and cause MSVC
\r
201 internal compiler errors). Only use it when you have to (see example ahead).
\r
203 template<class...> struct conjunction : std::true_type {};
\r
204 template<class B1> struct conjunction<B1> : B1 {};
\r
205 template<class B1, class... Bn>
\r
206 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
\r
208 template<class B> struct negation : std::integral_constant < bool, !B::value > {};
\r
210 // dispatch utility (taken from ranges-v3)
\r
211 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
\r
212 template<> struct priority_tag<0> {};
\r
219 template<value_t> struct external_constructor;
\r
222 struct external_constructor<value_t::boolean>
\r
224 template<typename BasicJsonType>
\r
225 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
\r
227 j.m_type = value_t::boolean;
\r
229 j.assert_invariant();
\r
234 struct external_constructor<value_t::string>
\r
236 template<typename BasicJsonType>
\r
237 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
\r
239 j.m_type = value_t::string;
\r
241 j.assert_invariant();
\r
246 struct external_constructor<value_t::number_float>
\r
248 template<typename BasicJsonType>
\r
249 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
\r
251 // replace infinity and NAN by null
\r
252 if (not std::isfinite(val))
\r
254 j = BasicJsonType{};
\r
258 j.m_type = value_t::number_float;
\r
261 j.assert_invariant();
\r
266 struct external_constructor<value_t::number_unsigned>
\r
268 template<typename BasicJsonType>
\r
269 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
\r
271 j.m_type = value_t::number_unsigned;
\r
273 j.assert_invariant();
\r
278 struct external_constructor<value_t::number_integer>
\r
280 template<typename BasicJsonType>
\r
281 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
\r
283 j.m_type = value_t::number_integer;
\r
285 j.assert_invariant();
\r
290 struct external_constructor<value_t::array>
\r
292 template<typename BasicJsonType>
\r
293 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
\r
295 j.m_type = value_t::array;
\r
297 j.assert_invariant();
\r
300 template<typename BasicJsonType, typename CompatibleArrayType,
\r
301 enable_if_t<not std::is_same<CompatibleArrayType,
\r
302 typename BasicJsonType::array_t>::value,
\r
304 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
\r
308 j.m_type = value_t::array;
\r
309 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
\r
310 j.assert_invariant();
\r
315 struct external_constructor<value_t::object>
\r
317 template<typename BasicJsonType>
\r
318 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
\r
320 j.m_type = value_t::object;
\r
322 j.assert_invariant();
\r
325 template<typename BasicJsonType, typename CompatibleObjectType,
\r
326 enable_if_t<not std::is_same<CompatibleObjectType,
\r
327 typename BasicJsonType::object_t>::value,
\r
329 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
\r
334 j.m_type = value_t::object;
\r
335 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
\r
336 j.assert_invariant();
\r
341 ////////////////////////
\r
342 // has_/is_ functions //
\r
343 ////////////////////////
\r
346 @brief Helper to determine whether there's a key_type for T.
\r
348 This helper is used to tell associative containers apart from other containers
\r
349 such as sequence containers. For instance, `std::map` passes the test as it
\r
350 contains a `mapped_type`, whereas `std::vector` fails the test.
\r
352 @sa http://stackoverflow.com/a/7728728/266378
\r
353 @since version 1.0.0, overworked in version 2.0.6
\r
355 #define NLOHMANN_JSON_HAS_HELPER(type) \
\r
356 template<typename T> struct has_##type { \
\r
358 template<typename U, typename = typename U::type> \
\r
359 static int detect(U &&); \
\r
360 static void detect(...); \
\r
362 static constexpr bool value = \
\r
363 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
\r
366 NLOHMANN_JSON_HAS_HELPER(mapped_type);
\r
367 NLOHMANN_JSON_HAS_HELPER(key_type);
\r
368 NLOHMANN_JSON_HAS_HELPER(value_type);
\r
369 NLOHMANN_JSON_HAS_HELPER(iterator);
\r
371 #undef NLOHMANN_JSON_HAS_HELPER
\r
374 template<bool B, class RealType, class CompatibleObjectType>
\r
375 struct is_compatible_object_type_impl : std::false_type {};
\r
377 template<class RealType, class CompatibleObjectType>
\r
378 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
\r
380 static constexpr auto value =
\r
381 std::is_constructible<typename RealType::key_type,
\r
382 typename CompatibleObjectType::key_type>::value and
\r
383 std::is_constructible<typename RealType::mapped_type,
\r
384 typename CompatibleObjectType::mapped_type>::value;
\r
387 template<class BasicJsonType, class CompatibleObjectType>
\r
388 struct is_compatible_object_type
\r
390 static auto constexpr value = is_compatible_object_type_impl <
\r
391 conjunction<negation<std::is_same<void, CompatibleObjectType>>,
\r
392 has_mapped_type<CompatibleObjectType>,
\r
393 has_key_type<CompatibleObjectType>>::value,
\r
394 typename BasicJsonType::object_t, CompatibleObjectType >::value;
\r
397 template<typename BasicJsonType, typename T>
\r
398 struct is_basic_json_nested_type
\r
400 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
\r
401 std::is_same<T, typename BasicJsonType::const_iterator>::value or
\r
402 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
\r
403 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value or
\r
404 std::is_same<T, typename BasicJsonType::json_pointer>::value;
\r
407 template<class BasicJsonType, class CompatibleArrayType>
\r
408 struct is_compatible_array_type
\r
410 static auto constexpr value =
\r
411 conjunction<negation<std::is_same<void, CompatibleArrayType>>,
\r
412 negation<is_compatible_object_type<
\r
413 BasicJsonType, CompatibleArrayType>>,
\r
414 negation<std::is_constructible<typename BasicJsonType::string_t,
\r
415 CompatibleArrayType>>,
\r
416 negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
\r
417 has_value_type<CompatibleArrayType>,
\r
418 has_iterator<CompatibleArrayType>>::value;
\r
421 template<bool, typename, typename>
\r
422 struct is_compatible_integer_type_impl : std::false_type {};
\r
424 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
\r
425 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
\r
427 // is there an assert somewhere on overflows?
\r
428 using RealLimits = std::numeric_limits<RealIntegerType>;
\r
429 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
\r
431 static constexpr auto value =
\r
432 std::is_constructible<RealIntegerType,
\r
433 CompatibleNumberIntegerType>::value and
\r
434 CompatibleLimits::is_integer and
\r
435 RealLimits::is_signed == CompatibleLimits::is_signed;
\r
438 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
\r
439 struct is_compatible_integer_type
\r
441 static constexpr auto value =
\r
442 is_compatible_integer_type_impl <
\r
443 std::is_integral<CompatibleNumberIntegerType>::value and
\r
444 not std::is_same<bool, CompatibleNumberIntegerType>::value,
\r
445 RealIntegerType, CompatibleNumberIntegerType > ::value;
\r
449 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
\r
450 template<typename BasicJsonType, typename T>
\r
451 struct has_from_json
\r
454 // also check the return type of from_json
\r
455 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
\r
456 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
\r
457 static int detect(U&&);
\r
458 static void detect(...);
\r
461 static constexpr bool value = std::is_integral<decltype(
\r
462 detect(std::declval<typename BasicJsonType::template json_serializer<T, void > >()))>::value;
\r
465 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
\r
466 // this overload is used for non-default-constructible user-defined-types
\r
467 template<typename BasicJsonType, typename T>
\r
468 struct has_non_default_from_json
\r
473 typename = enable_if_t<std::is_same<
\r
474 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
\r
475 static int detect(U&&);
\r
476 static void detect(...);
\r
479 static constexpr bool value = std::is_integral<decltype(detect(
\r
480 std::declval<typename BasicJsonType::template json_serializer<T, void> >()))>::value;
\r
483 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
\r
484 template<typename BasicJsonType, typename T>
\r
488 template<typename U, typename = decltype(uncvref_t<U>::to_json(
\r
489 std::declval<BasicJsonType&>(), std::declval<T>()))>
\r
490 static int detect(U&&);
\r
491 static void detect(...);
\r
494 static constexpr bool value = std::is_integral<decltype(detect(
\r
495 std::declval<typename BasicJsonType::template json_serializer<T, void> >()))>::value;
\r
503 template<typename BasicJsonType, typename T, enable_if_t<
\r
504 std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
\r
505 void to_json(BasicJsonType& j, T b) noexcept
\r
507 external_constructor<value_t::boolean>::construct(j, b);
\r
510 template<typename BasicJsonType, typename CompatibleString,
\r
511 enable_if_t<std::is_constructible<typename BasicJsonType::string_t,
\r
512 CompatibleString>::value, int> = 0>
\r
513 void to_json(BasicJsonType& j, const CompatibleString& s)
\r
515 external_constructor<value_t::string>::construct(j, s);
\r
518 template<typename BasicJsonType, typename FloatType,
\r
519 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
\r
520 void to_json(BasicJsonType& j, FloatType val) noexcept
\r
522 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
\r
526 typename BasicJsonType, typename CompatibleNumberUnsignedType,
\r
527 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
\r
528 CompatibleNumberUnsignedType>::value, int> = 0 >
\r
529 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
\r
531 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
\r
535 typename BasicJsonType, typename CompatibleNumberIntegerType,
\r
536 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
\r
537 CompatibleNumberIntegerType>::value, int> = 0 >
\r
538 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
\r
540 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
\r
543 template<typename BasicJsonType, typename UnscopedEnumType,
\r
544 enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
\r
545 void to_json(BasicJsonType& j, UnscopedEnumType e) noexcept
\r
547 external_constructor<value_t::number_integer>::construct(j, e);
\r
551 typename BasicJsonType, typename CompatibleArrayType,
\r
553 is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
\r
554 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
\r
556 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
\r
558 external_constructor<value_t::array>::construct(j, arr);
\r
562 typename BasicJsonType, typename CompatibleObjectType,
\r
563 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
\r
565 void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
\r
567 external_constructor<value_t::object>::construct(j, arr);
\r
575 // overloads for basic_json template parameters
\r
576 template<typename BasicJsonType, typename ArithmeticType,
\r
577 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
\r
578 not std::is_same<ArithmeticType,
\r
579 typename BasicJsonType::boolean_t>::value,
\r
581 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
\r
583 switch (static_cast<value_t>(j))
\r
585 case value_t::number_unsigned:
\r
587 val = static_cast<ArithmeticType>(
\r
588 *j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
\r
591 case value_t::number_integer:
\r
593 val = static_cast<ArithmeticType>(
\r
594 *j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
\r
597 case value_t::number_float:
\r
599 val = static_cast<ArithmeticType>(
\r
600 *j.template get_ptr<const typename BasicJsonType::number_float_t*>());
\r
606 std::domain_error("type must be number, but is " + j.type_name()));
\r
611 template<typename BasicJsonType>
\r
612 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
\r
614 if (not j.is_boolean())
\r
616 JSON_THROW(std::domain_error("type must be boolean, but is " + j.type_name()));
\r
618 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
\r
621 template<typename BasicJsonType>
\r
622 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
\r
624 if (not j.is_string())
\r
626 JSON_THROW(std::domain_error("type must be string, but is " + j.type_name()));
\r
628 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
\r
631 template<typename BasicJsonType>
\r
632 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
\r
634 get_arithmetic_value(j, val);
\r
637 template<typename BasicJsonType>
\r
638 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
\r
640 get_arithmetic_value(j, val);
\r
643 template<typename BasicJsonType>
\r
644 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
\r
646 get_arithmetic_value(j, val);
\r
649 template<typename BasicJsonType, typename UnscopedEnumType,
\r
650 enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
\r
651 void from_json(const BasicJsonType& j, UnscopedEnumType& e)
\r
653 typename std::underlying_type<UnscopedEnumType>::type val;
\r
654 get_arithmetic_value(j, val);
\r
655 e = static_cast<UnscopedEnumType>(val);
\r
658 template<typename BasicJsonType>
\r
659 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
\r
661 if (not j.is_array())
\r
663 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
\r
665 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
\r
668 // forward_list doesn't have an insert method
\r
669 template<typename BasicJsonType, typename T, typename Allocator>
\r
670 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
\r
672 // do not perform the check when user wants to retrieve jsons
\r
673 // (except when it's null.. ?)
\r
676 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
\r
678 if (not std::is_same<T, BasicJsonType>::value)
\r
680 if (not j.is_array())
\r
682 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
\r
685 for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
\r
687 l.push_front(it->template get<T>());
\r
691 template<typename BasicJsonType, typename CompatibleArrayType>
\r
692 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>)
\r
697 std::transform(j.begin(), j.end(),
\r
698 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
\r
700 // get<BasicJsonType>() returns *this, this won't call a from_json
\r
701 // method when value_type is BasicJsonType
\r
702 return i.template get<typename CompatibleArrayType::value_type>();
\r
706 template<typename BasicJsonType, typename CompatibleArrayType>
\r
707 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>)
\r
709 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
\r
715 arr.reserve(j.size());
\r
717 j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
\r
719 // get<BasicJsonType>() returns *this, this won't call a from_json
\r
720 // method when value_type is BasicJsonType
\r
721 return i.template get<typename CompatibleArrayType::value_type>();
\r
725 template<typename BasicJsonType, typename CompatibleArrayType,
\r
726 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
\r
727 not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
\r
728 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
\r
732 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
\r
735 // when T == BasicJsonType, do not check if value_t is correct
\r
736 if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
\r
738 if (not j.is_array())
\r
740 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
\r
743 from_json_array_impl(j, arr, priority_tag<1> {});
\r
746 template<typename BasicJsonType, typename CompatibleObjectType,
\r
747 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
\r
748 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
\r
750 if (not j.is_object())
\r
752 JSON_THROW(std::domain_error("type must be object, but is " + j.type_name()));
\r
755 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
\r
758 // we could avoid the assignment, but this might require a for loop, which
\r
759 // might be less efficient than the container constructor for some
\r
760 // containers (would it?)
\r
761 obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
\r
764 // overload for arithmetic types, not chosen for basic_json template arguments
\r
765 // (BooleanType, etc..); note: Is it really necessary to provide explicit
\r
766 // overloads for boolean_t etc. in case of a custom BooleanType which is not
\r
767 // an arithmetic type?
\r
768 template<typename BasicJsonType, typename ArithmeticType,
\r
770 std::is_arithmetic<ArithmeticType>::value and
\r
771 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
\r
772 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
\r
773 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
\r
774 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
\r
776 void from_json(const BasicJsonType& j, ArithmeticType& val)
\r
778 switch (static_cast<value_t>(j))
\r
780 case value_t::number_unsigned:
\r
782 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
\r
785 case value_t::number_integer:
\r
787 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
\r
790 case value_t::number_float:
\r
792 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
\r
795 case value_t::boolean:
\r
797 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
\r
802 JSON_THROW(std::domain_error("type must be number, but is " + j.type_name()));
\r
810 template<typename BasicJsonType, typename T>
\r
811 auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
\r
812 -> decltype(to_json(j, std::forward<T>(val)), void())
\r
814 return to_json(j, std::forward<T>(val));
\r
817 template<typename BasicJsonType, typename T>
\r
818 void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept
\r
820 static_assert(sizeof(BasicJsonType) == 0,
\r
821 "could not find to_json() method in T's namespace");
\r
825 template<typename BasicJsonType, typename T>
\r
826 void operator()(BasicJsonType& j, T&& val) const
\r
827 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
\r
829 return call(j, std::forward<T>(val), priority_tag<1> {});
\r
833 struct from_json_fn
\r
836 template<typename BasicJsonType, typename T>
\r
837 auto call(const BasicJsonType& j, T& val, priority_tag<1>) const
\r
838 noexcept(noexcept(from_json(j, val)))
\r
839 -> decltype(from_json(j, val), void())
\r
841 return from_json(j, val);
\r
844 template<typename BasicJsonType, typename T>
\r
845 void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept
\r
847 static_assert(sizeof(BasicJsonType) == 0,
\r
848 "could not find from_json() method in T's namespace");
\r
852 template<typename BasicJsonType, typename T>
\r
853 void operator()(const BasicJsonType& j, T& val) const
\r
854 noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
\r
856 return call(j, val, priority_tag<1> {});
\r
860 // taken from ranges-v3
\r
861 template<typename T>
\r
862 struct static_const
\r
864 static constexpr T value{};
\r
867 template<typename T>
\r
868 constexpr T static_const<T>::value;
\r
869 } // namespace detail
\r
872 /// namespace to hold default `to_json` / `from_json` functions
\r
875 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
\r
876 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
\r
881 @brief default JSONSerializer template argument
\r
883 This serializer ignores the template arguments and uses ADL
\r
884 ([argument-dependent lookup](http://en.cppreference.com/w/cpp/language/adl))
\r
887 template<typename = void, typename = void>
\r
888 struct adl_serializer
\r
891 @brief convert a JSON value to any value type
\r
893 This function is usually called by the `get()` function of the
\r
894 @ref basic_json class (either explicit or via conversion operators).
\r
896 @param[in] j JSON value to read from
\r
897 @param[in,out] val value to write to
\r
899 template<typename BasicJsonType, typename ValueType>
\r
900 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
\r
901 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
\r
903 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
\r
907 @brief convert any value type to a JSON value
\r
909 This function is usually called by the constructors of the @ref basic_json
\r
912 @param[in,out] j JSON value to write to
\r
913 @param[in] val value to read from
\r
915 template<typename BasicJsonType, typename ValueType>
\r
916 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
\r
917 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
\r
919 ::nlohmann::to_json(j, std::forward<ValueType>(val));
\r
925 @brief a class to store JSON values
\r
927 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
\r
929 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
\r
931 @tparam StringType type for JSON strings and object keys (`std::string` by
\r
932 default; will be used in @ref string_t)
\r
933 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
\r
935 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
\r
936 default; will be used in @ref number_integer_t)
\r
937 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
\r
938 `uint64_t` by default; will be used in @ref number_unsigned_t)
\r
939 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
\r
940 default; will be used in @ref number_float_t)
\r
941 @tparam AllocatorType type of the allocator to use (`std::allocator` by
\r
943 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
\r
944 and `from_json()` (@ref adl_serializer by default)
\r
946 @requirement The class satisfies the following concept requirements:
\r
948 - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
\r
949 JSON values can be default constructed. The result will be a JSON null
\r
951 - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
\r
952 A JSON value can be constructed from an rvalue argument.
\r
953 - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
\r
954 A JSON value can be copy-constructed from an lvalue expression.
\r
955 - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
\r
956 A JSON value van be assigned from an rvalue argument.
\r
957 - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
\r
958 A JSON value can be copy-assigned from an lvalue expression.
\r
959 - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
\r
960 JSON values can be destructed.
\r
962 - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
\r
964 [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
\r
965 All non-static data members are private and standard layout types, the
\r
966 class has no virtual functions or (virtual) base classes.
\r
968 - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
\r
969 JSON values can be compared with `==`, see @ref
\r
970 operator==(const_reference,const_reference).
\r
971 - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
\r
972 JSON values can be compared with `<`, see @ref
\r
973 operator<(const_reference,const_reference).
\r
974 - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
\r
975 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
\r
976 other compatible types, using unqualified function call @ref swap().
\r
977 - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
\r
978 JSON values can be compared against `std::nullptr_t` objects which are used
\r
979 to model the `null` value.
\r
981 - [Container](http://en.cppreference.com/w/cpp/concept/Container):
\r
982 JSON values can be used like STL containers and provide iterator access.
\r
983 - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
\r
984 JSON values can be used like STL containers and provide reverse iterator
\r
987 @invariant The member variables @a m_value and @a m_type have the following
\r
989 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
\r
990 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
\r
991 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
\r
992 The invariants are checked by member function assert_invariant().
\r
995 @note ObjectType trick from http://stackoverflow.com/a/9860911
\r
998 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
\r
999 Format](http://rfc7159.net/rfc7159)
\r
1001 @since version 1.0.0
\r
1006 template<typename U, typename V, typename... Args> class ObjectType = std::map,
\r
1007 template<typename U, typename... Args> class ArrayType = std::vector,
\r
1008 class StringType = std::string,
\r
1009 class BooleanType = bool,
\r
1010 class NumberIntegerType = std::int64_t,
\r
1011 class NumberUnsignedType = std::uint64_t,
\r
1012 class NumberFloatType = double,
\r
1013 template<typename U> class AllocatorType = std::allocator,
\r
1014 template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer
\r
1019 template<detail::value_t> friend struct detail::external_constructor;
\r
1020 /// workaround type for MSVC
\r
1021 using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
\r
1022 BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
\r
1023 AllocatorType, JSONSerializer>;
\r
1026 using value_t = detail::value_t;
\r
1027 // forward declarations
\r
1028 template<typename U> class iter_impl;
\r
1029 template<typename Base> class json_reverse_iterator;
\r
1030 class json_pointer;
\r
1031 template<typename T, typename SFINAE>
\r
1032 using json_serializer = JSONSerializer<T, SFINAE>;
\r
1034 /////////////////////
\r
1035 // container types //
\r
1036 /////////////////////
\r
1038 /// @name container types
\r
1039 /// The canonic container types to use @ref basic_json like any other STL
\r
1043 /// the type of elements in a basic_json container
\r
1044 using value_type = basic_json;
\r
1046 /// the type of an element reference
\r
1047 using reference = value_type&;
\r
1048 /// the type of an element const reference
\r
1049 using const_reference = const value_type&;
\r
1051 /// a type to represent differences between iterators
\r
1052 using difference_type = std::ptrdiff_t;
\r
1053 /// a type to represent container sizes
\r
1054 using size_type = std::size_t;
\r
1056 /// the allocator type
\r
1057 using allocator_type = AllocatorType<basic_json>;
\r
1059 /// the type of an element pointer
\r
1060 using pointer = typename std::allocator_traits<allocator_type>::pointer;
\r
1061 /// the type of an element const pointer
\r
1062 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
\r
1064 /// an iterator for a basic_json container
\r
1065 using iterator = iter_impl<basic_json>;
\r
1066 /// a const iterator for a basic_json container
\r
1067 using const_iterator = iter_impl<const basic_json>;
\r
1068 /// a reverse iterator for a basic_json container
\r
1069 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
\r
1070 /// a const reverse iterator for a basic_json container
\r
1071 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
\r
1077 @brief returns the allocator associated with the container
\r
1079 static allocator_type get_allocator()
\r
1081 return allocator_type();
\r
1085 @brief returns version information on the library
\r
1087 This function returns a JSON object with information about the library,
\r
1088 including the version number and information on the platform and compiler.
\r
1090 @return JSON object holding version information
\r
1092 ----------- | ---------------
\r
1093 `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).
\r
1094 `copyright` | The copyright line for the library as string.
\r
1095 `name` | The name of the library as string.
\r
1096 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
\r
1097 `url` | The URL of the project as string.
\r
1098 `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).
\r
1100 @liveexample{The following code shows an example output of the `meta()`
\r
1103 @complexity Constant.
\r
1107 static basic_json meta()
\r
1109 basic_json result;
\r
1111 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
\r
1112 result["name"] = "JSON for Modern C++";
\r
1113 result["url"] = "https://github.com/nlohmann/json";
\r
1114 result["version"] =
\r
1116 {"string", "2.1.1"},
\r
1123 result["platform"] = "win32";
\r
1124 #elif defined __linux__
\r
1125 result["platform"] = "linux";
\r
1126 #elif defined __APPLE__
\r
1127 result["platform"] = "apple";
\r
1128 #elif defined __unix__
\r
1129 result["platform"] = "unix";
\r
1131 result["platform"] = "unknown";
\r
1134 #if defined(__clang__)
\r
1135 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
\r
1136 #elif defined(__ICC) || defined(__INTEL_COMPILER)
\r
1137 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
\r
1138 #elif defined(__GNUC__) || defined(__GNUG__)
\r
1139 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
\r
1140 #elif defined(__HP_cc) || defined(__HP_aCC)
\r
1141 result["compiler"] = "hp"
\r
1142 #elif defined(__IBMCPP__)
\r
1143 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
\r
1144 #elif defined(_MSC_VER)
\r
1145 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
\r
1146 #elif defined(__PGI)
\r
1147 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
\r
1148 #elif defined(__SUNPRO_CC)
\r
1149 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
\r
1151 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
\r
1154 #ifdef __cplusplus
\r
1155 result["compiler"]["c++"] = std::to_string(__cplusplus);
\r
1157 result["compiler"]["c++"] = "unknown";
\r
1163 ///////////////////////////
\r
1164 // JSON value data types //
\r
1165 ///////////////////////////
\r
1167 /// @name JSON value data types
\r
1168 /// The data types to store a JSON value. These types are derived from
\r
1169 /// the template arguments passed to class @ref basic_json.
\r
1173 @brief a type for an object
\r
1175 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
\r
1176 > An object is an unordered collection of zero or more name/value pairs,
\r
1177 > where a name is a string and a value is a string, number, boolean, null,
\r
1178 > object, or array.
\r
1180 To store objects in C++, a type is defined by the template parameters
\r
1183 @tparam ObjectType the container to store objects (e.g., `std::map` or
\r
1184 `std::unordered_map`)
\r
1185 @tparam StringType the type of the keys or names (e.g., `std::string`).
\r
1186 The comparison function `std::less<StringType>` is used to order elements
\r
1187 inside the container.
\r
1188 @tparam AllocatorType the allocator to use for objects (e.g.,
\r
1193 With the default values for @a ObjectType (`std::map`), @a StringType
\r
1194 (`std::string`), and @a AllocatorType (`std::allocator`), the default
\r
1195 value for @a object_t is:
\r
1199 std::string, // key_type
\r
1200 basic_json, // value_type
\r
1201 std::less<std::string>, // key_compare
\r
1202 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
\r
1208 The choice of @a object_t influences the behavior of the JSON class. With
\r
1209 the default type, objects have the following behavior:
\r
1211 - When all names are unique, objects will be interoperable in the sense
\r
1212 that all software implementations receiving that object will agree on
\r
1213 the name-value mappings.
\r
1214 - When the names within an object are not unique, later stored name/value
\r
1215 pairs overwrite previously stored name/value pairs, leaving the used
\r
1216 names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will
\r
1217 be treated as equal and both stored as `{"key": 1}`.
\r
1218 - Internally, name/value pairs are stored in lexicographical order of the
\r
1219 names. Objects will also be serialized (see @ref dump) in this order.
\r
1220 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
\r
1221 and serialized as `{"a": 2, "b": 1}`.
\r
1222 - When comparing objects, the order of the name/value pairs is irrelevant.
\r
1223 This makes objects interoperable in the sense that they will not be
\r
1224 affected by these differences. For instance, `{"b": 1, "a": 2}` and
\r
1225 `{"a": 2, "b": 1}` will be treated as equal.
\r
1229 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
\r
1230 > An implementation may set limits on the maximum depth of nesting.
\r
1232 In this class, the object's limit of nesting is not constraint explicitly.
\r
1233 However, a maximum depth of nesting may be introduced by the compiler or
\r
1234 runtime environment. A theoretical limit can be queried by calling the
\r
1235 @ref max_size function of a JSON object.
\r
1239 Objects are stored as pointers in a @ref basic_json type. That is, for any
\r
1240 access to object values, a pointer of type `object_t*` must be
\r
1243 @sa @ref array_t -- type for an array value
\r
1245 @since version 1.0.0
\r
1247 @note The order name/value pairs are added to the object is *not*
\r
1248 preserved by the library. Therefore, iterating an object may return
\r
1249 name/value pairs in a different order than they were originally stored. In
\r
1250 fact, keys will be traversed in alphabetical order as `std::map` with
\r
1251 `std::less` is used by default. Please note this behavior conforms to [RFC
\r
1252 7159](http://rfc7159.net/rfc7159), because any order implements the
\r
1253 specified "unordered" nature of JSON objects.
\r
1255 using object_t = ObjectType<StringType,
\r
1257 std::less<StringType>,
\r
1258 AllocatorType<std::pair<const StringType,
\r
1262 @brief a type for an array
\r
1264 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
\r
1265 > An array is an ordered sequence of zero or more values.
\r
1267 To store objects in C++, a type is defined by the template parameters
\r
1270 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
\r
1272 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
\r
1276 With the default values for @a ArrayType (`std::vector`) and @a
\r
1277 AllocatorType (`std::allocator`), the default value for @a array_t is:
\r
1281 basic_json, // value_type
\r
1282 std::allocator<basic_json> // allocator_type
\r
1288 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
\r
1289 > An implementation may set limits on the maximum depth of nesting.
\r
1291 In this class, the array's limit of nesting is not constraint explicitly.
\r
1292 However, a maximum depth of nesting may be introduced by the compiler or
\r
1293 runtime environment. A theoretical limit can be queried by calling the
\r
1294 @ref max_size function of a JSON array.
\r
1298 Arrays are stored as pointers in a @ref basic_json type. That is, for any
\r
1299 access to array values, a pointer of type `array_t*` must be dereferenced.
\r
1301 @sa @ref object_t -- type for an object value
\r
1303 @since version 1.0.0
\r
1305 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
\r
1308 @brief a type for a string
\r
1310 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
\r
1311 > A string is a sequence of zero or more Unicode characters.
\r
1313 To store objects in C++, a type is defined by the template parameter
\r
1314 described below. Unicode values are split by the JSON class into
\r
1315 byte-sized characters during deserialization.
\r
1317 @tparam StringType the container to store strings (e.g., `std::string`).
\r
1318 Note this container is used for keys/names in objects, see @ref object_t.
\r
1322 With the default values for @a StringType (`std::string`), the default
\r
1323 value for @a string_t is:
\r
1331 Strings are stored in UTF-8 encoding. Therefore, functions like
\r
1332 `std::string::size()` or `std::string::length()` return the number of
\r
1333 bytes in the string rather than the number of characters or glyphs.
\r
1335 #### String comparison
\r
1337 [RFC 7159](http://rfc7159.net/rfc7159) states:
\r
1338 > Software implementations are typically required to test names of object
\r
1339 > members for equality. Implementations that transform the textual
\r
1340 > representation into sequences of Unicode code units and then perform the
\r
1341 > comparison numerically, code unit by code unit, are interoperable in the
\r
1342 > sense that implementations will agree in all cases on equality or
\r
1343 > inequality of two strings. For example, implementations that compare
\r
1344 > strings with escaped characters unconverted may incorrectly find that
\r
1345 > `"a\\b"` and `"a\u005Cb"` are not equal.
\r
1347 This implementation is interoperable as it does compare strings code unit
\r
1352 String values are stored as pointers in a @ref basic_json type. That is,
\r
1353 for any access to string values, a pointer of type `string_t*` must be
\r
1356 @since version 1.0.0
\r
1358 using string_t = StringType;
\r
1361 @brief a type for a boolean
\r
1363 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
\r
1364 type which differentiates the two literals `true` and `false`.
\r
1366 To store objects in C++, a type is defined by the template parameter @a
\r
1367 BooleanType which chooses the type to use.
\r
1371 With the default values for @a BooleanType (`bool`), the default value for
\r
1380 Boolean values are stored directly inside a @ref basic_json type.
\r
1382 @since version 1.0.0
\r
1384 using boolean_t = BooleanType;
\r
1387 @brief a type for a number (integer)
\r
1389 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
\r
1390 > The representation of numbers is similar to that used in most
\r
1391 > programming languages. A number is represented in base 10 using decimal
\r
1392 > digits. It contains an integer component that may be prefixed with an
\r
1393 > optional minus sign, which may be followed by a fraction part and/or an
\r
1394 > exponent part. Leading zeros are not allowed. (...) Numeric values that
\r
1395 > cannot be represented in the grammar below (such as Infinity and NaN)
\r
1396 > are not permitted.
\r
1398 This description includes both integer and floating-point numbers.
\r
1399 However, C++ allows more precise storage if it is known whether the number
\r
1400 is a signed integer, an unsigned integer or a floating-point number.
\r
1401 Therefore, three different types, @ref number_integer_t, @ref
\r
1402 number_unsigned_t and @ref number_float_t are used.
\r
1404 To store integer numbers in C++, a type is defined by the template
\r
1405 parameter @a NumberIntegerType which chooses the type to use.
\r
1409 With the default values for @a NumberIntegerType (`int64_t`), the default
\r
1410 value for @a number_integer_t is:
\r
1416 #### Default behavior
\r
1418 - The restrictions about leading zeros is not enforced in C++. Instead,
\r
1419 leading zeros in integer literals lead to an interpretation as octal
\r
1420 number. Internally, the value will be stored as decimal number. For
\r
1421 instance, the C++ integer literal `010` will be serialized to `8`.
\r
1422 During deserialization, leading zeros yield an error.
\r
1423 - Not-a-number (NaN) values will be serialized to `null`.
\r
1427 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
\r
1428 > An implementation may set limits on the range and precision of numbers.
\r
1430 When the default type is used, the maximal integer number that can be
\r
1431 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
\r
1432 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
\r
1433 that are out of range will yield over/underflow when used in a
\r
1434 constructor. During deserialization, too large or small integer numbers
\r
1435 will be automatically be stored as @ref number_unsigned_t or @ref
\r
1438 [RFC 7159](http://rfc7159.net/rfc7159) further states:
\r
1439 > Note that when such software is used, numbers that are integers and are
\r
1440 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
\r
1441 > that implementations will agree exactly on their numeric values.
\r
1443 As this range is a subrange of the exactly supported range [INT64_MIN,
\r
1444 INT64_MAX], this class's integer type is interoperable.
\r
1448 Integer number values are stored directly inside a @ref basic_json type.
\r
1450 @sa @ref number_float_t -- type for number values (floating-point)
\r
1452 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
\r
1454 @since version 1.0.0
\r
1456 using number_integer_t = NumberIntegerType;
\r
1459 @brief a type for a number (unsigned)
\r
1461 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
\r
1462 > The representation of numbers is similar to that used in most
\r
1463 > programming languages. A number is represented in base 10 using decimal
\r
1464 > digits. It contains an integer component that may be prefixed with an
\r
1465 > optional minus sign, which may be followed by a fraction part and/or an
\r
1466 > exponent part. Leading zeros are not allowed. (...) Numeric values that
\r
1467 > cannot be represented in the grammar below (such as Infinity and NaN)
\r
1468 > are not permitted.
\r
1470 This description includes both integer and floating-point numbers.
\r
1471 However, C++ allows more precise storage if it is known whether the number
\r
1472 is a signed integer, an unsigned integer or a floating-point number.
\r
1473 Therefore, three different types, @ref number_integer_t, @ref
\r
1474 number_unsigned_t and @ref number_float_t are used.
\r
1476 To store unsigned integer numbers in C++, a type is defined by the
\r
1477 template parameter @a NumberUnsignedType which chooses the type to use.
\r
1481 With the default values for @a NumberUnsignedType (`uint64_t`), the
\r
1482 default value for @a number_unsigned_t is:
\r
1488 #### Default behavior
\r
1490 - The restrictions about leading zeros is not enforced in C++. Instead,
\r
1491 leading zeros in integer literals lead to an interpretation as octal
\r
1492 number. Internally, the value will be stored as decimal number. For
\r
1493 instance, the C++ integer literal `010` will be serialized to `8`.
\r
1494 During deserialization, leading zeros yield an error.
\r
1495 - Not-a-number (NaN) values will be serialized to `null`.
\r
1499 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
\r
1500 > An implementation may set limits on the range and precision of numbers.
\r
1502 When the default type is used, the maximal integer number that can be
\r
1503 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
\r
1504 number that can be stored is `0`. Integer numbers that are out of range
\r
1505 will yield over/underflow when used in a constructor. During
\r
1506 deserialization, too large or small integer numbers will be automatically
\r
1507 be stored as @ref number_integer_t or @ref number_float_t.
\r
1509 [RFC 7159](http://rfc7159.net/rfc7159) further states:
\r
1510 > Note that when such software is used, numbers that are integers and are
\r
1511 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
\r
1512 > that implementations will agree exactly on their numeric values.
\r
1514 As this range is a subrange (when considered in conjunction with the
\r
1515 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
\r
1516 this class's integer type is interoperable.
\r
1520 Integer number values are stored directly inside a @ref basic_json type.
\r
1522 @sa @ref number_float_t -- type for number values (floating-point)
\r
1523 @sa @ref number_integer_t -- type for number values (integer)
\r
1525 @since version 2.0.0
\r
1527 using number_unsigned_t = NumberUnsignedType;
\r
1530 @brief a type for a number (floating-point)
\r
1532 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
\r
1533 > The representation of numbers is similar to that used in most
\r
1534 > programming languages. A number is represented in base 10 using decimal
\r
1535 > digits. It contains an integer component that may be prefixed with an
\r
1536 > optional minus sign, which may be followed by a fraction part and/or an
\r
1537 > exponent part. Leading zeros are not allowed. (...) Numeric values that
\r
1538 > cannot be represented in the grammar below (such as Infinity and NaN)
\r
1539 > are not permitted.
\r
1541 This description includes both integer and floating-point numbers.
\r
1542 However, C++ allows more precise storage if it is known whether the number
\r
1543 is a signed integer, an unsigned integer or a floating-point number.
\r
1544 Therefore, three different types, @ref number_integer_t, @ref
\r
1545 number_unsigned_t and @ref number_float_t are used.
\r
1547 To store floating-point numbers in C++, a type is defined by the template
\r
1548 parameter @a NumberFloatType which chooses the type to use.
\r
1552 With the default values for @a NumberFloatType (`double`), the default
\r
1553 value for @a number_float_t is:
\r
1559 #### Default behavior
\r
1561 - The restrictions about leading zeros is not enforced in C++. Instead,
\r
1562 leading zeros in floating-point literals will be ignored. Internally,
\r
1563 the value will be stored as decimal number. For instance, the C++
\r
1564 floating-point literal `01.2` will be serialized to `1.2`. During
\r
1565 deserialization, leading zeros yield an error.
\r
1566 - Not-a-number (NaN) values will be serialized to `null`.
\r
1570 [RFC 7159](http://rfc7159.net/rfc7159) states:
\r
1571 > This specification allows implementations to set limits on the range and
\r
1572 > precision of numbers accepted. Since software that implements IEEE
\r
1573 > 754-2008 binary64 (double precision) numbers is generally available and
\r
1574 > widely used, good interoperability can be achieved by implementations
\r
1575 > that expect no more precision or range than these provide, in the sense
\r
1576 > that implementations will approximate JSON numbers within the expected
\r
1579 This implementation does exactly follow this approach, as it uses double
\r
1580 precision floating-point numbers. Note values smaller than
\r
1581 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
\r
1582 will be stored as NaN internally and be serialized to `null`.
\r
1586 Floating-point number values are stored directly inside a @ref basic_json
\r
1589 @sa @ref number_integer_t -- type for number values (integer)
\r
1591 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
\r
1593 @since version 1.0.0
\r
1595 using number_float_t = NumberFloatType;
\r
1601 /// helper for exception-safe object creation
\r
1602 template<typename T, typename... Args>
\r
1603 static T* create(Args&& ... args)
\r
1605 AllocatorType<T> alloc;
\r
1606 auto deleter = [&](T * object)
\r
1608 alloc.deallocate(object, 1);
\r
1610 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
\r
1611 alloc.construct(object.get(), std::forward<Args>(args)...);
\r
1612 assert(object != nullptr);
\r
1613 return object.release();
\r
1616 ////////////////////////
\r
1617 // JSON value storage //
\r
1618 ////////////////////////
\r
1621 @brief a JSON value
\r
1623 The actual storage for a JSON value of the @ref basic_json class. This
\r
1624 union combines the different storage types for the JSON value types
\r
1625 defined in @ref value_t.
\r
1627 JSON type | value_t type | used type
\r
1628 --------- | --------------- | ------------------------
\r
1629 object | object | pointer to @ref object_t
\r
1630 array | array | pointer to @ref array_t
\r
1631 string | string | pointer to @ref string_t
\r
1632 boolean | boolean | @ref boolean_t
\r
1633 number | number_integer | @ref number_integer_t
\r
1634 number | number_unsigned | @ref number_unsigned_t
\r
1635 number | number_float | @ref number_float_t
\r
1636 null | null | *no value is stored*
\r
1638 @note Variable-length types (objects, arrays, and strings) are stored as
\r
1639 pointers. The size of the union should not exceed 64 bits if the default
\r
1640 value types are used.
\r
1642 @since version 1.0.0
\r
1646 /// object (stored with pointer to save storage)
\r
1648 /// array (stored with pointer to save storage)
\r
1650 /// string (stored with pointer to save storage)
\r
1653 boolean_t boolean;
\r
1654 /// number (integer)
\r
1655 number_integer_t number_integer;
\r
1656 /// number (unsigned integer)
\r
1657 number_unsigned_t number_unsigned;
\r
1658 /// number (floating-point)
\r
1659 number_float_t number_float;
\r
1661 /// default constructor (for null values)
\r
1662 json_value() = default;
\r
1663 /// constructor for booleans
\r
1664 json_value(boolean_t v) noexcept : boolean(v) {}
\r
1665 /// constructor for numbers (integer)
\r
1666 json_value(number_integer_t v) noexcept : number_integer(v) {}
\r
1667 /// constructor for numbers (unsigned)
\r
1668 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
\r
1669 /// constructor for numbers (floating-point)
\r
1670 json_value(number_float_t v) noexcept : number_float(v) {}
\r
1671 /// constructor for empty values of a given type
\r
1672 json_value(value_t t)
\r
1676 case value_t::object:
\r
1678 object = create<object_t>();
\r
1682 case value_t::array:
\r
1684 array = create<array_t>();
\r
1688 case value_t::string:
\r
1690 string = create<string_t>("");
\r
1694 case value_t::boolean:
\r
1696 boolean = boolean_t(false);
\r
1700 case value_t::number_integer:
\r
1702 number_integer = number_integer_t(0);
\r
1706 case value_t::number_unsigned:
\r
1708 number_unsigned = number_unsigned_t(0);
\r
1712 case value_t::number_float:
\r
1714 number_float = number_float_t(0.0);
\r
1718 case value_t::null:
\r
1725 if (t == value_t::null)
\r
1727 JSON_THROW(std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
\r
1734 /// constructor for strings
\r
1735 json_value(const string_t& value)
\r
1737 string = create<string_t>(value);
\r
1740 /// constructor for objects
\r
1741 json_value(const object_t& value)
\r
1743 object = create<object_t>(value);
\r
1746 /// constructor for arrays
\r
1747 json_value(const array_t& value)
\r
1749 array = create<array_t>(value);
\r
1754 @brief checks the class invariants
\r
1756 This function asserts the class invariants. It needs to be called at the
\r
1757 end of every constructor to make sure that created objects respect the
\r
1758 invariant. Furthermore, it has to be called each time the type of a JSON
\r
1759 value is changed, because the invariant expresses a relationship between
\r
1760 @a m_type and @a m_value.
\r
1762 void assert_invariant() const
\r
1764 assert(m_type != value_t::object or m_value.object != nullptr);
\r
1765 assert(m_type != value_t::array or m_value.array != nullptr);
\r
1766 assert(m_type != value_t::string or m_value.string != nullptr);
\r
1770 //////////////////////////
\r
1771 // JSON parser callback //
\r
1772 //////////////////////////
\r
1775 @brief JSON callback events
\r
1777 This enumeration lists the parser events that can trigger calling a
\r
1778 callback function of type @ref parser_callback_t during parsing.
\r
1780 @image html callback_events.png "Example when certain parse events are triggered"
\r
1782 @since version 1.0.0
\r
1784 enum class parse_event_t : uint8_t
\r
1786 /// the parser read `{` and started to process a JSON object
\r
1788 /// the parser read `}` and finished processing a JSON object
\r
1790 /// the parser read `[` and started to process a JSON array
\r
1792 /// the parser read `]` and finished processing a JSON array
\r
1794 /// the parser read a key of a value in an object
\r
1796 /// the parser finished reading a JSON value
\r
1801 @brief per-element parser callback type
\r
1803 With a parser callback function, the result of parsing a JSON text can be
\r
1804 influenced. When passed to @ref parse(std::istream&, const
\r
1805 parser_callback_t) or @ref parse(const CharT, const parser_callback_t),
\r
1806 it is called on certain events (passed as @ref parse_event_t via parameter
\r
1807 @a event) with a set recursion depth @a depth and context JSON value
\r
1808 @a parsed. The return value of the callback function is a boolean
\r
1809 indicating whether the element that emitted the callback shall be kept or
\r
1812 We distinguish six scenarios (determined by the event type) in which the
\r
1813 callback function can be called. The following table describes the values
\r
1814 of the parameters @a depth, @a event, and @a parsed.
\r
1816 parameter @a event | description | parameter @a depth | parameter @a parsed
\r
1817 ------------------ | ----------- | ------------------ | -------------------
\r
1818 parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
\r
1819 parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
\r
1820 parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
\r
1821 parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
\r
1822 parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
\r
1823 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
\r
1825 @image html callback_events.png "Example when certain parse events are triggered"
\r
1827 Discarding a value (i.e., returning `false`) has different effects
\r
1828 depending on the context in which function was called:
\r
1830 - Discarded values in structured types are skipped. That is, the parser
\r
1831 will behave as if the discarded value was never read.
\r
1832 - In case a value outside a structured type is skipped, it is replaced
\r
1833 with `null`. This case happens if the top-level element is skipped.
\r
1835 @param[in] depth the depth of the recursion during parsing
\r
1837 @param[in] event an event of type parse_event_t indicating the context in
\r
1838 the callback function has been called
\r
1840 @param[in,out] parsed the current intermediate parse result; note that
\r
1841 writing to this value has no effect for parse_event_t::key events
\r
1843 @return Whether the JSON value which called the function during parsing
\r
1844 should be kept (`true`) or not (`false`). In the latter case, it is either
\r
1845 skipped completely or replaced by an empty discarded object.
\r
1847 @sa @ref parse(std::istream&, parser_callback_t) or
\r
1848 @ref parse(const CharT, const parser_callback_t) for examples
\r
1850 @since version 1.0.0
\r
1852 using parser_callback_t = std::function<bool(int depth,
\r
1853 parse_event_t event,
\r
1854 basic_json& parsed)>;
\r
1857 //////////////////
\r
1858 // constructors //
\r
1859 //////////////////
\r
1861 /// @name constructors and destructors
\r
1862 /// Constructors of class @ref basic_json, copy/move constructor, copy
\r
1863 /// assignment, static functions creating objects, and the destructor.
\r
1867 @brief create an empty value with a given type
\r
1869 Create an empty JSON value with a given type. The value will be default
\r
1870 initialized with an empty value which depends on the type:
\r
1872 Value type | initial value
\r
1873 ----------- | -------------
\r
1881 @param[in] value_type the type of the value to create
\r
1883 @complexity Constant.
\r
1885 @throw std::bad_alloc if allocation for object, array, or string value
\r
1888 @liveexample{The following code shows the constructor for different @ref
\r
1889 value_t values,basic_json__value_t}
\r
1891 @since version 1.0.0
\r
1893 basic_json(const value_t value_type)
\r
1894 : m_type(value_type), m_value(value_type)
\r
1896 assert_invariant();
\r
1900 @brief create a null object
\r
1902 Create a `null` JSON value. It either takes a null pointer as parameter
\r
1903 (explicitly creating `null`) or no parameter (implicitly creating `null`).
\r
1904 The passed null pointer itself is not read -- it is only used to choose
\r
1905 the right constructor.
\r
1907 @complexity Constant.
\r
1909 @exceptionsafety No-throw guarantee: this constructor never throws
\r
1912 @liveexample{The following code shows the constructor with and without a
\r
1913 null pointer parameter.,basic_json__nullptr_t}
\r
1915 @since version 1.0.0
\r
1917 basic_json(std::nullptr_t = nullptr) noexcept
\r
1918 : basic_json(value_t::null)
\r
1920 assert_invariant();
\r
1924 @brief create a JSON value
\r
1926 This is a "catch all" constructor for all compatible JSON types; that is,
\r
1927 types for which a `to_json()` method exsits. The constructor forwards the
\r
1928 parameter @a val to that method (to `json_serializer<U>::to_json` method
\r
1929 with `U = uncvref_t<CompatibleType>`, to be exact).
\r
1931 Template type @a CompatibleType includes, but is not limited to, the
\r
1933 - **arrays**: @ref array_t and all kinds of compatible containers such as
\r
1934 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
\r
1935 `std::array`, `std::set`, `std::unordered_set`, `std::multiset`, and
\r
1936 `unordered_multiset` with a `value_type` from which a @ref basic_json
\r
1937 value can be constructed.
\r
1938 - **objects**: @ref object_t and all kinds of compatible associative
\r
1939 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
\r
1940 and `std::unordered_multimap` with a `key_type` compatible to
\r
1941 @ref string_t and a `value_type` from which a @ref basic_json value can
\r
1943 - **strings**: @ref string_t, string literals, and all compatible string
\r
1944 containers can be used.
\r
1945 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
\r
1946 @ref number_float_t, and all convertible number types such as `int`,
\r
1947 `size_t`, `int64_t`, `float` or `double` can be used.
\r
1948 - **boolean**: @ref boolean_t / `bool` can be used.
\r
1950 See the examples below.
\r
1952 @tparam CompatibleType a type such that:
\r
1953 - @a CompatibleType is not derived from `std::istream`,
\r
1954 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
\r
1956 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
\r
1957 @ref json_pointer, @ref iterator, etc ...)
\r
1958 - @ref @ref json_serializer<U> has a
\r
1959 `to_json(basic_json_t&, CompatibleType&&)` method
\r
1961 @tparam U = `uncvref_t<CompatibleType>`
\r
1963 @param[in] val the value to be forwarded
\r
1965 @complexity Usually linear in the size of the passed @a val, also
\r
1966 depending on the implementation of the called `to_json()`
\r
1969 @throw what `json_serializer<U>::to_json()` throws
\r
1971 @liveexample{The following code shows the constructor with several
\r
1972 compatible types.,basic_json__CompatibleType}
\r
1974 @since version 2.1.0
\r
1976 template<typename CompatibleType, typename U = detail::uncvref_t<CompatibleType>,
\r
1977 detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
\r
1978 not std::is_same<U, basic_json_t>::value and
\r
1979 not detail::is_basic_json_nested_type<
\r
1980 basic_json_t, U>::value and
\r
1981 detail::has_to_json<basic_json, U>::value,
\r
1983 basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
\r
1984 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
\r
1986 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
\r
1987 assert_invariant();
\r
1991 @brief create a container (array or object) from an initializer list
\r
1993 Creates a JSON value of type array or object from the passed initializer
\r
1994 list @a init. In case @a type_deduction is `true` (default), the type of
\r
1995 the JSON value to be created is deducted from the initializer list @a init
\r
1996 according to the following rules:
\r
1998 1. If the list is empty, an empty JSON object value `{}` is created.
\r
1999 2. If the list consists of pairs whose first element is a string, a JSON
\r
2000 object value is created where the first elements of the pairs are
\r
2001 treated as keys and the second elements are as values.
\r
2002 3. In all other cases, an array is created.
\r
2004 The rules aim to create the best fit between a C++ initializer list and
\r
2005 JSON values. The rationale is as follows:
\r
2007 1. The empty initializer list is written as `{}` which is exactly an empty
\r
2009 2. C++ has now way of describing mapped types other than to list a list of
\r
2010 pairs. As JSON requires that keys must be of type string, rule 2 is the
\r
2011 weakest constraint one can pose on initializer lists to interpret them
\r
2013 3. In all other cases, the initializer list could not be interpreted as
\r
2014 JSON object type, so interpreting it as JSON array type is safe.
\r
2016 With the rules described above, the following JSON values cannot be
\r
2017 expressed by an initializer list:
\r
2019 - the empty array (`[]`): use @ref array(std::initializer_list<basic_json>)
\r
2020 with an empty initializer list in this case
\r
2021 - arrays whose elements satisfy rule 2: use @ref
\r
2022 array(std::initializer_list<basic_json>) with the same initializer list
\r
2025 @note When used without parentheses around an empty initializer list, @ref
\r
2026 basic_json() is called instead of this function, yielding the JSON null
\r
2029 @param[in] init initializer list with JSON values
\r
2031 @param[in] type_deduction internal parameter; when set to `true`, the type
\r
2032 of the JSON value is deducted from the initializer list @a init; when set
\r
2033 to `false`, the type provided via @a manual_type is forced. This mode is
\r
2034 used by the functions @ref array(std::initializer_list<basic_json>) and
\r
2035 @ref object(std::initializer_list<basic_json>).
\r
2037 @param[in] manual_type internal parameter; when @a type_deduction is set
\r
2038 to `false`, the created JSON value will use the provided type (only @ref
\r
2039 value_t::array and @ref value_t::object are valid); when @a type_deduction
\r
2040 is set to `true`, this parameter has no effect
\r
2042 @throw std::domain_error if @a type_deduction is `false`, @a manual_type
\r
2043 is `value_t::object`, but @a init contains an element which is not a pair
\r
2044 whose first element is a string; example: `"cannot create object from
\r
2045 initializer list"`
\r
2047 @complexity Linear in the size of the initializer list @a init.
\r
2049 @liveexample{The example below shows how JSON values are created from
\r
2050 initializer lists.,basic_json__list_init_t}
\r
2052 @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
\r
2053 value from an initializer list
\r
2054 @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
\r
2055 value from an initializer list
\r
2057 @since version 1.0.0
\r
2059 basic_json(std::initializer_list<basic_json> init,
\r
2060 bool type_deduction = true,
\r
2061 value_t manual_type = value_t::array)
\r
2063 // check if each element is an array with two elements whose first
\r
2064 // element is a string
\r
2065 bool is_an_object = std::all_of(init.begin(), init.end(),
\r
2066 [](const basic_json & element)
\r
2068 return element.is_array() and element.size() == 2 and element[0].is_string();
\r
2071 // adjust type if type deduction is not wanted
\r
2072 if (not type_deduction)
\r
2074 // if array is wanted, do not create an object though possible
\r
2075 if (manual_type == value_t::array)
\r
2077 is_an_object = false;
\r
2080 // if object is wanted but impossible, throw an exception
\r
2081 if (manual_type == value_t::object and not is_an_object)
\r
2083 JSON_THROW(std::domain_error("cannot create object from initializer list"));
\r
2089 // the initializer list is a list of pairs -> create object
\r
2090 m_type = value_t::object;
\r
2091 m_value = value_t::object;
\r
2093 std::for_each(init.begin(), init.end(), [this](const basic_json & element)
\r
2095 m_value.object->emplace(*(element[0].m_value.string), element[1]);
\r
2100 // the initializer list describes an array -> create array
\r
2101 m_type = value_t::array;
\r
2102 m_value.array = create<array_t>(init);
\r
2105 assert_invariant();
\r
2109 @brief explicitly create an array from an initializer list
\r
2111 Creates a JSON array value from a given initializer list. That is, given a
\r
2112 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
\r
2113 initializer list is empty, the empty array `[]` is created.
\r
2115 @note This function is only needed to express two edge cases that cannot
\r
2116 be realized with the initializer list constructor (@ref
\r
2117 basic_json(std::initializer_list<basic_json>, bool, value_t)). These cases
\r
2119 1. creating an array whose elements are all pairs whose first element is a
\r
2120 string -- in this case, the initializer list constructor would create an
\r
2121 object, taking the first elements as keys
\r
2122 2. creating an empty array -- passing the empty initializer list to the
\r
2123 initializer list constructor yields an empty object
\r
2125 @param[in] init initializer list with JSON values to create an array from
\r
2128 @return JSON array value
\r
2130 @complexity Linear in the size of @a init.
\r
2132 @liveexample{The following code shows an example for the `array`
\r
2135 @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
\r
2136 create a JSON value from an initializer list
\r
2137 @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
\r
2138 value from an initializer list
\r
2140 @since version 1.0.0
\r
2142 static basic_json array(std::initializer_list<basic_json> init =
\r
2143 std::initializer_list<basic_json>())
\r
2145 return basic_json(init, false, value_t::array);
\r
2149 @brief explicitly create an object from an initializer list
\r
2151 Creates a JSON object value from a given initializer list. The initializer
\r
2152 lists elements must be pairs, and their first elements must be strings. If
\r
2153 the initializer list is empty, the empty object `{}` is created.
\r
2155 @note This function is only added for symmetry reasons. In contrast to the
\r
2156 related function @ref array(std::initializer_list<basic_json>), there are
\r
2157 no cases which can only be expressed by this function. That is, any
\r
2158 initializer list @a init can also be passed to the initializer list
\r
2159 constructor @ref basic_json(std::initializer_list<basic_json>, bool,
\r
2162 @param[in] init initializer list to create an object from (optional)
\r
2164 @return JSON object value
\r
2166 @throw std::domain_error if @a init is not a pair whose first elements are
\r
2167 strings; thrown by
\r
2168 @ref basic_json(std::initializer_list<basic_json>, bool, value_t)
\r
2170 @complexity Linear in the size of @a init.
\r
2172 @liveexample{The following code shows an example for the `object`
\r
2175 @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
\r
2176 create a JSON value from an initializer list
\r
2177 @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
\r
2178 value from an initializer list
\r
2180 @since version 1.0.0
\r
2182 static basic_json object(std::initializer_list<basic_json> init =
\r
2183 std::initializer_list<basic_json>())
\r
2185 return basic_json(init, false, value_t::object);
\r
2189 @brief construct an array with count copies of given value
\r
2191 Constructs a JSON array value by creating @a cnt copies of a passed value.
\r
2192 In case @a cnt is `0`, an empty array is created. As postcondition,
\r
2193 `std::distance(begin(),end()) == cnt` holds.
\r
2195 @param[in] cnt the number of JSON copies of @a val to create
\r
2196 @param[in] val the JSON value to copy
\r
2198 @complexity Linear in @a cnt.
\r
2200 @liveexample{The following code shows examples for the @ref
\r
2201 basic_json(size_type\, const basic_json&)
\r
2202 constructor.,basic_json__size_type_basic_json}
\r
2204 @since version 1.0.0
\r
2206 basic_json(size_type cnt, const basic_json& val)
\r
2207 : m_type(value_t::array)
\r
2209 m_value.array = create<array_t>(cnt, val);
\r
2210 assert_invariant();
\r
2214 @brief construct a JSON container given an iterator range
\r
2216 Constructs the JSON value with the contents of the range `[first, last)`.
\r
2217 The semantics depends on the different types a JSON value can have:
\r
2218 - In case of primitive types (number, boolean, or string), @a first must
\r
2219 be `begin()` and @a last must be `end()`. In this case, the value is
\r
2220 copied. Otherwise, std::out_of_range is thrown.
\r
2221 - In case of structured types (array, object), the constructor behaves as
\r
2222 similar versions for `std::vector`.
\r
2223 - In case of a null type, std::domain_error is thrown.
\r
2225 @tparam InputIT an input iterator type (@ref iterator or @ref
\r
2228 @param[in] first begin of the range to copy from (included)
\r
2229 @param[in] last end of the range to copy from (excluded)
\r
2231 @pre Iterators @a first and @a last must be initialized. **This
\r
2232 precondition is enforced with an assertion.**
\r
2234 @throw std::domain_error if iterators are not compatible; that is, do not
\r
2235 belong to the same JSON value; example: `"iterators are not compatible"`
\r
2236 @throw std::out_of_range if iterators are for a primitive type (number,
\r
2237 boolean, or string) where an out of range error can be detected easily;
\r
2238 example: `"iterators out of range"`
\r
2239 @throw std::bad_alloc if allocation for object, array, or string fails
\r
2240 @throw std::domain_error if called with a null value; example: `"cannot
\r
2241 use construct with iterators from null"`
\r
2243 @complexity Linear in distance between @a first and @a last.
\r
2245 @liveexample{The example below shows several ways to create JSON values by
\r
2246 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
\r
2248 @since version 1.0.0
\r
2250 template<class InputIT, typename std::enable_if<
\r
2251 std::is_same<InputIT, typename basic_json_t::iterator>::value or
\r
2252 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
\r
2253 basic_json(InputIT first, InputIT last)
\r
2255 assert(first.m_object != nullptr);
\r
2256 assert(last.m_object != nullptr);
\r
2258 // make sure iterator fits the current value
\r
2259 if (first.m_object != last.m_object)
\r
2261 JSON_THROW(std::domain_error("iterators are not compatible"));
\r
2264 // copy type from first iterator
\r
2265 m_type = first.m_object->m_type;
\r
2267 // check if iterator range is complete for primitive values
\r
2270 case value_t::boolean:
\r
2271 case value_t::number_float:
\r
2272 case value_t::number_integer:
\r
2273 case value_t::number_unsigned:
\r
2274 case value_t::string:
\r
2276 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
\r
2278 JSON_THROW(std::out_of_range("iterators out of range"));
\r
2291 case value_t::number_integer:
\r
2293 m_value.number_integer = first.m_object->m_value.number_integer;
\r
2297 case value_t::number_unsigned:
\r
2299 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
\r
2303 case value_t::number_float:
\r
2305 m_value.number_float = first.m_object->m_value.number_float;
\r
2309 case value_t::boolean:
\r
2311 m_value.boolean = first.m_object->m_value.boolean;
\r
2315 case value_t::string:
\r
2317 m_value = *first.m_object->m_value.string;
\r
2321 case value_t::object:
\r
2323 m_value.object = create<object_t>(first.m_it.object_iterator,
\r
2324 last.m_it.object_iterator);
\r
2328 case value_t::array:
\r
2330 m_value.array = create<array_t>(first.m_it.array_iterator,
\r
2331 last.m_it.array_iterator);
\r
2337 JSON_THROW(std::domain_error("cannot use construct with iterators from " + first.m_object->type_name()));
\r
2341 assert_invariant();
\r
2345 @brief construct a JSON value given an input stream
\r
2347 @param[in,out] i stream to read a serialized JSON value from
\r
2348 @param[in] cb a parser callback function of type @ref parser_callback_t
\r
2349 which is used to control the deserialization by filtering unwanted values
\r
2352 @complexity Linear in the length of the input. The parser is a predictive
\r
2353 LL(1) parser. The complexity can be higher if the parser callback function
\r
2354 @a cb has a super-linear complexity.
\r
2356 @note A UTF-8 byte order mark is silently ignored.
\r
2358 @deprecated This constructor is deprecated and will be removed in version
\r
2359 3.0.0 to unify the interface of the library. Deserialization will be
\r
2360 done by stream operators or by calling one of the `parse` functions,
\r
2361 e.g. @ref parse(std::istream&, const parser_callback_t). That is, calls
\r
2362 like `json j(i);` for an input stream @a i need to be replaced by
\r
2363 `json j = json::parse(i);`. See the example below.
\r
2365 @liveexample{The example below demonstrates constructing a JSON value from
\r
2366 a `std::stringstream` with and without callback
\r
2367 function.,basic_json__istream}
\r
2369 @since version 2.0.0, deprecated in version 2.0.3, to be removed in
\r
2373 explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
\r
2375 *this = parser(i, cb).parse();
\r
2376 assert_invariant();
\r
2379 ///////////////////////////////////////
\r
2380 // other constructors and destructor //
\r
2381 ///////////////////////////////////////
\r
2384 @brief copy constructor
\r
2386 Creates a copy of a given JSON value.
\r
2388 @param[in] other the JSON value to copy
\r
2390 @complexity Linear in the size of @a other.
\r
2392 @requirement This function helps `basic_json` satisfying the
\r
2393 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
2395 - The complexity is linear.
\r
2396 - As postcondition, it holds: `other == basic_json(other)`.
\r
2398 @throw std::bad_alloc if allocation for object, array, or string fails.
\r
2400 @liveexample{The following code shows an example for the copy
\r
2401 constructor.,basic_json__basic_json}
\r
2403 @since version 1.0.0
\r
2405 basic_json(const basic_json& other)
\r
2406 : m_type(other.m_type)
\r
2408 // check of passed value is valid
\r
2409 other.assert_invariant();
\r
2413 case value_t::object:
\r
2415 m_value = *other.m_value.object;
\r
2419 case value_t::array:
\r
2421 m_value = *other.m_value.array;
\r
2425 case value_t::string:
\r
2427 m_value = *other.m_value.string;
\r
2431 case value_t::boolean:
\r
2433 m_value = other.m_value.boolean;
\r
2437 case value_t::number_integer:
\r
2439 m_value = other.m_value.number_integer;
\r
2443 case value_t::number_unsigned:
\r
2445 m_value = other.m_value.number_unsigned;
\r
2449 case value_t::number_float:
\r
2451 m_value = other.m_value.number_float;
\r
2461 assert_invariant();
\r
2465 @brief move constructor
\r
2467 Move constructor. Constructs a JSON value with the contents of the given
\r
2468 value @a other using move semantics. It "steals" the resources from @a
\r
2469 other and leaves it as JSON null value.
\r
2471 @param[in,out] other value to move to this object
\r
2473 @post @a other is a JSON null value
\r
2475 @complexity Constant.
\r
2477 @liveexample{The code below shows the move constructor explicitly called
\r
2478 via std::move.,basic_json__moveconstructor}
\r
2480 @since version 1.0.0
\r
2482 basic_json(basic_json&& other) noexcept
\r
2483 : m_type(std::move(other.m_type)),
\r
2484 m_value(std::move(other.m_value))
\r
2486 // check that passed value is valid
\r
2487 other.assert_invariant();
\r
2489 // invalidate payload
\r
2490 other.m_type = value_t::null;
\r
2491 other.m_value = {};
\r
2493 assert_invariant();
\r
2497 @brief copy assignment
\r
2499 Copy assignment operator. Copies a JSON value via the "copy and swap"
\r
2500 strategy: It is expressed in terms of the copy constructor, destructor,
\r
2501 and the swap() member function.
\r
2503 @param[in] other value to copy from
\r
2505 @complexity Linear.
\r
2507 @requirement This function helps `basic_json` satisfying the
\r
2508 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
2510 - The complexity is linear.
\r
2512 @liveexample{The code below shows and example for the copy assignment. It
\r
2513 creates a copy of value `a` which is then swapped with `b`. Finally\, the
\r
2514 copy of `a` (which is the null value after the swap) is
\r
2515 destroyed.,basic_json__copyassignment}
\r
2517 @since version 1.0.0
\r
2519 reference& operator=(basic_json other) noexcept (
\r
2520 std::is_nothrow_move_constructible<value_t>::value and
\r
2521 std::is_nothrow_move_assignable<value_t>::value and
\r
2522 std::is_nothrow_move_constructible<json_value>::value and
\r
2523 std::is_nothrow_move_assignable<json_value>::value
\r
2526 // check that passed value is valid
\r
2527 other.assert_invariant();
\r
2530 swap(m_type, other.m_type);
\r
2531 swap(m_value, other.m_value);
\r
2533 assert_invariant();
\r
2540 Destroys the JSON value and frees all allocated memory.
\r
2542 @complexity Linear.
\r
2544 @requirement This function helps `basic_json` satisfying the
\r
2545 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
2547 - The complexity is linear.
\r
2548 - All stored elements are destroyed and all memory is freed.
\r
2550 @since version 1.0.0
\r
2554 assert_invariant();
\r
2558 case value_t::object:
\r
2560 AllocatorType<object_t> alloc;
\r
2561 alloc.destroy(m_value.object);
\r
2562 alloc.deallocate(m_value.object, 1);
\r
2566 case value_t::array:
\r
2568 AllocatorType<array_t> alloc;
\r
2569 alloc.destroy(m_value.array);
\r
2570 alloc.deallocate(m_value.array, 1);
\r
2574 case value_t::string:
\r
2576 AllocatorType<string_t> alloc;
\r
2577 alloc.destroy(m_value.string);
\r
2578 alloc.deallocate(m_value.string, 1);
\r
2584 // all other types need no specific destructor
\r
2593 ///////////////////////
\r
2594 // object inspection //
\r
2595 ///////////////////////
\r
2597 /// @name object inspection
\r
2598 /// Functions to inspect the type of a JSON value.
\r
2602 @brief serialization
\r
2604 Serialization function for JSON values. The function tries to mimic
\r
2605 Python's `json.dumps()` function, and currently supports its @a indent
\r
2608 @param[in] indent If indent is nonnegative, then array elements and object
\r
2609 members will be pretty-printed with that indent level. An indent level of
\r
2610 `0` will only insert newlines. `-1` (the default) selects the most compact
\r
2613 @return string containing the serialization of the JSON value
\r
2615 @complexity Linear.
\r
2617 @liveexample{The following example shows the effect of different @a indent
\r
2618 parameters to the result of the serialization.,dump}
\r
2620 @see https://docs.python.org/2/library/json.html#json.dump
\r
2622 @since version 1.0.0
\r
2624 string_t dump(const int indent = -1) const
\r
2626 std::stringstream ss;
\r
2630 dump(ss, true, static_cast<unsigned int>(indent));
\r
2634 dump(ss, false, 0);
\r
2641 @brief return the type of the JSON value (explicit)
\r
2643 Return the type of the JSON value as a value from the @ref value_t
\r
2646 @return the type of the JSON value
\r
2648 @complexity Constant.
\r
2650 @exceptionsafety No-throw guarantee: this member function never throws
\r
2653 @liveexample{The following code exemplifies `type()` for all JSON
\r
2656 @since version 1.0.0
\r
2658 constexpr value_t type() const noexcept
\r
2664 @brief return whether type is primitive
\r
2666 This function returns true iff the JSON type is primitive (string, number,
\r
2667 boolean, or null).
\r
2669 @return `true` if type is primitive (string, number, boolean, or null),
\r
2670 `false` otherwise.
\r
2672 @complexity Constant.
\r
2674 @exceptionsafety No-throw guarantee: this member function never throws
\r
2677 @liveexample{The following code exemplifies `is_primitive()` for all JSON
\r
2678 types.,is_primitive}
\r
2680 @sa @ref is_structured() -- returns whether JSON value is structured
\r
2681 @sa @ref is_null() -- returns whether JSON value is `null`
\r
2682 @sa @ref is_string() -- returns whether JSON value is a string
\r
2683 @sa @ref is_boolean() -- returns whether JSON value is a boolean
\r
2684 @sa @ref is_number() -- returns whether JSON value is a number
\r
2686 @since version 1.0.0
\r
2688 constexpr bool is_primitive() const noexcept
\r
2690 return is_null() or is_string() or is_boolean() or is_number();
\r
2694 @brief return whether type is structured
\r
2696 This function returns true iff the JSON type is structured (array or
\r
2699 @return `true` if type is structured (array or object), `false` otherwise.
\r
2701 @complexity Constant.
\r
2703 @exceptionsafety No-throw guarantee: this member function never throws
\r
2706 @liveexample{The following code exemplifies `is_structured()` for all JSON
\r
2707 types.,is_structured}
\r
2709 @sa @ref is_primitive() -- returns whether value is primitive
\r
2710 @sa @ref is_array() -- returns whether value is an array
\r
2711 @sa @ref is_object() -- returns whether value is an object
\r
2713 @since version 1.0.0
\r
2715 constexpr bool is_structured() const noexcept
\r
2717 return is_array() or is_object();
\r
2721 @brief return whether value is null
\r
2723 This function returns true iff the JSON value is null.
\r
2725 @return `true` if type is null, `false` otherwise.
\r
2727 @complexity Constant.
\r
2729 @exceptionsafety No-throw guarantee: this member function never throws
\r
2732 @liveexample{The following code exemplifies `is_null()` for all JSON
\r
2735 @since version 1.0.0
\r
2737 constexpr bool is_null() const noexcept
\r
2739 return m_type == value_t::null;
\r
2743 @brief return whether value is a boolean
\r
2745 This function returns true iff the JSON value is a boolean.
\r
2747 @return `true` if type is boolean, `false` otherwise.
\r
2749 @complexity Constant.
\r
2751 @exceptionsafety No-throw guarantee: this member function never throws
\r
2754 @liveexample{The following code exemplifies `is_boolean()` for all JSON
\r
2755 types.,is_boolean}
\r
2757 @since version 1.0.0
\r
2759 constexpr bool is_boolean() const noexcept
\r
2761 return m_type == value_t::boolean;
\r
2765 @brief return whether value is a number
\r
2767 This function returns true iff the JSON value is a number. This includes
\r
2768 both integer and floating-point values.
\r
2770 @return `true` if type is number (regardless whether integer, unsigned
\r
2771 integer or floating-type), `false` otherwise.
\r
2773 @complexity Constant.
\r
2775 @exceptionsafety No-throw guarantee: this member function never throws
\r
2778 @liveexample{The following code exemplifies `is_number()` for all JSON
\r
2781 @sa @ref is_number_integer() -- check if value is an integer or unsigned
\r
2783 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
\r
2785 @sa @ref is_number_float() -- check if value is a floating-point number
\r
2787 @since version 1.0.0
\r
2789 constexpr bool is_number() const noexcept
\r
2791 return is_number_integer() or is_number_float();
\r
2795 @brief return whether value is an integer number
\r
2797 This function returns true iff the JSON value is an integer or unsigned
\r
2798 integer number. This excludes floating-point values.
\r
2800 @return `true` if type is an integer or unsigned integer number, `false`
\r
2803 @complexity Constant.
\r
2805 @exceptionsafety No-throw guarantee: this member function never throws
\r
2808 @liveexample{The following code exemplifies `is_number_integer()` for all
\r
2809 JSON types.,is_number_integer}
\r
2811 @sa @ref is_number() -- check if value is a number
\r
2812 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
\r
2814 @sa @ref is_number_float() -- check if value is a floating-point number
\r
2816 @since version 1.0.0
\r
2818 constexpr bool is_number_integer() const noexcept
\r
2820 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
\r
2824 @brief return whether value is an unsigned integer number
\r
2826 This function returns true iff the JSON value is an unsigned integer
\r
2827 number. This excludes floating-point and (signed) integer values.
\r
2829 @return `true` if type is an unsigned integer number, `false` otherwise.
\r
2831 @complexity Constant.
\r
2833 @exceptionsafety No-throw guarantee: this member function never throws
\r
2836 @liveexample{The following code exemplifies `is_number_unsigned()` for all
\r
2837 JSON types.,is_number_unsigned}
\r
2839 @sa @ref is_number() -- check if value is a number
\r
2840 @sa @ref is_number_integer() -- check if value is an integer or unsigned
\r
2842 @sa @ref is_number_float() -- check if value is a floating-point number
\r
2844 @since version 2.0.0
\r
2846 constexpr bool is_number_unsigned() const noexcept
\r
2848 return m_type == value_t::number_unsigned;
\r
2852 @brief return whether value is a floating-point number
\r
2854 This function returns true iff the JSON value is a floating-point number.
\r
2855 This excludes integer and unsigned integer values.
\r
2857 @return `true` if type is a floating-point number, `false` otherwise.
\r
2859 @complexity Constant.
\r
2861 @exceptionsafety No-throw guarantee: this member function never throws
\r
2864 @liveexample{The following code exemplifies `is_number_float()` for all
\r
2865 JSON types.,is_number_float}
\r
2867 @sa @ref is_number() -- check if value is number
\r
2868 @sa @ref is_number_integer() -- check if value is an integer number
\r
2869 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
\r
2872 @since version 1.0.0
\r
2874 constexpr bool is_number_float() const noexcept
\r
2876 return m_type == value_t::number_float;
\r
2880 @brief return whether value is an object
\r
2882 This function returns true iff the JSON value is an object.
\r
2884 @return `true` if type is object, `false` otherwise.
\r
2886 @complexity Constant.
\r
2888 @exceptionsafety No-throw guarantee: this member function never throws
\r
2891 @liveexample{The following code exemplifies `is_object()` for all JSON
\r
2894 @since version 1.0.0
\r
2896 constexpr bool is_object() const noexcept
\r
2898 return m_type == value_t::object;
\r
2902 @brief return whether value is an array
\r
2904 This function returns true iff the JSON value is an array.
\r
2906 @return `true` if type is array, `false` otherwise.
\r
2908 @complexity Constant.
\r
2910 @exceptionsafety No-throw guarantee: this member function never throws
\r
2913 @liveexample{The following code exemplifies `is_array()` for all JSON
\r
2916 @since version 1.0.0
\r
2918 constexpr bool is_array() const noexcept
\r
2920 return m_type == value_t::array;
\r
2924 @brief return whether value is a string
\r
2926 This function returns true iff the JSON value is a string.
\r
2928 @return `true` if type is string, `false` otherwise.
\r
2930 @complexity Constant.
\r
2932 @exceptionsafety No-throw guarantee: this member function never throws
\r
2935 @liveexample{The following code exemplifies `is_string()` for all JSON
\r
2938 @since version 1.0.0
\r
2940 constexpr bool is_string() const noexcept
\r
2942 return m_type == value_t::string;
\r
2946 @brief return whether value is discarded
\r
2948 This function returns true iff the JSON value was discarded during parsing
\r
2949 with a callback function (see @ref parser_callback_t).
\r
2951 @note This function will always be `false` for JSON values after parsing.
\r
2952 That is, discarded values can only occur during parsing, but will be
\r
2953 removed when inside a structured value or replaced by null in other cases.
\r
2955 @return `true` if type is discarded, `false` otherwise.
\r
2957 @complexity Constant.
\r
2959 @exceptionsafety No-throw guarantee: this member function never throws
\r
2962 @liveexample{The following code exemplifies `is_discarded()` for all JSON
\r
2963 types.,is_discarded}
\r
2965 @since version 1.0.0
\r
2967 constexpr bool is_discarded() const noexcept
\r
2969 return m_type == value_t::discarded;
\r
2973 @brief return the type of the JSON value (implicit)
\r
2975 Implicitly return the type of the JSON value as a value from the @ref
\r
2976 value_t enumeration.
\r
2978 @return the type of the JSON value
\r
2980 @complexity Constant.
\r
2982 @exceptionsafety No-throw guarantee: this member function never throws
\r
2985 @liveexample{The following code exemplifies the @ref value_t operator for
\r
2986 all JSON types.,operator__value_t}
\r
2988 @since version 1.0.0
\r
2990 constexpr operator value_t() const noexcept
\r
2998 //////////////////
\r
2999 // value access //
\r
3000 //////////////////
\r
3002 /// get a boolean (explicit)
\r
3003 boolean_t get_impl(boolean_t* /*unused*/) const
\r
3007 return m_value.boolean;
\r
3010 JSON_THROW(std::domain_error("type must be boolean, but is " + type_name()));
\r
3013 /// get a pointer to the value (object)
\r
3014 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
\r
3016 return is_object() ? m_value.object : nullptr;
\r
3019 /// get a pointer to the value (object)
\r
3020 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
\r
3022 return is_object() ? m_value.object : nullptr;
\r
3025 /// get a pointer to the value (array)
\r
3026 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
\r
3028 return is_array() ? m_value.array : nullptr;
\r
3031 /// get a pointer to the value (array)
\r
3032 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
\r
3034 return is_array() ? m_value.array : nullptr;
\r
3037 /// get a pointer to the value (string)
\r
3038 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
\r
3040 return is_string() ? m_value.string : nullptr;
\r
3043 /// get a pointer to the value (string)
\r
3044 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
\r
3046 return is_string() ? m_value.string : nullptr;
\r
3049 /// get a pointer to the value (boolean)
\r
3050 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
\r
3052 return is_boolean() ? &m_value.boolean : nullptr;
\r
3055 /// get a pointer to the value (boolean)
\r
3056 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
\r
3058 return is_boolean() ? &m_value.boolean : nullptr;
\r
3061 /// get a pointer to the value (integer number)
\r
3062 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
\r
3064 return is_number_integer() ? &m_value.number_integer : nullptr;
\r
3067 /// get a pointer to the value (integer number)
\r
3068 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
\r
3070 return is_number_integer() ? &m_value.number_integer : nullptr;
\r
3073 /// get a pointer to the value (unsigned number)
\r
3074 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
\r
3076 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
\r
3079 /// get a pointer to the value (unsigned number)
\r
3080 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
\r
3082 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
\r
3085 /// get a pointer to the value (floating-point number)
\r
3086 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
\r
3088 return is_number_float() ? &m_value.number_float : nullptr;
\r
3091 /// get a pointer to the value (floating-point number)
\r
3092 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
\r
3094 return is_number_float() ? &m_value.number_float : nullptr;
\r
3098 @brief helper function to implement get_ref()
\r
3100 This funcion helps to implement get_ref() without code duplication for
\r
3101 const and non-const overloads
\r
3103 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
\r
3105 @throw std::domain_error if ReferenceType does not match underlying value
\r
3106 type of the current JSON
\r
3108 template<typename ReferenceType, typename ThisType>
\r
3109 static ReferenceType get_ref_impl(ThisType& obj)
\r
3112 using PointerType = typename std::add_pointer<ReferenceType>::type;
\r
3114 // delegate the call to get_ptr<>()
\r
3115 auto ptr = obj.template get_ptr<PointerType>();
\r
3117 if (ptr != nullptr)
\r
3122 JSON_THROW(std::domain_error("incompatible ReferenceType for get_ref, actual type is " +
\r
3123 obj.type_name()));
\r
3127 /// @name value access
\r
3128 /// Direct access to the stored value of a JSON value.
\r
3132 @brief get special-case overload
\r
3134 This overloads avoids a lot of template boilerplate, it can be seen as the
\r
3137 @tparam BasicJsonType == @ref basic_json
\r
3139 @return a copy of *this
\r
3141 @complexity Constant.
\r
3143 @since version 2.1.0
\r
3146 typename BasicJsonType,
\r
3147 detail::enable_if_t<std::is_same<typename std::remove_const<BasicJsonType>::type,
\r
3148 basic_json_t>::value,
\r
3150 basic_json get() const
\r
3156 @brief get a value (explicit)
\r
3158 Explicit type conversion between the JSON value and a compatible value
\r
3159 which is [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
\r
3160 and [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
\r
3161 The value is converted by calling the @ref json_serializer<ValueType>
\r
3162 `from_json()` method.
\r
3164 The function is equivalent to executing
\r
3167 JSONSerializer<ValueType>::from_json(*this, ret);
\r
3171 This overloads is chosen if:
\r
3172 - @a ValueType is not @ref basic_json,
\r
3173 - @ref json_serializer<ValueType> has a `from_json()` method of the form
\r
3174 `void from_json(const @ref basic_json&, ValueType&)`, and
\r
3175 - @ref json_serializer<ValueType> does not have a `from_json()` method of
\r
3176 the form `ValueType from_json(const @ref basic_json&)`
\r
3178 @tparam ValueTypeCV the provided value type
\r
3179 @tparam ValueType the returned value type
\r
3181 @return copy of the JSON value, converted to @a ValueType
\r
3183 @throw what @ref json_serializer<ValueType> `from_json()` method throws
\r
3185 @liveexample{The example below shows several conversions from JSON values
\r
3186 to other types. There a few things to note: (1) Floating-point numbers can
\r
3187 be converted to integers\, (2) A JSON array can be converted to a standard
\r
3188 `std::vector<short>`\, (3) A JSON object can be converted to C++
\r
3189 associative containers such as `std::unordered_map<std::string\,
\r
3190 json>`.,get__ValueType_const}
\r
3192 @since version 2.1.0
\r
3195 typename ValueTypeCV,
\r
3196 typename ValueType = detail::uncvref_t<ValueTypeCV>,
\r
3197 detail::enable_if_t <
\r
3198 not std::is_same<basic_json_t, ValueType>::value and
\r
3199 detail::has_from_json<basic_json_t, ValueType>::value and
\r
3200 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
\r
3202 ValueType get() const noexcept(noexcept(
\r
3203 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
\r
3205 // we cannot static_assert on ValueTypeCV being non-const, because
\r
3206 // there is support for get<const basic_json_t>(), which is why we
\r
3207 // still need the uncvref
\r
3208 static_assert(not std::is_reference<ValueTypeCV>::value,
\r
3209 "get() cannot be used with reference types, you might want to use get_ref()");
\r
3210 static_assert(std::is_default_constructible<ValueType>::value,
\r
3211 "types must be DefaultConstructible when used with get()");
\r
3214 JSONSerializer<ValueType>::from_json(*this, ret);
\r
3219 @brief get a value (explicit); special case
\r
3221 Explicit type conversion between the JSON value and a compatible value
\r
3222 which is **not** [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
\r
3223 and **not** [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
\r
3224 The value is converted by calling the @ref json_serializer<ValueType>
\r
3225 `from_json()` method.
\r
3227 The function is equivalent to executing
\r
3229 return JSONSerializer<ValueTypeCV>::from_json(*this);
\r
3232 This overloads is chosen if:
\r
3233 - @a ValueType is not @ref basic_json and
\r
3234 - @ref json_serializer<ValueType> has a `from_json()` method of the form
\r
3235 `ValueType from_json(const @ref basic_json&)`
\r
3237 @note If @ref json_serializer<ValueType> has both overloads of
\r
3238 `from_json()`, this one is chosen.
\r
3240 @tparam ValueTypeCV the provided value type
\r
3241 @tparam ValueType the returned value type
\r
3243 @return copy of the JSON value, converted to @a ValueType
\r
3245 @throw what @ref json_serializer<ValueType> `from_json()` method throws
\r
3247 @since version 2.1.0
\r
3250 typename ValueTypeCV,
\r
3251 typename ValueType = detail::uncvref_t<ValueTypeCV>,
\r
3252 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
\r
3253 detail::has_non_default_from_json<basic_json_t,
\r
3254 ValueType>::value, int> = 0 >
\r
3255 ValueType get() const noexcept(noexcept(
\r
3256 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
\r
3258 static_assert(not std::is_reference<ValueTypeCV>::value,
\r
3259 "get() cannot be used with reference types, you might want to use get_ref()");
\r
3260 return JSONSerializer<ValueTypeCV>::from_json(*this);
\r
3264 @brief get a pointer value (explicit)
\r
3266 Explicit pointer access to the internally stored JSON value. No copies are
\r
3269 @warning The pointer becomes invalid if the underlying JSON object
\r
3272 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
\r
3273 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
\r
3274 @ref number_unsigned_t, or @ref number_float_t.
\r
3276 @return pointer to the internally stored JSON value if the requested
\r
3277 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
\r
3279 @complexity Constant.
\r
3281 @liveexample{The example below shows how pointers to internal values of a
\r
3282 JSON value can be requested. Note that no type conversions are made and a
\r
3283 `nullptr` is returned if the value and the requested pointer type does not
\r
3284 match.,get__PointerType}
\r
3286 @sa @ref get_ptr() for explicit pointer-member access
\r
3288 @since version 1.0.0
\r
3290 template<typename PointerType, typename std::enable_if<
\r
3291 std::is_pointer<PointerType>::value, int>::type = 0>
\r
3292 PointerType get() noexcept
\r
3294 // delegate the call to get_ptr
\r
3295 return get_ptr<PointerType>();
\r
3299 @brief get a pointer value (explicit)
\r
3302 template<typename PointerType, typename std::enable_if<
\r
3303 std::is_pointer<PointerType>::value, int>::type = 0>
\r
3304 constexpr const PointerType get() const noexcept
\r
3306 // delegate the call to get_ptr
\r
3307 return get_ptr<PointerType>();
\r
3311 @brief get a pointer value (implicit)
\r
3313 Implicit pointer access to the internally stored JSON value. No copies are
\r
3316 @warning Writing data to the pointee of the result yields an undefined
\r
3319 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
\r
3320 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
\r
3321 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
\r
3324 @return pointer to the internally stored JSON value if the requested
\r
3325 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
\r
3327 @complexity Constant.
\r
3329 @liveexample{The example below shows how pointers to internal values of a
\r
3330 JSON value can be requested. Note that no type conversions are made and a
\r
3331 `nullptr` is returned if the value and the requested pointer type does not
\r
3334 @since version 1.0.0
\r
3336 template<typename PointerType, typename std::enable_if<
\r
3337 std::is_pointer<PointerType>::value, int>::type = 0>
\r
3338 PointerType get_ptr() noexcept
\r
3340 // get the type of the PointerType (remove pointer and const)
\r
3341 using pointee_t = typename std::remove_const<typename
\r
3342 std::remove_pointer<typename
\r
3343 std::remove_const<PointerType>::type>::type>::type;
\r
3344 // make sure the type matches the allowed types
\r
3346 std::is_same<object_t, pointee_t>::value
\r
3347 or std::is_same<array_t, pointee_t>::value
\r
3348 or std::is_same<string_t, pointee_t>::value
\r
3349 or std::is_same<boolean_t, pointee_t>::value
\r
3350 or std::is_same<number_integer_t, pointee_t>::value
\r
3351 or std::is_same<number_unsigned_t, pointee_t>::value
\r
3352 or std::is_same<number_float_t, pointee_t>::value
\r
3353 , "incompatible pointer type");
\r
3355 // delegate the call to get_impl_ptr<>()
\r
3356 return get_impl_ptr(static_cast<PointerType>(nullptr));
\r
3360 @brief get a pointer value (implicit)
\r
3361 @copydoc get_ptr()
\r
3363 template<typename PointerType, typename std::enable_if<
\r
3364 std::is_pointer<PointerType>::value and
\r
3365 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
\r
3366 constexpr const PointerType get_ptr() const noexcept
\r
3368 // get the type of the PointerType (remove pointer and const)
\r
3369 using pointee_t = typename std::remove_const<typename
\r
3370 std::remove_pointer<typename
\r
3371 std::remove_const<PointerType>::type>::type>::type;
\r
3372 // make sure the type matches the allowed types
\r
3374 std::is_same<object_t, pointee_t>::value
\r
3375 or std::is_same<array_t, pointee_t>::value
\r
3376 or std::is_same<string_t, pointee_t>::value
\r
3377 or std::is_same<boolean_t, pointee_t>::value
\r
3378 or std::is_same<number_integer_t, pointee_t>::value
\r
3379 or std::is_same<number_unsigned_t, pointee_t>::value
\r
3380 or std::is_same<number_float_t, pointee_t>::value
\r
3381 , "incompatible pointer type");
\r
3383 // delegate the call to get_impl_ptr<>() const
\r
3384 return get_impl_ptr(static_cast<const PointerType>(nullptr));
\r
3388 @brief get a reference value (implicit)
\r
3390 Implicit reference access to the internally stored JSON value. No copies
\r
3393 @warning Writing data to the referee of the result yields an undefined
\r
3396 @tparam ReferenceType reference type; must be a reference to @ref array_t,
\r
3397 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
\r
3398 @ref number_float_t. Enforced by static assertion.
\r
3400 @return reference to the internally stored JSON value if the requested
\r
3401 reference type @a ReferenceType fits to the JSON value; throws
\r
3402 std::domain_error otherwise
\r
3404 @throw std::domain_error in case passed type @a ReferenceType is
\r
3405 incompatible with the stored JSON value
\r
3407 @complexity Constant.
\r
3409 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
\r
3411 @since version 1.1.0
\r
3413 template<typename ReferenceType, typename std::enable_if<
\r
3414 std::is_reference<ReferenceType>::value, int>::type = 0>
\r
3415 ReferenceType get_ref()
\r
3417 // delegate call to get_ref_impl
\r
3418 return get_ref_impl<ReferenceType>(*this);
\r
3422 @brief get a reference value (implicit)
\r
3423 @copydoc get_ref()
\r
3425 template<typename ReferenceType, typename std::enable_if<
\r
3426 std::is_reference<ReferenceType>::value and
\r
3427 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
\r
3428 ReferenceType get_ref() const
\r
3430 // delegate call to get_ref_impl
\r
3431 return get_ref_impl<ReferenceType>(*this);
\r
3435 @brief get a value (implicit)
\r
3437 Implicit type conversion between the JSON value and a compatible value.
\r
3438 The call is realized by calling @ref get() const.
\r
3440 @tparam ValueType non-pointer type compatible to the JSON value, for
\r
3441 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
\r
3442 `std::vector` types for JSON arrays. The character type of @ref string_t
\r
3443 as well as an initializer list of this type is excluded to avoid
\r
3444 ambiguities as these types implicitly convert to `std::string`.
\r
3446 @return copy of the JSON value, converted to type @a ValueType
\r
3448 @throw std::domain_error in case passed type @a ValueType is incompatible
\r
3449 to JSON, thrown by @ref get() const
\r
3451 @complexity Linear in the size of the JSON value.
\r
3453 @liveexample{The example below shows several conversions from JSON values
\r
3454 to other types. There a few things to note: (1) Floating-point numbers can
\r
3455 be converted to integers\, (2) A JSON array can be converted to a standard
\r
3456 `std::vector<short>`\, (3) A JSON object can be converted to C++
\r
3457 associative containers such as `std::unordered_map<std::string\,
\r
3458 json>`.,operator__ValueType}
\r
3460 @since version 1.0.0
\r
3462 template < typename ValueType, typename std::enable_if <
\r
3463 not std::is_pointer<ValueType>::value and
\r
3464 not std::is_same<ValueType, typename string_t::value_type>::value
\r
3465 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
\r
3466 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
\r
3468 , int >::type = 0 >
\r
3469 operator ValueType() const
\r
3471 // delegate the call to get<>() const
\r
3472 return get<ValueType>();
\r
3478 ////////////////////
\r
3479 // element access //
\r
3480 ////////////////////
\r
3482 /// @name element access
\r
3483 /// Access to the JSON value.
\r
3487 @brief access specified array element with bounds checking
\r
3489 Returns a reference to the element at specified location @a idx, with
\r
3492 @param[in] idx index of the element to access
\r
3494 @return reference to the element at index @a idx
\r
3496 @throw std::domain_error if the JSON value is not an array; example:
\r
3497 `"cannot use at() with string"`
\r
3498 @throw std::out_of_range if the index @a idx is out of range of the array;
\r
3499 that is, `idx >= size()`; example: `"array index 7 is out of range"`
\r
3501 @complexity Constant.
\r
3503 @liveexample{The example below shows how array elements can be read and
\r
3504 written using `at()`.,at__size_type}
\r
3506 @since version 1.0.0
\r
3508 reference at(size_type idx)
\r
3510 // at only works for arrays
\r
3515 return m_value.array->at(idx);
\r
3517 JSON_CATCH (std::out_of_range&)
\r
3519 // create better exception explanation
\r
3520 JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
\r
3525 JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
\r
3530 @brief access specified array element with bounds checking
\r
3532 Returns a const reference to the element at specified location @a idx,
\r
3533 with bounds checking.
\r
3535 @param[in] idx index of the element to access
\r
3537 @return const reference to the element at index @a idx
\r
3539 @throw std::domain_error if the JSON value is not an array; example:
\r
3540 `"cannot use at() with string"`
\r
3541 @throw std::out_of_range if the index @a idx is out of range of the array;
\r
3542 that is, `idx >= size()`; example: `"array index 7 is out of range"`
\r
3544 @complexity Constant.
\r
3546 @liveexample{The example below shows how array elements can be read using
\r
3547 `at()`.,at__size_type_const}
\r
3549 @since version 1.0.0
\r
3551 const_reference at(size_type idx) const
\r
3553 // at only works for arrays
\r
3558 return m_value.array->at(idx);
\r
3560 JSON_CATCH (std::out_of_range&)
\r
3562 // create better exception explanation
\r
3563 JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
\r
3568 JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
\r
3573 @brief access specified object element with bounds checking
\r
3575 Returns a reference to the element at with specified key @a key, with
\r
3578 @param[in] key key of the element to access
\r
3580 @return reference to the element at key @a key
\r
3582 @throw std::domain_error if the JSON value is not an object; example:
\r
3583 `"cannot use at() with boolean"`
\r
3584 @throw std::out_of_range if the key @a key is is not stored in the object;
\r
3585 that is, `find(key) == end()`; example: `"key "the fast" not found"`
\r
3587 @complexity Logarithmic in the size of the container.
\r
3589 @liveexample{The example below shows how object elements can be read and
\r
3590 written using `at()`.,at__object_t_key_type}
\r
3592 @sa @ref operator[](const typename object_t::key_type&) for unchecked
\r
3593 access by reference
\r
3594 @sa @ref value() for access by value with a default value
\r
3596 @since version 1.0.0
\r
3598 reference at(const typename object_t::key_type& key)
\r
3600 // at only works for objects
\r
3605 return m_value.object->at(key);
\r
3607 JSON_CATCH (std::out_of_range&)
\r
3609 // create better exception explanation
\r
3610 JSON_THROW(std::out_of_range("key '" + key + "' not found"));
\r
3615 JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
\r
3620 @brief access specified object element with bounds checking
\r
3622 Returns a const reference to the element at with specified key @a key,
\r
3623 with bounds checking.
\r
3625 @param[in] key key of the element to access
\r
3627 @return const reference to the element at key @a key
\r
3629 @throw std::domain_error if the JSON value is not an object; example:
\r
3630 `"cannot use at() with boolean"`
\r
3631 @throw std::out_of_range if the key @a key is is not stored in the object;
\r
3632 that is, `find(key) == end()`; example: `"key "the fast" not found"`
\r
3634 @complexity Logarithmic in the size of the container.
\r
3636 @liveexample{The example below shows how object elements can be read using
\r
3637 `at()`.,at__object_t_key_type_const}
\r
3639 @sa @ref operator[](const typename object_t::key_type&) for unchecked
\r
3640 access by reference
\r
3641 @sa @ref value() for access by value with a default value
\r
3643 @since version 1.0.0
\r
3645 const_reference at(const typename object_t::key_type& key) const
\r
3647 // at only works for objects
\r
3652 return m_value.object->at(key);
\r
3654 JSON_CATCH (std::out_of_range&)
\r
3656 // create better exception explanation
\r
3657 JSON_THROW(std::out_of_range("key '" + key + "' not found"));
\r
3662 JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
\r
3667 @brief access specified array element
\r
3669 Returns a reference to the element at specified location @a idx.
\r
3671 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
\r
3672 then the array is silently filled up with `null` values to make `idx` a
\r
3673 valid reference to the last stored element.
\r
3675 @param[in] idx index of the element to access
\r
3677 @return reference to the element at index @a idx
\r
3679 @throw std::domain_error if JSON is not an array or null; example:
\r
3680 `"cannot use operator[] with string"`
\r
3682 @complexity Constant if @a idx is in the range of the array. Otherwise
\r
3683 linear in `idx - size()`.
\r
3685 @liveexample{The example below shows how array elements can be read and
\r
3686 written using `[]` operator. Note the addition of `null`
\r
3687 values.,operatorarray__size_type}
\r
3689 @since version 1.0.0
\r
3691 reference operator[](size_type idx)
\r
3693 // implicitly convert null value to an empty array
\r
3696 m_type = value_t::array;
\r
3697 m_value.array = create<array_t>();
\r
3698 assert_invariant();
\r
3701 // operator[] only works for arrays
\r
3704 // fill up array with null values if given idx is outside range
\r
3705 if (idx >= m_value.array->size())
\r
3707 m_value.array->insert(m_value.array->end(),
\r
3708 idx - m_value.array->size() + 1,
\r
3712 return m_value.array->operator[](idx);
\r
3715 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
\r
3719 @brief access specified array element
\r
3721 Returns a const reference to the element at specified location @a idx.
\r
3723 @param[in] idx index of the element to access
\r
3725 @return const reference to the element at index @a idx
\r
3727 @throw std::domain_error if JSON is not an array; example: `"cannot use
\r
3728 operator[] with null"`
\r
3730 @complexity Constant.
\r
3732 @liveexample{The example below shows how array elements can be read using
\r
3733 the `[]` operator.,operatorarray__size_type_const}
\r
3735 @since version 1.0.0
\r
3737 const_reference operator[](size_type idx) const
\r
3739 // const operator[] only works for arrays
\r
3742 return m_value.array->operator[](idx);
\r
3745 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
\r
3749 @brief access specified object element
\r
3751 Returns a reference to the element at with specified key @a key.
\r
3753 @note If @a key is not found in the object, then it is silently added to
\r
3754 the object and filled with a `null` value to make `key` a valid reference.
\r
3755 In case the value was `null` before, it is converted to an object.
\r
3757 @param[in] key key of the element to access
\r
3759 @return reference to the element at key @a key
\r
3761 @throw std::domain_error if JSON is not an object or null; example:
\r
3762 `"cannot use operator[] with string"`
\r
3764 @complexity Logarithmic in the size of the container.
\r
3766 @liveexample{The example below shows how object elements can be read and
\r
3767 written using the `[]` operator.,operatorarray__key_type}
\r
3769 @sa @ref at(const typename object_t::key_type&) for access by reference
\r
3770 with range checking
\r
3771 @sa @ref value() for access by value with a default value
\r
3773 @since version 1.0.0
\r
3775 reference operator[](const typename object_t::key_type& key)
\r
3777 // implicitly convert null value to an empty object
\r
3780 m_type = value_t::object;
\r
3781 m_value.object = create<object_t>();
\r
3782 assert_invariant();
\r
3785 // operator[] only works for objects
\r
3788 return m_value.object->operator[](key);
\r
3791 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
\r
3795 @brief read-only access specified object element
\r
3797 Returns a const reference to the element at with specified key @a key. No
\r
3798 bounds checking is performed.
\r
3800 @warning If the element with key @a key does not exist, the behavior is
\r
3803 @param[in] key key of the element to access
\r
3805 @return const reference to the element at key @a key
\r
3807 @pre The element with key @a key must exist. **This precondition is
\r
3808 enforced with an assertion.**
\r
3810 @throw std::domain_error if JSON is not an object; example: `"cannot use
\r
3811 operator[] with null"`
\r
3813 @complexity Logarithmic in the size of the container.
\r
3815 @liveexample{The example below shows how object elements can be read using
\r
3816 the `[]` operator.,operatorarray__key_type_const}
\r
3818 @sa @ref at(const typename object_t::key_type&) for access by reference
\r
3819 with range checking
\r
3820 @sa @ref value() for access by value with a default value
\r
3822 @since version 1.0.0
\r
3824 const_reference operator[](const typename object_t::key_type& key) const
\r
3826 // const operator[] only works for objects
\r
3829 assert(m_value.object->find(key) != m_value.object->end());
\r
3830 return m_value.object->find(key)->second;
\r
3833 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
\r
3837 @brief access specified object element
\r
3839 Returns a reference to the element at with specified key @a key.
\r
3841 @note If @a key is not found in the object, then it is silently added to
\r
3842 the object and filled with a `null` value to make `key` a valid reference.
\r
3843 In case the value was `null` before, it is converted to an object.
\r
3845 @param[in] key key of the element to access
\r
3847 @return reference to the element at key @a key
\r
3849 @throw std::domain_error if JSON is not an object or null; example:
\r
3850 `"cannot use operator[] with string"`
\r
3852 @complexity Logarithmic in the size of the container.
\r
3854 @liveexample{The example below shows how object elements can be read and
\r
3855 written using the `[]` operator.,operatorarray__key_type}
\r
3857 @sa @ref at(const typename object_t::key_type&) for access by reference
\r
3858 with range checking
\r
3859 @sa @ref value() for access by value with a default value
\r
3861 @since version 1.0.0
\r
3863 template<typename T, std::size_t n>
\r
3864 reference operator[](T * (&key)[n])
\r
3866 return operator[](static_cast<const T>(key));
\r
3870 @brief read-only access specified object element
\r
3872 Returns a const reference to the element at with specified key @a key. No
\r
3873 bounds checking is performed.
\r
3875 @warning If the element with key @a key does not exist, the behavior is
\r
3878 @note This function is required for compatibility reasons with Clang.
\r
3880 @param[in] key key of the element to access
\r
3882 @return const reference to the element at key @a key
\r
3884 @throw std::domain_error if JSON is not an object; example: `"cannot use
\r
3885 operator[] with null"`
\r
3887 @complexity Logarithmic in the size of the container.
\r
3889 @liveexample{The example below shows how object elements can be read using
\r
3890 the `[]` operator.,operatorarray__key_type_const}
\r
3892 @sa @ref at(const typename object_t::key_type&) for access by reference
\r
3893 with range checking
\r
3894 @sa @ref value() for access by value with a default value
\r
3896 @since version 1.0.0
\r
3898 template<typename T, std::size_t n>
\r
3899 const_reference operator[](T * (&key)[n]) const
\r
3901 return operator[](static_cast<const T>(key));
\r
3905 @brief access specified object element
\r
3907 Returns a reference to the element at with specified key @a key.
\r
3909 @note If @a key is not found in the object, then it is silently added to
\r
3910 the object and filled with a `null` value to make `key` a valid reference.
\r
3911 In case the value was `null` before, it is converted to an object.
\r
3913 @param[in] key key of the element to access
\r
3915 @return reference to the element at key @a key
\r
3917 @throw std::domain_error if JSON is not an object or null; example:
\r
3918 `"cannot use operator[] with string"`
\r
3920 @complexity Logarithmic in the size of the container.
\r
3922 @liveexample{The example below shows how object elements can be read and
\r
3923 written using the `[]` operator.,operatorarray__key_type}
\r
3925 @sa @ref at(const typename object_t::key_type&) for access by reference
\r
3926 with range checking
\r
3927 @sa @ref value() for access by value with a default value
\r
3929 @since version 1.1.0
\r
3931 template<typename T>
\r
3932 reference operator[](T* key)
\r
3934 // implicitly convert null to object
\r
3937 m_type = value_t::object;
\r
3938 m_value = value_t::object;
\r
3939 assert_invariant();
\r
3942 // at only works for objects
\r
3945 return m_value.object->operator[](key);
\r
3948 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
\r
3952 @brief read-only access specified object element
\r
3954 Returns a const reference to the element at with specified key @a key. No
\r
3955 bounds checking is performed.
\r
3957 @warning If the element with key @a key does not exist, the behavior is
\r
3960 @param[in] key key of the element to access
\r
3962 @return const reference to the element at key @a key
\r
3964 @pre The element with key @a key must exist. **This precondition is
\r
3965 enforced with an assertion.**
\r
3967 @throw std::domain_error if JSON is not an object; example: `"cannot use
\r
3968 operator[] with null"`
\r
3970 @complexity Logarithmic in the size of the container.
\r
3972 @liveexample{The example below shows how object elements can be read using
\r
3973 the `[]` operator.,operatorarray__key_type_const}
\r
3975 @sa @ref at(const typename object_t::key_type&) for access by reference
\r
3976 with range checking
\r
3977 @sa @ref value() for access by value with a default value
\r
3979 @since version 1.1.0
\r
3981 template<typename T>
\r
3982 const_reference operator[](T* key) const
\r
3984 // at only works for objects
\r
3987 assert(m_value.object->find(key) != m_value.object->end());
\r
3988 return m_value.object->find(key)->second;
\r
3991 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
\r
3995 @brief access specified object element with default value
\r
3997 Returns either a copy of an object's element at the specified key @a key
\r
3998 or a given default value if no element with key @a key exists.
\r
4000 The function is basically equivalent to executing
\r
4004 } catch(std::out_of_range) {
\r
4005 return default_value;
\r
4009 @note Unlike @ref at(const typename object_t::key_type&), this function
\r
4010 does not throw if the given key @a key was not found.
\r
4012 @note Unlike @ref operator[](const typename object_t::key_type& key), this
\r
4013 function does not implicitly add an element to the position defined by @a
\r
4014 key. This function is furthermore also applicable to const objects.
\r
4016 @param[in] key key of the element to access
\r
4017 @param[in] default_value the value to return if @a key is not found
\r
4019 @tparam ValueType type compatible to JSON values, for instance `int` for
\r
4020 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
\r
4021 JSON arrays. Note the type of the expected value at @a key and the default
\r
4022 value @a default_value must be compatible.
\r
4024 @return copy of the element at key @a key or @a default_value if @a key
\r
4027 @throw std::domain_error if JSON is not an object; example: `"cannot use
\r
4028 value() with null"`
\r
4030 @complexity Logarithmic in the size of the container.
\r
4032 @liveexample{The example below shows how object elements can be queried
\r
4033 with a default value.,basic_json__value}
\r
4035 @sa @ref at(const typename object_t::key_type&) for access by reference
\r
4036 with range checking
\r
4037 @sa @ref operator[](const typename object_t::key_type&) for unchecked
\r
4038 access by reference
\r
4040 @since version 1.0.0
\r
4042 template<class ValueType, typename std::enable_if<
\r
4043 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
\r
4044 ValueType value(const typename object_t::key_type& key, ValueType default_value) const
\r
4046 // at only works for objects
\r
4049 // if key is found, return value and given default value otherwise
\r
4050 const auto it = find(key);
\r
4056 return default_value;
\r
4060 JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
\r
4065 @brief overload for a default value of type const char*
\r
4066 @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
\r
4068 string_t value(const typename object_t::key_type& key, const char* default_value) const
\r
4070 return value(key, string_t(default_value));
\r
4074 @brief access specified object element via JSON Pointer with default value
\r
4076 Returns either a copy of an object's element at the specified key @a key
\r
4077 or a given default value if no element with key @a key exists.
\r
4079 The function is basically equivalent to executing
\r
4083 } catch(std::out_of_range) {
\r
4084 return default_value;
\r
4088 @note Unlike @ref at(const json_pointer&), this function does not throw
\r
4089 if the given key @a key was not found.
\r
4091 @param[in] ptr a JSON pointer to the element to access
\r
4092 @param[in] default_value the value to return if @a ptr found no value
\r
4094 @tparam ValueType type compatible to JSON values, for instance `int` for
\r
4095 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
\r
4096 JSON arrays. Note the type of the expected value at @a key and the default
\r
4097 value @a default_value must be compatible.
\r
4099 @return copy of the element at key @a key or @a default_value if @a key
\r
4102 @throw std::domain_error if JSON is not an object; example: `"cannot use
\r
4103 value() with null"`
\r
4105 @complexity Logarithmic in the size of the container.
\r
4107 @liveexample{The example below shows how object elements can be queried
\r
4108 with a default value.,basic_json__value_ptr}
\r
4110 @sa @ref operator[](const json_pointer&) for unchecked access by reference
\r
4112 @since version 2.0.2
\r
4114 template<class ValueType, typename std::enable_if<
\r
4115 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
\r
4116 ValueType value(const json_pointer& ptr, ValueType default_value) const
\r
4118 // at only works for objects
\r
4121 // if pointer resolves a value, return it or use default value
\r
4124 return ptr.get_checked(this);
\r
4126 JSON_CATCH (std::out_of_range&)
\r
4128 return default_value;
\r
4132 JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
\r
4136 @brief overload for a default value of type const char*
\r
4137 @copydoc basic_json::value(const json_pointer&, ValueType) const
\r
4139 string_t value(const json_pointer& ptr, const char* default_value) const
\r
4141 return value(ptr, string_t(default_value));
\r
4145 @brief access the first element
\r
4147 Returns a reference to the first element in the container. For a JSON
\r
4148 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
\r
4150 @return In case of a structured type (array or object), a reference to the
\r
4151 first element is returned. In case of number, string, or boolean values, a
\r
4152 reference to the value is returned.
\r
4154 @complexity Constant.
\r
4156 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
\r
4157 or an empty array or object (undefined behavior, **guarded by
\r
4159 @post The JSON value remains unchanged.
\r
4161 @throw std::out_of_range when called on `null` value
\r
4163 @liveexample{The following code shows an example for `front()`.,front}
\r
4165 @sa @ref back() -- access the last element
\r
4167 @since version 1.0.0
\r
4175 @copydoc basic_json::front()
\r
4177 const_reference front() const
\r
4183 @brief access the last element
\r
4185 Returns a reference to the last element in the container. For a JSON
\r
4186 container `c`, the expression `c.back()` is equivalent to
\r
4188 auto tmp = c.end();
\r
4193 @return In case of a structured type (array or object), a reference to the
\r
4194 last element is returned. In case of number, string, or boolean values, a
\r
4195 reference to the value is returned.
\r
4197 @complexity Constant.
\r
4199 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
\r
4200 or an empty array or object (undefined behavior, **guarded by
\r
4202 @post The JSON value remains unchanged.
\r
4204 @throw std::out_of_range when called on `null` value.
\r
4206 @liveexample{The following code shows an example for `back()`.,back}
\r
4208 @sa @ref front() -- access the first element
\r
4210 @since version 1.0.0
\r
4220 @copydoc basic_json::back()
\r
4222 const_reference back() const
\r
4224 auto tmp = cend();
\r
4230 @brief remove element given an iterator
\r
4232 Removes the element specified by iterator @a pos. The iterator @a pos must
\r
4233 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
\r
4234 but is not dereferenceable) cannot be used as a value for @a pos.
\r
4236 If called on a primitive type other than `null`, the resulting JSON value
\r
4239 @param[in] pos iterator to the element to remove
\r
4240 @return Iterator following the last removed element. If the iterator @a
\r
4241 pos refers to the last element, the `end()` iterator is returned.
\r
4243 @tparam IteratorType an @ref iterator or @ref const_iterator
\r
4245 @post Invalidates iterators and references at or after the point of the
\r
4246 erase, including the `end()` iterator.
\r
4248 @throw std::domain_error if called on a `null` value; example: `"cannot
\r
4249 use erase() with null"`
\r
4250 @throw std::domain_error if called on an iterator which does not belong to
\r
4251 the current JSON value; example: `"iterator does not fit current value"`
\r
4252 @throw std::out_of_range if called on a primitive type with invalid
\r
4253 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
\r
4256 @complexity The complexity depends on the type:
\r
4257 - objects: amortized constant
\r
4258 - arrays: linear in distance between @a pos and the end of the container
\r
4259 - strings: linear in the length of the string
\r
4260 - other types: constant
\r
4262 @liveexample{The example shows the result of `erase()` for different JSON
\r
4263 types.,erase__IteratorType}
\r
4265 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
\r
4267 @sa @ref erase(const typename object_t::key_type&) -- removes the element
\r
4268 from an object at the given key
\r
4269 @sa @ref erase(const size_type) -- removes the element from an array at
\r
4272 @since version 1.0.0
\r
4274 template<class IteratorType, typename std::enable_if<
\r
4275 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
\r
4276 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
\r
4278 IteratorType erase(IteratorType pos)
\r
4280 // make sure iterator fits the current value
\r
4281 if (this != pos.m_object)
\r
4283 JSON_THROW(std::domain_error("iterator does not fit current value"));
\r
4286 IteratorType result = end();
\r
4290 case value_t::boolean:
\r
4291 case value_t::number_float:
\r
4292 case value_t::number_integer:
\r
4293 case value_t::number_unsigned:
\r
4294 case value_t::string:
\r
4296 if (not pos.m_it.primitive_iterator.is_begin())
\r
4298 JSON_THROW(std::out_of_range("iterator out of range"));
\r
4303 AllocatorType<string_t> alloc;
\r
4304 alloc.destroy(m_value.string);
\r
4305 alloc.deallocate(m_value.string, 1);
\r
4306 m_value.string = nullptr;
\r
4309 m_type = value_t::null;
\r
4310 assert_invariant();
\r
4314 case value_t::object:
\r
4316 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
\r
4320 case value_t::array:
\r
4322 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
\r
4328 JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
\r
4336 @brief remove elements given an iterator range
\r
4338 Removes the element specified by the range `[first; last)`. The iterator
\r
4339 @a first does not need to be dereferenceable if `first == last`: erasing
\r
4340 an empty range is a no-op.
\r
4342 If called on a primitive type other than `null`, the resulting JSON value
\r
4345 @param[in] first iterator to the beginning of the range to remove
\r
4346 @param[in] last iterator past the end of the range to remove
\r
4347 @return Iterator following the last removed element. If the iterator @a
\r
4348 second refers to the last element, the `end()` iterator is returned.
\r
4350 @tparam IteratorType an @ref iterator or @ref const_iterator
\r
4352 @post Invalidates iterators and references at or after the point of the
\r
4353 erase, including the `end()` iterator.
\r
4355 @throw std::domain_error if called on a `null` value; example: `"cannot
\r
4356 use erase() with null"`
\r
4357 @throw std::domain_error if called on iterators which does not belong to
\r
4358 the current JSON value; example: `"iterators do not fit current value"`
\r
4359 @throw std::out_of_range if called on a primitive type with invalid
\r
4360 iterators (i.e., if `first != begin()` and `last != end()`); example:
\r
4361 `"iterators out of range"`
\r
4363 @complexity The complexity depends on the type:
\r
4364 - objects: `log(size()) + std::distance(first, last)`
\r
4365 - arrays: linear in the distance between @a first and @a last, plus linear
\r
4366 in the distance between @a last and end of the container
\r
4367 - strings: linear in the length of the string
\r
4368 - other types: constant
\r
4370 @liveexample{The example shows the result of `erase()` for different JSON
\r
4371 types.,erase__IteratorType_IteratorType}
\r
4373 @sa @ref erase(IteratorType) -- removes the element at a given position
\r
4374 @sa @ref erase(const typename object_t::key_type&) -- removes the element
\r
4375 from an object at the given key
\r
4376 @sa @ref erase(const size_type) -- removes the element from an array at
\r
4379 @since version 1.0.0
\r
4381 template<class IteratorType, typename std::enable_if<
\r
4382 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
\r
4383 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
\r
4385 IteratorType erase(IteratorType first, IteratorType last)
\r
4387 // make sure iterator fits the current value
\r
4388 if (this != first.m_object or this != last.m_object)
\r
4390 JSON_THROW(std::domain_error("iterators do not fit current value"));
\r
4393 IteratorType result = end();
\r
4397 case value_t::boolean:
\r
4398 case value_t::number_float:
\r
4399 case value_t::number_integer:
\r
4400 case value_t::number_unsigned:
\r
4401 case value_t::string:
\r
4403 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
\r
4405 JSON_THROW(std::out_of_range("iterators out of range"));
\r
4410 AllocatorType<string_t> alloc;
\r
4411 alloc.destroy(m_value.string);
\r
4412 alloc.deallocate(m_value.string, 1);
\r
4413 m_value.string = nullptr;
\r
4416 m_type = value_t::null;
\r
4417 assert_invariant();
\r
4421 case value_t::object:
\r
4423 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
\r
4424 last.m_it.object_iterator);
\r
4428 case value_t::array:
\r
4430 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
\r
4431 last.m_it.array_iterator);
\r
4437 JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
\r
4445 @brief remove element from a JSON object given a key
\r
4447 Removes elements from a JSON object with the key value @a key.
\r
4449 @param[in] key value of the elements to remove
\r
4451 @return Number of elements removed. If @a ObjectType is the default
\r
4452 `std::map` type, the return value will always be `0` (@a key was not
\r
4453 found) or `1` (@a key was found).
\r
4455 @post References and iterators to the erased elements are invalidated.
\r
4456 Other references and iterators are not affected.
\r
4458 @throw std::domain_error when called on a type other than JSON object;
\r
4459 example: `"cannot use erase() with null"`
\r
4461 @complexity `log(size()) + count(key)`
\r
4463 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
\r
4465 @sa @ref erase(IteratorType) -- removes the element at a given position
\r
4466 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
\r
4468 @sa @ref erase(const size_type) -- removes the element from an array at
\r
4471 @since version 1.0.0
\r
4473 size_type erase(const typename object_t::key_type& key)
\r
4475 // this erase only works for objects
\r
4478 return m_value.object->erase(key);
\r
4481 JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
\r
4485 @brief remove element from a JSON array given an index
\r
4487 Removes element from a JSON array at the index @a idx.
\r
4489 @param[in] idx index of the element to remove
\r
4491 @throw std::domain_error when called on a type other than JSON array;
\r
4492 example: `"cannot use erase() with null"`
\r
4493 @throw std::out_of_range when `idx >= size()`; example: `"array index 17
\r
4496 @complexity Linear in distance between @a idx and the end of the container.
\r
4498 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
\r
4500 @sa @ref erase(IteratorType) -- removes the element at a given position
\r
4501 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
\r
4503 @sa @ref erase(const typename object_t::key_type&) -- removes the element
\r
4504 from an object at the given key
\r
4506 @since version 1.0.0
\r
4508 void erase(const size_type idx)
\r
4510 // this erase only works for arrays
\r
4513 if (idx >= size())
\r
4515 JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
\r
4518 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
\r
4522 JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
\r
4537 @brief find an element in a JSON object
\r
4539 Finds an element in a JSON object with key equivalent to @a key. If the
\r
4540 element is not found or the JSON value is not an object, end() is
\r
4543 @note This method always returns @ref end() when executed on a JSON type
\r
4544 that is not an object.
\r
4546 @param[in] key key value of the element to search for
\r
4548 @return Iterator to an element with key equivalent to @a key. If no such
\r
4549 element is found or the JSON value is not an object, past-the-end (see
\r
4550 @ref end()) iterator is returned.
\r
4552 @complexity Logarithmic in the size of the JSON object.
\r
4554 @liveexample{The example shows how `find()` is used.,find__key_type}
\r
4556 @since version 1.0.0
\r
4558 iterator find(typename object_t::key_type key)
\r
4560 auto result = end();
\r
4564 result.m_it.object_iterator = m_value.object->find(key);
\r
4571 @brief find an element in a JSON object
\r
4572 @copydoc find(typename object_t::key_type)
\r
4574 const_iterator find(typename object_t::key_type key) const
\r
4576 auto result = cend();
\r
4580 result.m_it.object_iterator = m_value.object->find(key);
\r
4587 @brief returns the number of occurrences of a key in a JSON object
\r
4589 Returns the number of elements with key @a key. If ObjectType is the
\r
4590 default `std::map` type, the return value will always be `0` (@a key was
\r
4591 not found) or `1` (@a key was found).
\r
4593 @note This method always returns `0` when executed on a JSON type that is
\r
4596 @param[in] key key value of the element to count
\r
4598 @return Number of elements with key @a key. If the JSON value is not an
\r
4599 object, the return value will be `0`.
\r
4601 @complexity Logarithmic in the size of the JSON object.
\r
4603 @liveexample{The example shows how `count()` is used.,count}
\r
4605 @since version 1.0.0
\r
4607 size_type count(typename object_t::key_type key) const
\r
4609 // return 0 for all nonobject types
\r
4610 return is_object() ? m_value.object->count(key) : 0;
\r
4620 /// @name iterators
\r
4624 @brief returns an iterator to the first element
\r
4626 Returns an iterator to the first element.
\r
4628 @image html range-begin-end.svg "Illustration from cppreference.com"
\r
4630 @return iterator to the first element
\r
4632 @complexity Constant.
\r
4634 @requirement This function helps `basic_json` satisfying the
\r
4635 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
4637 - The complexity is constant.
\r
4639 @liveexample{The following code shows an example for `begin()`.,begin}
\r
4641 @sa @ref cbegin() -- returns a const iterator to the beginning
\r
4642 @sa @ref end() -- returns an iterator to the end
\r
4643 @sa @ref cend() -- returns a const iterator to the end
\r
4645 @since version 1.0.0
\r
4647 iterator begin() noexcept
\r
4649 iterator result(this);
\r
4650 result.set_begin();
\r
4655 @copydoc basic_json::cbegin()
\r
4657 const_iterator begin() const noexcept
\r
4663 @brief returns a const iterator to the first element
\r
4665 Returns a const iterator to the first element.
\r
4667 @image html range-begin-end.svg "Illustration from cppreference.com"
\r
4669 @return const iterator to the first element
\r
4671 @complexity Constant.
\r
4673 @requirement This function helps `basic_json` satisfying the
\r
4674 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
4676 - The complexity is constant.
\r
4677 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
\r
4679 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
\r
4681 @sa @ref begin() -- returns an iterator to the beginning
\r
4682 @sa @ref end() -- returns an iterator to the end
\r
4683 @sa @ref cend() -- returns a const iterator to the end
\r
4685 @since version 1.0.0
\r
4687 const_iterator cbegin() const noexcept
\r
4689 const_iterator result(this);
\r
4690 result.set_begin();
\r
4695 @brief returns an iterator to one past the last element
\r
4697 Returns an iterator to one past the last element.
\r
4699 @image html range-begin-end.svg "Illustration from cppreference.com"
\r
4701 @return iterator one past the last element
\r
4703 @complexity Constant.
\r
4705 @requirement This function helps `basic_json` satisfying the
\r
4706 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
4708 - The complexity is constant.
\r
4710 @liveexample{The following code shows an example for `end()`.,end}
\r
4712 @sa @ref cend() -- returns a const iterator to the end
\r
4713 @sa @ref begin() -- returns an iterator to the beginning
\r
4714 @sa @ref cbegin() -- returns a const iterator to the beginning
\r
4716 @since version 1.0.0
\r
4718 iterator end() noexcept
\r
4720 iterator result(this);
\r
4726 @copydoc basic_json::cend()
\r
4728 const_iterator end() const noexcept
\r
4734 @brief returns a const iterator to one past the last element
\r
4736 Returns a const iterator to one past the last element.
\r
4738 @image html range-begin-end.svg "Illustration from cppreference.com"
\r
4740 @return const iterator one past the last element
\r
4742 @complexity Constant.
\r
4744 @requirement This function helps `basic_json` satisfying the
\r
4745 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
4747 - The complexity is constant.
\r
4748 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
\r
4750 @liveexample{The following code shows an example for `cend()`.,cend}
\r
4752 @sa @ref end() -- returns an iterator to the end
\r
4753 @sa @ref begin() -- returns an iterator to the beginning
\r
4754 @sa @ref cbegin() -- returns a const iterator to the beginning
\r
4756 @since version 1.0.0
\r
4758 const_iterator cend() const noexcept
\r
4760 const_iterator result(this);
\r
4766 @brief returns an iterator to the reverse-beginning
\r
4768 Returns an iterator to the reverse-beginning; that is, the last element.
\r
4770 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
\r
4772 @complexity Constant.
\r
4774 @requirement This function helps `basic_json` satisfying the
\r
4775 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
\r
4777 - The complexity is constant.
\r
4778 - Has the semantics of `reverse_iterator(end())`.
\r
4780 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
\r
4782 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
\r
4783 @sa @ref rend() -- returns a reverse iterator to the end
\r
4784 @sa @ref crend() -- returns a const reverse iterator to the end
\r
4786 @since version 1.0.0
\r
4788 reverse_iterator rbegin() noexcept
\r
4790 return reverse_iterator(end());
\r
4794 @copydoc basic_json::crbegin()
\r
4796 const_reverse_iterator rbegin() const noexcept
\r
4802 @brief returns an iterator to the reverse-end
\r
4804 Returns an iterator to the reverse-end; that is, one before the first
\r
4807 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
\r
4809 @complexity Constant.
\r
4811 @requirement This function helps `basic_json` satisfying the
\r
4812 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
\r
4814 - The complexity is constant.
\r
4815 - Has the semantics of `reverse_iterator(begin())`.
\r
4817 @liveexample{The following code shows an example for `rend()`.,rend}
\r
4819 @sa @ref crend() -- returns a const reverse iterator to the end
\r
4820 @sa @ref rbegin() -- returns a reverse iterator to the beginning
\r
4821 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
\r
4823 @since version 1.0.0
\r
4825 reverse_iterator rend() noexcept
\r
4827 return reverse_iterator(begin());
\r
4831 @copydoc basic_json::crend()
\r
4833 const_reverse_iterator rend() const noexcept
\r
4839 @brief returns a const reverse iterator to the last element
\r
4841 Returns a const iterator to the reverse-beginning; that is, the last
\r
4844 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
\r
4846 @complexity Constant.
\r
4848 @requirement This function helps `basic_json` satisfying the
\r
4849 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
\r
4851 - The complexity is constant.
\r
4852 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
\r
4854 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
\r
4856 @sa @ref rbegin() -- returns a reverse iterator to the beginning
\r
4857 @sa @ref rend() -- returns a reverse iterator to the end
\r
4858 @sa @ref crend() -- returns a const reverse iterator to the end
\r
4860 @since version 1.0.0
\r
4862 const_reverse_iterator crbegin() const noexcept
\r
4864 return const_reverse_iterator(cend());
\r
4868 @brief returns a const reverse iterator to one before the first
\r
4870 Returns a const reverse iterator to the reverse-end; that is, one before
\r
4871 the first element.
\r
4873 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
\r
4875 @complexity Constant.
\r
4877 @requirement This function helps `basic_json` satisfying the
\r
4878 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
\r
4880 - The complexity is constant.
\r
4881 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
\r
4883 @liveexample{The following code shows an example for `crend()`.,crend}
\r
4885 @sa @ref rend() -- returns a reverse iterator to the end
\r
4886 @sa @ref rbegin() -- returns a reverse iterator to the beginning
\r
4887 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
\r
4889 @since version 1.0.0
\r
4891 const_reverse_iterator crend() const noexcept
\r
4893 return const_reverse_iterator(cbegin());
\r
4897 // forward declaration
\r
4898 template<typename IteratorType> class iteration_proxy;
\r
4902 @brief wrapper to access iterator member functions in range-based for
\r
4904 This function allows to access @ref iterator::key() and @ref
\r
4905 iterator::value() during range-based for loops. In these loops, a
\r
4906 reference to the JSON values is returned, so there is no access to the
\r
4907 underlying iterator.
\r
4909 @note The name of this function is not yet final and may change in the
\r
4912 static iteration_proxy<iterator> iterator_wrapper(reference cont)
\r
4914 return iteration_proxy<iterator>(cont);
\r
4918 @copydoc iterator_wrapper(reference)
\r
4920 static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
\r
4922 return iteration_proxy<const_iterator>(cont);
\r
4932 /// @name capacity
\r
4936 @brief checks whether the container is empty
\r
4938 Checks if a JSON value has no elements.
\r
4940 @return The return value depends on the different types and is
\r
4941 defined as follows:
\r
4942 Value type | return value
\r
4943 ----------- | -------------
\r
4948 object | result of function `object_t::empty()`
\r
4949 array | result of function `array_t::empty()`
\r
4951 @note This function does not return whether a string stored as JSON value
\r
4952 is empty - it returns whether the JSON container itself is empty which is
\r
4953 false in the case of a string.
\r
4955 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
\r
4956 the Container concept; that is, their `empty()` functions have constant
\r
4959 @requirement This function helps `basic_json` satisfying the
\r
4960 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
4962 - The complexity is constant.
\r
4963 - Has the semantics of `begin() == end()`.
\r
4965 @liveexample{The following code uses `empty()` to check if a JSON
\r
4966 object contains any elements.,empty}
\r
4968 @sa @ref size() -- returns the number of elements
\r
4970 @since version 1.0.0
\r
4972 bool empty() const noexcept
\r
4976 case value_t::null:
\r
4978 // null values are empty
\r
4982 case value_t::array:
\r
4984 // delegate call to array_t::empty()
\r
4985 return m_value.array->empty();
\r
4988 case value_t::object:
\r
4990 // delegate call to object_t::empty()
\r
4991 return m_value.object->empty();
\r
4996 // all other types are nonempty
\r
5003 @brief returns the number of elements
\r
5005 Returns the number of elements in a JSON value.
\r
5007 @return The return value depends on the different types and is
\r
5008 defined as follows:
\r
5009 Value type | return value
\r
5010 ----------- | -------------
\r
5015 object | result of function object_t::size()
\r
5016 array | result of function array_t::size()
\r
5018 @note This function does not return the length of a string stored as JSON
\r
5019 value - it returns the number of elements in the JSON value which is 1 in
\r
5020 the case of a string.
\r
5022 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
\r
5023 the Container concept; that is, their size() functions have constant
\r
5026 @requirement This function helps `basic_json` satisfying the
\r
5027 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
5029 - The complexity is constant.
\r
5030 - Has the semantics of `std::distance(begin(), end())`.
\r
5032 @liveexample{The following code calls `size()` on the different value
\r
5035 @sa @ref empty() -- checks whether the container is empty
\r
5036 @sa @ref max_size() -- returns the maximal number of elements
\r
5038 @since version 1.0.0
\r
5040 size_type size() const noexcept
\r
5044 case value_t::null:
\r
5046 // null values are empty
\r
5050 case value_t::array:
\r
5052 // delegate call to array_t::size()
\r
5053 return m_value.array->size();
\r
5056 case value_t::object:
\r
5058 // delegate call to object_t::size()
\r
5059 return m_value.object->size();
\r
5064 // all other types have size 1
\r
5071 @brief returns the maximum possible number of elements
\r
5073 Returns the maximum number of elements a JSON value is able to hold due to
\r
5074 system or library implementation limitations, i.e. `std::distance(begin(),
\r
5075 end())` for the JSON value.
\r
5077 @return The return value depends on the different types and is
\r
5078 defined as follows:
\r
5079 Value type | return value
\r
5080 ----------- | -------------
\r
5081 null | `0` (same as `size()`)
\r
5082 boolean | `1` (same as `size()`)
\r
5083 string | `1` (same as `size()`)
\r
5084 number | `1` (same as `size()`)
\r
5085 object | result of function `object_t::max_size()`
\r
5086 array | result of function `array_t::max_size()`
\r
5088 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
\r
5089 the Container concept; that is, their `max_size()` functions have constant
\r
5092 @requirement This function helps `basic_json` satisfying the
\r
5093 [Container](http://en.cppreference.com/w/cpp/concept/Container)
\r
5095 - The complexity is constant.
\r
5096 - Has the semantics of returning `b.size()` where `b` is the largest
\r
5097 possible JSON value.
\r
5099 @liveexample{The following code calls `max_size()` on the different value
\r
5100 types. Note the output is implementation specific.,max_size}
\r
5102 @sa @ref size() -- returns the number of elements
\r
5104 @since version 1.0.0
\r
5106 size_type max_size() const noexcept
\r
5110 case value_t::array:
\r
5112 // delegate call to array_t::max_size()
\r
5113 return m_value.array->max_size();
\r
5116 case value_t::object:
\r
5118 // delegate call to object_t::max_size()
\r
5119 return m_value.object->max_size();
\r
5124 // all other types have max_size() == size()
\r
5137 /// @name modifiers
\r
5141 @brief clears the contents
\r
5143 Clears the content of a JSON value and resets it to the default value as
\r
5144 if @ref basic_json(value_t) would have been called:
\r
5146 Value type | initial value
\r
5147 ----------- | -------------
\r
5155 @complexity Linear in the size of the JSON value.
\r
5157 @liveexample{The example below shows the effect of `clear()` to different
\r
5158 JSON types.,clear}
\r
5160 @since version 1.0.0
\r
5162 void clear() noexcept
\r
5166 case value_t::number_integer:
\r
5168 m_value.number_integer = 0;
\r
5172 case value_t::number_unsigned:
\r
5174 m_value.number_unsigned = 0;
\r
5178 case value_t::number_float:
\r
5180 m_value.number_float = 0.0;
\r
5184 case value_t::boolean:
\r
5186 m_value.boolean = false;
\r
5190 case value_t::string:
\r
5192 m_value.string->clear();
\r
5196 case value_t::array:
\r
5198 m_value.array->clear();
\r
5202 case value_t::object:
\r
5204 m_value.object->clear();
\r
5216 @brief add an object to an array
\r
5218 Appends the given element @a val to the end of the JSON value. If the
\r
5219 function is called on a JSON null value, an empty array is created before
\r
5222 @param[in] val the value to add to the JSON array
\r
5224 @throw std::domain_error when called on a type other than JSON array or
\r
5225 null; example: `"cannot use push_back() with number"`
\r
5227 @complexity Amortized constant.
\r
5229 @liveexample{The example shows how `push_back()` and `+=` can be used to
\r
5230 add elements to a JSON array. Note how the `null` value was silently
\r
5231 converted to a JSON array.,push_back}
\r
5233 @since version 1.0.0
\r
5235 void push_back(basic_json&& val)
\r
5237 // push_back only works for null objects or arrays
\r
5238 if (not(is_null() or is_array()))
\r
5240 JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
\r
5243 // transform null object into an array
\r
5246 m_type = value_t::array;
\r
5247 m_value = value_t::array;
\r
5248 assert_invariant();
\r
5251 // add element to array (move semantics)
\r
5252 m_value.array->push_back(std::move(val));
\r
5253 // invalidate object
\r
5254 val.m_type = value_t::null;
\r
5258 @brief add an object to an array
\r
5259 @copydoc push_back(basic_json&&)
\r
5261 reference operator+=(basic_json&& val)
\r
5263 push_back(std::move(val));
\r
5268 @brief add an object to an array
\r
5269 @copydoc push_back(basic_json&&)
\r
5271 void push_back(const basic_json& val)
\r
5273 // push_back only works for null objects or arrays
\r
5274 if (not(is_null() or is_array()))
\r
5276 JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
\r
5279 // transform null object into an array
\r
5282 m_type = value_t::array;
\r
5283 m_value = value_t::array;
\r
5284 assert_invariant();
\r
5287 // add element to array
\r
5288 m_value.array->push_back(val);
\r
5292 @brief add an object to an array
\r
5293 @copydoc push_back(basic_json&&)
\r
5295 reference operator+=(const basic_json& val)
\r
5302 @brief add an object to an object
\r
5304 Inserts the given element @a val to the JSON object. If the function is
\r
5305 called on a JSON null value, an empty object is created before inserting
\r
5308 @param[in] val the value to add to the JSON object
\r
5310 @throw std::domain_error when called on a type other than JSON object or
\r
5311 null; example: `"cannot use push_back() with number"`
\r
5313 @complexity Logarithmic in the size of the container, O(log(`size()`)).
\r
5315 @liveexample{The example shows how `push_back()` and `+=` can be used to
\r
5316 add elements to a JSON object. Note how the `null` value was silently
\r
5317 converted to a JSON object.,push_back__object_t__value}
\r
5319 @since version 1.0.0
\r
5321 void push_back(const typename object_t::value_type& val)
\r
5323 // push_back only works for null objects or objects
\r
5324 if (not(is_null() or is_object()))
\r
5326 JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
\r
5329 // transform null object into an object
\r
5332 m_type = value_t::object;
\r
5333 m_value = value_t::object;
\r
5334 assert_invariant();
\r
5337 // add element to array
\r
5338 m_value.object->insert(val);
\r
5342 @brief add an object to an object
\r
5343 @copydoc push_back(const typename object_t::value_type&)
\r
5345 reference operator+=(const typename object_t::value_type& val)
\r
5352 @brief add an object to an object
\r
5354 This function allows to use `push_back` with an initializer list. In case
\r
5356 1. the current value is an object,
\r
5357 2. the initializer list @a init contains only two elements, and
\r
5358 3. the first element of @a init is a string,
\r
5360 @a init is converted into an object element and added using
\r
5361 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
\r
5362 is converted to a JSON value and added using @ref push_back(basic_json&&).
\r
5364 @param init an initializer list
\r
5366 @complexity Linear in the size of the initializer list @a init.
\r
5368 @note This function is required to resolve an ambiguous overload error,
\r
5369 because pairs like `{"key", "value"}` can be both interpreted as
\r
5370 `object_t::value_type` or `std::initializer_list<basic_json>`, see
\r
5371 https://github.com/nlohmann/json/issues/235 for more information.
\r
5373 @liveexample{The example shows how initializer lists are treated as
\r
5374 objects when possible.,push_back__initializer_list}
\r
5376 void push_back(std::initializer_list<basic_json> init)
\r
5378 if (is_object() and init.size() == 2 and init.begin()->is_string())
\r
5380 const string_t key = *init.begin();
\r
5381 push_back(typename object_t::value_type(key, *(init.begin() + 1)));
\r
5385 push_back(basic_json(init));
\r
5390 @brief add an object to an object
\r
5391 @copydoc push_back(std::initializer_list<basic_json>)
\r
5393 reference operator+=(std::initializer_list<basic_json> init)
\r
5400 @brief add an object to an array
\r
5402 Creates a JSON value from the passed parameters @a args to the end of the
\r
5403 JSON value. If the function is called on a JSON null value, an empty array
\r
5404 is created before appending the value created from @a args.
\r
5406 @param[in] args arguments to forward to a constructor of @ref basic_json
\r
5407 @tparam Args compatible types to create a @ref basic_json object
\r
5409 @throw std::domain_error when called on a type other than JSON array or
\r
5410 null; example: `"cannot use emplace_back() with number"`
\r
5412 @complexity Amortized constant.
\r
5414 @liveexample{The example shows how `push_back()` can be used to add
\r
5415 elements to a JSON array. Note how the `null` value was silently converted
\r
5416 to a JSON array.,emplace_back}
\r
5418 @since version 2.0.8
\r
5420 template<class... Args>
\r
5421 void emplace_back(Args&& ... args)
\r
5423 // emplace_back only works for null objects or arrays
\r
5424 if (not(is_null() or is_array()))
\r
5426 JSON_THROW(std::domain_error("cannot use emplace_back() with " + type_name()));
\r
5429 // transform null object into an array
\r
5432 m_type = value_t::array;
\r
5433 m_value = value_t::array;
\r
5434 assert_invariant();
\r
5437 // add element to array (perfect forwarding)
\r
5438 m_value.array->emplace_back(std::forward<Args>(args)...);
\r
5442 @brief add an object to an object if key does not exist
\r
5444 Inserts a new element into a JSON object constructed in-place with the
\r
5445 given @a args if there is no element with the key in the container. If the
\r
5446 function is called on a JSON null value, an empty object is created before
\r
5447 appending the value created from @a args.
\r
5449 @param[in] args arguments to forward to a constructor of @ref basic_json
\r
5450 @tparam Args compatible types to create a @ref basic_json object
\r
5452 @return a pair consisting of an iterator to the inserted element, or the
\r
5453 already-existing element if no insertion happened, and a bool
\r
5454 denoting whether the insertion took place.
\r
5456 @throw std::domain_error when called on a type other than JSON object or
\r
5457 null; example: `"cannot use emplace() with number"`
\r
5459 @complexity Logarithmic in the size of the container, O(log(`size()`)).
\r
5461 @liveexample{The example shows how `emplace()` can be used to add elements
\r
5462 to a JSON object. Note how the `null` value was silently converted to a
\r
5463 JSON object. Further note how no value is added if there was already one
\r
5464 value stored with the same key.,emplace}
\r
5466 @since version 2.0.8
\r
5468 template<class... Args>
\r
5469 std::pair<iterator, bool> emplace(Args&& ... args)
\r
5471 // emplace only works for null objects or arrays
\r
5472 if (not(is_null() or is_object()))
\r
5474 JSON_THROW(std::domain_error("cannot use emplace() with " + type_name()));
\r
5477 // transform null object into an object
\r
5480 m_type = value_t::object;
\r
5481 m_value = value_t::object;
\r
5482 assert_invariant();
\r
5485 // add element to array (perfect forwarding)
\r
5486 auto res = m_value.object->emplace(std::forward<Args>(args)...);
\r
5487 // create result iterator and set iterator to the result of emplace
\r
5488 auto it = begin();
\r
5489 it.m_it.object_iterator = res.first;
\r
5491 // return pair of iterator and boolean
\r
5492 return {it, res.second};
\r
5496 @brief inserts element
\r
5498 Inserts element @a val before iterator @a pos.
\r
5500 @param[in] pos iterator before which the content will be inserted; may be
\r
5501 the end() iterator
\r
5502 @param[in] val element to insert
\r
5503 @return iterator pointing to the inserted @a val.
\r
5505 @throw std::domain_error if called on JSON values other than arrays;
\r
5506 example: `"cannot use insert() with string"`
\r
5507 @throw std::domain_error if @a pos is not an iterator of *this; example:
\r
5508 `"iterator does not fit current value"`
\r
5510 @complexity Constant plus linear in the distance between @a pos and end of
\r
5513 @liveexample{The example shows how `insert()` is used.,insert}
\r
5515 @since version 1.0.0
\r
5517 iterator insert(const_iterator pos, const basic_json& val)
\r
5519 // insert only works for arrays
\r
5522 // check if iterator pos fits to this JSON value
\r
5523 if (pos.m_object != this)
\r
5525 JSON_THROW(std::domain_error("iterator does not fit current value"));
\r
5528 // insert to array and return iterator
\r
5529 iterator result(this);
\r
5530 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
\r
5534 JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
\r
5538 @brief inserts element
\r
5539 @copydoc insert(const_iterator, const basic_json&)
\r
5541 iterator insert(const_iterator pos, basic_json&& val)
\r
5543 return insert(pos, val);
\r
5547 @brief inserts elements
\r
5549 Inserts @a cnt copies of @a val before iterator @a pos.
\r
5551 @param[in] pos iterator before which the content will be inserted; may be
\r
5552 the end() iterator
\r
5553 @param[in] cnt number of copies of @a val to insert
\r
5554 @param[in] val element to insert
\r
5555 @return iterator pointing to the first element inserted, or @a pos if
\r
5558 @throw std::domain_error if called on JSON values other than arrays;
\r
5559 example: `"cannot use insert() with string"`
\r
5560 @throw std::domain_error if @a pos is not an iterator of *this; example:
\r
5561 `"iterator does not fit current value"`
\r
5563 @complexity Linear in @a cnt plus linear in the distance between @a pos
\r
5564 and end of the container.
\r
5566 @liveexample{The example shows how `insert()` is used.,insert__count}
\r
5568 @since version 1.0.0
\r
5570 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
\r
5572 // insert only works for arrays
\r
5575 // check if iterator pos fits to this JSON value
\r
5576 if (pos.m_object != this)
\r
5578 JSON_THROW(std::domain_error("iterator does not fit current value"));
\r
5581 // insert to array and return iterator
\r
5582 iterator result(this);
\r
5583 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
\r
5587 JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
\r
5591 @brief inserts elements
\r
5593 Inserts elements from range `[first, last)` before iterator @a pos.
\r
5595 @param[in] pos iterator before which the content will be inserted; may be
\r
5596 the end() iterator
\r
5597 @param[in] first begin of the range of elements to insert
\r
5598 @param[in] last end of the range of elements to insert
\r
5600 @throw std::domain_error if called on JSON values other than arrays;
\r
5601 example: `"cannot use insert() with string"`
\r
5602 @throw std::domain_error if @a pos is not an iterator of *this; example:
\r
5603 `"iterator does not fit current value"`
\r
5604 @throw std::domain_error if @a first and @a last do not belong to the same
\r
5605 JSON value; example: `"iterators do not fit"`
\r
5606 @throw std::domain_error if @a first or @a last are iterators into
\r
5607 container for which insert is called; example: `"passed iterators may not
\r
5608 belong to container"`
\r
5610 @return iterator pointing to the first element inserted, or @a pos if
\r
5613 @complexity Linear in `std::distance(first, last)` plus linear in the
\r
5614 distance between @a pos and end of the container.
\r
5616 @liveexample{The example shows how `insert()` is used.,insert__range}
\r
5618 @since version 1.0.0
\r
5620 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
\r
5622 // insert only works for arrays
\r
5623 if (not is_array())
\r
5625 JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
\r
5628 // check if iterator pos fits to this JSON value
\r
5629 if (pos.m_object != this)
\r
5631 JSON_THROW(std::domain_error("iterator does not fit current value"));
\r
5634 // check if range iterators belong to the same JSON object
\r
5635 if (first.m_object != last.m_object)
\r
5637 JSON_THROW(std::domain_error("iterators do not fit"));
\r
5640 if (first.m_object == this or last.m_object == this)
\r
5642 JSON_THROW(std::domain_error("passed iterators may not belong to container"));
\r
5645 // insert to array and return iterator
\r
5646 iterator result(this);
\r
5647 result.m_it.array_iterator = m_value.array->insert(
\r
5648 pos.m_it.array_iterator,
\r
5649 first.m_it.array_iterator,
\r
5650 last.m_it.array_iterator);
\r
5655 @brief inserts elements
\r
5657 Inserts elements from initializer list @a ilist before iterator @a pos.
\r
5659 @param[in] pos iterator before which the content will be inserted; may be
\r
5660 the end() iterator
\r
5661 @param[in] ilist initializer list to insert the values from
\r
5663 @throw std::domain_error if called on JSON values other than arrays;
\r
5664 example: `"cannot use insert() with string"`
\r
5665 @throw std::domain_error if @a pos is not an iterator of *this; example:
\r
5666 `"iterator does not fit current value"`
\r
5668 @return iterator pointing to the first element inserted, or @a pos if
\r
5671 @complexity Linear in `ilist.size()` plus linear in the distance between
\r
5672 @a pos and end of the container.
\r
5674 @liveexample{The example shows how `insert()` is used.,insert__ilist}
\r
5676 @since version 1.0.0
\r
5678 iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
\r
5680 // insert only works for arrays
\r
5681 if (not is_array())
\r
5683 JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
\r
5686 // check if iterator pos fits to this JSON value
\r
5687 if (pos.m_object != this)
\r
5689 JSON_THROW(std::domain_error("iterator does not fit current value"));
\r
5692 // insert to array and return iterator
\r
5693 iterator result(this);
\r
5694 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
\r
5699 @brief exchanges the values
\r
5701 Exchanges the contents of the JSON value with those of @a other. Does not
\r
5702 invoke any move, copy, or swap operations on individual elements. All
\r
5703 iterators and references remain valid. The past-the-end iterator is
\r
5706 @param[in,out] other JSON value to exchange the contents with
\r
5708 @complexity Constant.
\r
5710 @liveexample{The example below shows how JSON values can be swapped with
\r
5711 `swap()`.,swap__reference}
\r
5713 @since version 1.0.0
\r
5715 void swap(reference other) noexcept (
\r
5716 std::is_nothrow_move_constructible<value_t>::value and
\r
5717 std::is_nothrow_move_assignable<value_t>::value and
\r
5718 std::is_nothrow_move_constructible<json_value>::value and
\r
5719 std::is_nothrow_move_assignable<json_value>::value
\r
5722 std::swap(m_type, other.m_type);
\r
5723 std::swap(m_value, other.m_value);
\r
5724 assert_invariant();
\r
5728 @brief exchanges the values
\r
5730 Exchanges the contents of a JSON array with those of @a other. Does not
\r
5731 invoke any move, copy, or swap operations on individual elements. All
\r
5732 iterators and references remain valid. The past-the-end iterator is
\r
5735 @param[in,out] other array to exchange the contents with
\r
5737 @throw std::domain_error when JSON value is not an array; example:
\r
5738 `"cannot use swap() with string"`
\r
5740 @complexity Constant.
\r
5742 @liveexample{The example below shows how arrays can be swapped with
\r
5743 `swap()`.,swap__array_t}
\r
5745 @since version 1.0.0
\r
5747 void swap(array_t& other)
\r
5749 // swap only works for arrays
\r
5752 std::swap(*(m_value.array), other);
\r
5756 JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
\r
5761 @brief exchanges the values
\r
5763 Exchanges the contents of a JSON object with those of @a other. Does not
\r
5764 invoke any move, copy, or swap operations on individual elements. All
\r
5765 iterators and references remain valid. The past-the-end iterator is
\r
5768 @param[in,out] other object to exchange the contents with
\r
5770 @throw std::domain_error when JSON value is not an object; example:
\r
5771 `"cannot use swap() with string"`
\r
5773 @complexity Constant.
\r
5775 @liveexample{The example below shows how objects can be swapped with
\r
5776 `swap()`.,swap__object_t}
\r
5778 @since version 1.0.0
\r
5780 void swap(object_t& other)
\r
5782 // swap only works for objects
\r
5785 std::swap(*(m_value.object), other);
\r
5789 JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
\r
5794 @brief exchanges the values
\r
5796 Exchanges the contents of a JSON string with those of @a other. Does not
\r
5797 invoke any move, copy, or swap operations on individual elements. All
\r
5798 iterators and references remain valid. The past-the-end iterator is
\r
5801 @param[in,out] other string to exchange the contents with
\r
5803 @throw std::domain_error when JSON value is not a string; example: `"cannot
\r
5804 use swap() with boolean"`
\r
5806 @complexity Constant.
\r
5808 @liveexample{The example below shows how strings can be swapped with
\r
5809 `swap()`.,swap__string_t}
\r
5811 @since version 1.0.0
\r
5813 void swap(string_t& other)
\r
5815 // swap only works for strings
\r
5818 std::swap(*(m_value.string), other);
\r
5822 JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
\r
5829 //////////////////////////////////////////
\r
5830 // lexicographical comparison operators //
\r
5831 //////////////////////////////////////////
\r
5833 /// @name lexicographical comparison operators
\r
5837 @brief comparison: equal
\r
5839 Compares two JSON values for equality according to the following rules:
\r
5840 - Two JSON values are equal if (1) they are from the same type and (2)
\r
5841 their stored values are the same.
\r
5842 - Integer and floating-point numbers are automatically converted before
\r
5843 comparison. Floating-point numbers are compared indirectly: two
\r
5844 floating-point numbers `f1` and `f2` are considered equal if neither
\r
5845 `f1 > f2` nor `f2 > f1` holds.
\r
5846 - Two JSON null values are equal.
\r
5848 @param[in] lhs first JSON value to consider
\r
5849 @param[in] rhs second JSON value to consider
\r
5850 @return whether the values @a lhs and @a rhs are equal
\r
5852 @complexity Linear.
\r
5854 @liveexample{The example demonstrates comparing several JSON
\r
5855 types.,operator__equal}
\r
5857 @since version 1.0.0
\r
5859 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
\r
5861 const auto lhs_type = lhs.type();
\r
5862 const auto rhs_type = rhs.type();
\r
5864 if (lhs_type == rhs_type)
\r
5868 case value_t::array:
\r
5870 return *lhs.m_value.array == *rhs.m_value.array;
\r
5872 case value_t::object:
\r
5874 return *lhs.m_value.object == *rhs.m_value.object;
\r
5876 case value_t::null:
\r
5880 case value_t::string:
\r
5882 return *lhs.m_value.string == *rhs.m_value.string;
\r
5884 case value_t::boolean:
\r
5886 return lhs.m_value.boolean == rhs.m_value.boolean;
\r
5888 case value_t::number_integer:
\r
5890 return lhs.m_value.number_integer == rhs.m_value.number_integer;
\r
5892 case value_t::number_unsigned:
\r
5894 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
\r
5896 case value_t::number_float:
\r
5898 return lhs.m_value.number_float == rhs.m_value.number_float;
\r
5906 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
\r
5908 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
\r
5910 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
\r
5912 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
\r
5914 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
\r
5916 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
\r
5918 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
\r
5920 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
\r
5922 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
\r
5924 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
\r
5926 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
\r
5928 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
\r
5935 @brief comparison: equal
\r
5936 @copydoc operator==(const_reference, const_reference)
\r
5938 template<typename ScalarType, typename std::enable_if<
\r
5939 std::is_scalar<ScalarType>::value, int>::type = 0>
\r
5940 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
\r
5942 return (lhs == basic_json(rhs));
\r
5946 @brief comparison: equal
\r
5947 @copydoc operator==(const_reference, const_reference)
\r
5949 template<typename ScalarType, typename std::enable_if<
\r
5950 std::is_scalar<ScalarType>::value, int>::type = 0>
\r
5951 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
\r
5953 return (basic_json(lhs) == rhs);
\r
5957 @brief comparison: not equal
\r
5959 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
\r
5961 @param[in] lhs first JSON value to consider
\r
5962 @param[in] rhs second JSON value to consider
\r
5963 @return whether the values @a lhs and @a rhs are not equal
\r
5965 @complexity Linear.
\r
5967 @liveexample{The example demonstrates comparing several JSON
\r
5968 types.,operator__notequal}
\r
5970 @since version 1.0.0
\r
5972 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
\r
5974 return not (lhs == rhs);
\r
5978 @brief comparison: not equal
\r
5979 @copydoc operator!=(const_reference, const_reference)
\r
5981 template<typename ScalarType, typename std::enable_if<
\r
5982 std::is_scalar<ScalarType>::value, int>::type = 0>
\r
5983 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
\r
5985 return (lhs != basic_json(rhs));
\r
5989 @brief comparison: not equal
\r
5990 @copydoc operator!=(const_reference, const_reference)
\r
5992 template<typename ScalarType, typename std::enable_if<
\r
5993 std::is_scalar<ScalarType>::value, int>::type = 0>
\r
5994 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
\r
5996 return (basic_json(lhs) != rhs);
\r
6000 @brief comparison: less than
\r
6002 Compares whether one JSON value @a lhs is less than another JSON value @a
\r
6003 rhs according to the following rules:
\r
6004 - If @a lhs and @a rhs have the same type, the values are compared using
\r
6005 the default `<` operator.
\r
6006 - Integer and floating-point numbers are automatically converted before
\r
6008 - In case @a lhs and @a rhs have different types, the values are ignored
\r
6009 and the order of the types is considered, see
\r
6010 @ref operator<(const value_t, const value_t).
\r
6012 @param[in] lhs first JSON value to consider
\r
6013 @param[in] rhs second JSON value to consider
\r
6014 @return whether @a lhs is less than @a rhs
\r
6016 @complexity Linear.
\r
6018 @liveexample{The example demonstrates comparing several JSON
\r
6019 types.,operator__less}
\r
6021 @since version 1.0.0
\r
6023 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
\r
6025 const auto lhs_type = lhs.type();
\r
6026 const auto rhs_type = rhs.type();
\r
6028 if (lhs_type == rhs_type)
\r
6032 case value_t::array:
\r
6034 return *lhs.m_value.array < *rhs.m_value.array;
\r
6036 case value_t::object:
\r
6038 return *lhs.m_value.object < *rhs.m_value.object;
\r
6040 case value_t::null:
\r
6044 case value_t::string:
\r
6046 return *lhs.m_value.string < *rhs.m_value.string;
\r
6048 case value_t::boolean:
\r
6050 return lhs.m_value.boolean < rhs.m_value.boolean;
\r
6052 case value_t::number_integer:
\r
6054 return lhs.m_value.number_integer < rhs.m_value.number_integer;
\r
6056 case value_t::number_unsigned:
\r
6058 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
\r
6060 case value_t::number_float:
\r
6062 return lhs.m_value.number_float < rhs.m_value.number_float;
\r
6070 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
\r
6072 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
\r
6074 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
\r
6076 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
\r
6078 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
\r
6080 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
\r
6082 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
\r
6084 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
\r
6086 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
\r
6088 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
\r
6090 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
\r
6092 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
\r
6095 // We only reach this line if we cannot compare values. In that case,
\r
6096 // we compare types. Note we have to call the operator explicitly,
\r
6097 // because MSVC has problems otherwise.
\r
6098 return operator<(lhs_type, rhs_type);
\r
6102 @brief comparison: less than or equal
\r
6104 Compares whether one JSON value @a lhs is less than or equal to another
\r
6105 JSON value by calculating `not (rhs < lhs)`.
\r
6107 @param[in] lhs first JSON value to consider
\r
6108 @param[in] rhs second JSON value to consider
\r
6109 @return whether @a lhs is less than or equal to @a rhs
\r
6111 @complexity Linear.
\r
6113 @liveexample{The example demonstrates comparing several JSON
\r
6114 types.,operator__greater}
\r
6116 @since version 1.0.0
\r
6118 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
\r
6120 return not (rhs < lhs);
\r
6124 @brief comparison: greater than
\r
6126 Compares whether one JSON value @a lhs is greater than another
\r
6127 JSON value by calculating `not (lhs <= rhs)`.
\r
6129 @param[in] lhs first JSON value to consider
\r
6130 @param[in] rhs second JSON value to consider
\r
6131 @return whether @a lhs is greater than to @a rhs
\r
6133 @complexity Linear.
\r
6135 @liveexample{The example demonstrates comparing several JSON
\r
6136 types.,operator__lessequal}
\r
6138 @since version 1.0.0
\r
6140 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
\r
6142 return not (lhs <= rhs);
\r
6146 @brief comparison: greater than or equal
\r
6148 Compares whether one JSON value @a lhs is greater than or equal to another
\r
6149 JSON value by calculating `not (lhs < rhs)`.
\r
6151 @param[in] lhs first JSON value to consider
\r
6152 @param[in] rhs second JSON value to consider
\r
6153 @return whether @a lhs is greater than or equal to @a rhs
\r
6155 @complexity Linear.
\r
6157 @liveexample{The example demonstrates comparing several JSON
\r
6158 types.,operator__greaterequal}
\r
6160 @since version 1.0.0
\r
6162 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
\r
6164 return not (lhs < rhs);
\r
6170 ///////////////////
\r
6171 // serialization //
\r
6172 ///////////////////
\r
6174 /// @name serialization
\r
6178 @brief serialize to stream
\r
6180 Serialize the given JSON value @a j to the output stream @a o. The JSON
\r
6181 value will be serialized using the @ref dump member function. The
\r
6182 indentation of the output can be controlled with the member variable
\r
6183 `width` of the output stream @a o. For instance, using the manipulator
\r
6184 `std::setw(4)` on @a o sets the indentation level to `4` and the
\r
6185 serialization result is the same as calling `dump(4)`.
\r
6187 @param[in,out] o stream to serialize to
\r
6188 @param[in] j JSON value to serialize
\r
6190 @return the stream @a o
\r
6192 @complexity Linear.
\r
6194 @liveexample{The example below shows the serialization with different
\r
6195 parameters to `width` to adjust the indentation level.,operator_serialize}
\r
6197 @since version 1.0.0
\r
6199 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
\r
6201 // read width member and use it as indentation parameter if nonzero
\r
6202 const bool pretty_print = (o.width() > 0);
\r
6203 const auto indentation = (pretty_print ? o.width() : 0);
\r
6205 // reset width to 0 for subsequent calls to this stream
\r
6208 // do the actual serialization
\r
6209 j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
\r
6215 @brief serialize to stream
\r
6216 @copydoc operator<<(std::ostream&, const basic_json&)
\r
6218 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
\r
6226 /////////////////////
\r
6227 // deserialization //
\r
6228 /////////////////////
\r
6230 /// @name deserialization
\r
6234 @brief deserialize from an array
\r
6236 This function reads from an array of 1-byte values.
\r
6238 @pre Each element of the container has a size of 1 byte. Violating this
\r
6239 precondition yields undefined behavior. **This precondition is enforced
\r
6240 with a static assertion.**
\r
6242 @param[in] array array to read from
\r
6243 @param[in] cb a parser callback function of type @ref parser_callback_t
\r
6244 which is used to control the deserialization by filtering unwanted values
\r
6247 @return result of the deserialization
\r
6249 @complexity Linear in the length of the input. The parser is a predictive
\r
6250 LL(1) parser. The complexity can be higher if the parser callback function
\r
6251 @a cb has a super-linear complexity.
\r
6253 @note A UTF-8 byte order mark is silently ignored.
\r
6255 @liveexample{The example below demonstrates the `parse()` function reading
\r
6256 from an array.,parse__array__parser_callback_t}
\r
6258 @since version 2.0.3
\r
6260 template<class T, std::size_t N>
\r
6261 static basic_json parse(T (&array)[N],
\r
6262 const parser_callback_t cb = nullptr)
\r
6264 // delegate the call to the iterator-range parse overload
\r
6265 return parse(std::begin(array), std::end(array), cb);
\r
6269 @brief deserialize from string literal
\r
6271 @tparam CharT character/literal type with size of 1 byte
\r
6272 @param[in] s string literal to read a serialized JSON value from
\r
6273 @param[in] cb a parser callback function of type @ref parser_callback_t
\r
6274 which is used to control the deserialization by filtering unwanted values
\r
6277 @return result of the deserialization
\r
6279 @complexity Linear in the length of the input. The parser is a predictive
\r
6280 LL(1) parser. The complexity can be higher if the parser callback function
\r
6281 @a cb has a super-linear complexity.
\r
6283 @note A UTF-8 byte order mark is silently ignored.
\r
6284 @note String containers like `std::string` or @ref string_t can be parsed
\r
6285 with @ref parse(const ContiguousContainer&, const parser_callback_t)
\r
6287 @liveexample{The example below demonstrates the `parse()` function with
\r
6288 and without callback function.,parse__string__parser_callback_t}
\r
6290 @sa @ref parse(std::istream&, const parser_callback_t) for a version that
\r
6291 reads from an input stream
\r
6293 @since version 1.0.0 (originally for @ref string_t)
\r
6295 template<typename CharT, typename std::enable_if<
\r
6296 std::is_pointer<CharT>::value and
\r
6297 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
\r
6298 sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
\r
6299 static basic_json parse(const CharT s,
\r
6300 const parser_callback_t cb = nullptr)
\r
6302 return parser(reinterpret_cast<const char*>(s), cb).parse();
\r
6306 @brief deserialize from stream
\r
6308 @param[in,out] i stream to read a serialized JSON value from
\r
6309 @param[in] cb a parser callback function of type @ref parser_callback_t
\r
6310 which is used to control the deserialization by filtering unwanted values
\r
6313 @return result of the deserialization
\r
6315 @complexity Linear in the length of the input. The parser is a predictive
\r
6316 LL(1) parser. The complexity can be higher if the parser callback function
\r
6317 @a cb has a super-linear complexity.
\r
6319 @note A UTF-8 byte order mark is silently ignored.
\r
6321 @liveexample{The example below demonstrates the `parse()` function with
\r
6322 and without callback function.,parse__istream__parser_callback_t}
\r
6324 @sa @ref parse(const CharT, const parser_callback_t) for a version
\r
6325 that reads from a string
\r
6327 @since version 1.0.0
\r
6329 static basic_json parse(std::istream& i,
\r
6330 const parser_callback_t cb = nullptr)
\r
6332 return parser(i, cb).parse();
\r
6336 @copydoc parse(std::istream&, const parser_callback_t)
\r
6338 static basic_json parse(std::istream&& i,
\r
6339 const parser_callback_t cb = nullptr)
\r
6341 return parser(i, cb).parse();
\r
6345 @brief deserialize from an iterator range with contiguous storage
\r
6347 This function reads from an iterator range of a container with contiguous
\r
6348 storage of 1-byte values. Compatible container types include
\r
6349 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
\r
6350 `std::initializer_list`. Furthermore, C-style arrays can be used with
\r
6351 `std::begin()`/`std::end()`. User-defined containers can be used as long
\r
6352 as they implement random-access iterators and a contiguous storage.
\r
6354 @pre The iterator range is contiguous. Violating this precondition yields
\r
6355 undefined behavior. **This precondition is enforced with an assertion.**
\r
6356 @pre Each element in the range has a size of 1 byte. Violating this
\r
6357 precondition yields undefined behavior. **This precondition is enforced
\r
6358 with a static assertion.**
\r
6360 @warning There is no way to enforce all preconditions at compile-time. If
\r
6361 the function is called with noncompliant iterators and with
\r
6362 assertions switched off, the behavior is undefined and will most
\r
6363 likely yield segmentation violation.
\r
6365 @tparam IteratorType iterator of container with contiguous storage
\r
6366 @param[in] first begin of the range to parse (included)
\r
6367 @param[in] last end of the range to parse (excluded)
\r
6368 @param[in] cb a parser callback function of type @ref parser_callback_t
\r
6369 which is used to control the deserialization by filtering unwanted values
\r
6372 @return result of the deserialization
\r
6374 @complexity Linear in the length of the input. The parser is a predictive
\r
6375 LL(1) parser. The complexity can be higher if the parser callback function
\r
6376 @a cb has a super-linear complexity.
\r
6378 @note A UTF-8 byte order mark is silently ignored.
\r
6380 @liveexample{The example below demonstrates the `parse()` function reading
\r
6381 from an iterator range.,parse__iteratortype__parser_callback_t}
\r
6383 @since version 2.0.3
\r
6385 template<class IteratorType, typename std::enable_if<
\r
6387 std::random_access_iterator_tag,
\r
6388 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
\r
6389 static basic_json parse(IteratorType first, IteratorType last,
\r
6390 const parser_callback_t cb = nullptr)
\r
6392 // assertion to check that the iterator range is indeed contiguous,
\r
6393 // see http://stackoverflow.com/a/35008842/266378 for more discussion
\r
6394 assert(std::accumulate(first, last, std::pair<bool, int>(true, 0),
\r
6395 [&first](std::pair<bool, int> res, decltype(*first) val)
\r
6397 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
\r
6401 // assertion to check that each element is 1 byte long
\r
6402 static_assert(sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
\r
6403 "each element in the iterator range must have the size of 1 byte");
\r
6405 // if iterator range is empty, create a parser with an empty string
\r
6406 // to generate "unexpected EOF" error message
\r
6407 if (std::distance(first, last) <= 0)
\r
6409 return parser("").parse();
\r
6412 return parser(first, last, cb).parse();
\r
6416 @brief deserialize from a container with contiguous storage
\r
6418 This function reads from a container with contiguous storage of 1-byte
\r
6419 values. Compatible container types include `std::vector`, `std::string`,
\r
6420 `std::array`, and `std::initializer_list`. User-defined containers can be
\r
6421 used as long as they implement random-access iterators and a contiguous
\r
6424 @pre The container storage is contiguous. Violating this precondition
\r
6425 yields undefined behavior. **This precondition is enforced with an
\r
6427 @pre Each element of the container has a size of 1 byte. Violating this
\r
6428 precondition yields undefined behavior. **This precondition is enforced
\r
6429 with a static assertion.**
\r
6431 @warning There is no way to enforce all preconditions at compile-time. If
\r
6432 the function is called with a noncompliant container and with
\r
6433 assertions switched off, the behavior is undefined and will most
\r
6434 likely yield segmentation violation.
\r
6436 @tparam ContiguousContainer container type with contiguous storage
\r
6437 @param[in] c container to read from
\r
6438 @param[in] cb a parser callback function of type @ref parser_callback_t
\r
6439 which is used to control the deserialization by filtering unwanted values
\r
6442 @return result of the deserialization
\r
6444 @complexity Linear in the length of the input. The parser is a predictive
\r
6445 LL(1) parser. The complexity can be higher if the parser callback function
\r
6446 @a cb has a super-linear complexity.
\r
6448 @note A UTF-8 byte order mark is silently ignored.
\r
6450 @liveexample{The example below demonstrates the `parse()` function reading
\r
6451 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
\r
6453 @since version 2.0.3
\r
6455 template<class ContiguousContainer, typename std::enable_if<
\r
6456 not std::is_pointer<ContiguousContainer>::value and
\r
6458 std::random_access_iterator_tag,
\r
6459 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
\r
6461 static basic_json parse(const ContiguousContainer& c,
\r
6462 const parser_callback_t cb = nullptr)
\r
6464 // delegate the call to the iterator-range parse overload
\r
6465 return parse(std::begin(c), std::end(c), cb);
\r
6469 @brief deserialize from stream
\r
6471 Deserializes an input stream to a JSON value.
\r
6473 @param[in,out] i input stream to read a serialized JSON value from
\r
6474 @param[in,out] j JSON value to write the deserialized input to
\r
6476 @throw std::invalid_argument in case of parse errors
\r
6478 @complexity Linear in the length of the input. The parser is a predictive
\r
6481 @note A UTF-8 byte order mark is silently ignored.
\r
6483 @liveexample{The example below shows how a JSON value is constructed by
\r
6484 reading a serialization from a stream.,operator_deserialize}
\r
6486 @sa parse(std::istream&, const parser_callback_t) for a variant with a
\r
6487 parser callback function to filter values while parsing
\r
6489 @since version 1.0.0
\r
6491 friend std::istream& operator<<(basic_json& j, std::istream& i)
\r
6493 j = parser(i).parse();
\r
6498 @brief deserialize from stream
\r
6499 @copydoc operator<<(basic_json&, std::istream&)
\r
6501 friend std::istream& operator>>(std::istream& i, basic_json& j)
\r
6503 j = parser(i).parse();
\r
6509 //////////////////////////////////////////
\r
6510 // binary serialization/deserialization //
\r
6511 //////////////////////////////////////////
\r
6513 /// @name binary serialization/deserialization support
\r
6518 @note Some code in the switch cases has been copied, because otherwise
\r
6519 copilers would complain about implicit fallthrough and there is no
\r
6520 portable attribute to mute such warnings.
\r
6522 template<typename T>
\r
6523 static void add_to_vector(std::vector<uint8_t>& vec, size_t bytes, const T number)
\r
6525 assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8);
\r
6531 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 070) & 0xff));
\r
6532 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 060) & 0xff));
\r
6533 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 050) & 0xff));
\r
6534 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 040) & 0xff));
\r
6535 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
\r
6536 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
\r
6537 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
\r
6538 vec.push_back(static_cast<uint8_t>(number & 0xff));
\r
6544 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
\r
6545 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
\r
6546 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
\r
6547 vec.push_back(static_cast<uint8_t>(number & 0xff));
\r
6553 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
\r
6554 vec.push_back(static_cast<uint8_t>(number & 0xff));
\r
6560 vec.push_back(static_cast<uint8_t>(number & 0xff));
\r
6567 @brief take sufficient bytes from a vector to fill an integer variable
\r
6569 In the context of binary serialization formats, we need to read several
\r
6570 bytes from a byte vector and combine them to multi-byte integral data
\r
6573 @param[in] vec byte vector to read from
\r
6574 @param[in] current_index the position in the vector after which to read
\r
6576 @return the next sizeof(T) bytes from @a vec, in reverse order as T
\r
6578 @tparam T the integral return type
\r
6580 @throw std::out_of_range if there are less than sizeof(T)+1 bytes in the
\r
6581 vector @a vec to read
\r
6583 In the for loop, the bytes from the vector are copied in reverse order into
\r
6584 the return value. In the figures below, let sizeof(T)=4 and `i` be the loop
\r
6589 vec: | | | a | b | c | d | T: | | | | |
\r
6591 current_index i ptr sizeof(T)
\r
6595 vec: | | | a | b | c | d | T: | d | c | b | a |
\r
6600 @sa Code adapted from <http://stackoverflow.com/a/41031865/266378>.
\r
6602 template<typename T>
\r
6603 static T get_from_vector(const std::vector<uint8_t>& vec, const size_t current_index)
\r
6605 if (current_index + sizeof(T) + 1 > vec.size())
\r
6607 JSON_THROW(std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector"));
\r
6611 auto* ptr = reinterpret_cast<uint8_t*>(&result);
\r
6612 for (size_t i = 0; i < sizeof(T); ++i)
\r
6614 *ptr++ = vec[current_index + sizeof(T) - i];
\r
6620 @brief create a MessagePack serialization of a given JSON value
\r
6622 This is a straightforward implementation of the MessagePack specification.
\r
6624 @param[in] j JSON value to serialize
\r
6625 @param[in,out] v byte vector to write the serialization to
\r
6627 @sa https://github.com/msgpack/msgpack/blob/master/spec.md
\r
6629 static void to_msgpack_internal(const basic_json& j, std::vector<uint8_t>& v)
\r
6633 case value_t::null:
\r
6636 v.push_back(0xc0);
\r
6640 case value_t::boolean:
\r
6643 v.push_back(j.m_value.boolean ? 0xc3 : 0xc2);
\r
6647 case value_t::number_integer:
\r
6649 if (j.m_value.number_integer >= 0)
\r
6651 // MessagePack does not differentiate between positive
\r
6652 // signed integers and unsigned integers. Therefore, we
\r
6653 // used the code from the value_t::number_unsigned case
\r
6655 if (j.m_value.number_unsigned < 128)
\r
6657 // positive fixnum
\r
6658 add_to_vector(v, 1, j.m_value.number_unsigned);
\r
6660 else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
\r
6663 v.push_back(0xcc);
\r
6664 add_to_vector(v, 1, j.m_value.number_unsigned);
\r
6666 else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
\r
6669 v.push_back(0xcd);
\r
6670 add_to_vector(v, 2, j.m_value.number_unsigned);
\r
6672 else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
\r
6675 v.push_back(0xce);
\r
6676 add_to_vector(v, 4, j.m_value.number_unsigned);
\r
6678 else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
\r
6681 v.push_back(0xcf);
\r
6682 add_to_vector(v, 8, j.m_value.number_unsigned);
\r
6687 if (j.m_value.number_integer >= -32)
\r
6689 // negative fixnum
\r
6690 add_to_vector(v, 1, j.m_value.number_integer);
\r
6692 else if (j.m_value.number_integer >= std::numeric_limits<int8_t>::min() and j.m_value.number_integer <= std::numeric_limits<int8_t>::max())
\r
6695 v.push_back(0xd0);
\r
6696 add_to_vector(v, 1, j.m_value.number_integer);
\r
6698 else if (j.m_value.number_integer >= std::numeric_limits<int16_t>::min() and j.m_value.number_integer <= std::numeric_limits<int16_t>::max())
\r
6701 v.push_back(0xd1);
\r
6702 add_to_vector(v, 2, j.m_value.number_integer);
\r
6704 else if (j.m_value.number_integer >= std::numeric_limits<int32_t>::min() and j.m_value.number_integer <= std::numeric_limits<int32_t>::max())
\r
6707 v.push_back(0xd2);
\r
6708 add_to_vector(v, 4, j.m_value.number_integer);
\r
6710 else if (j.m_value.number_integer >= std::numeric_limits<int64_t>::min() and j.m_value.number_integer <= std::numeric_limits<int64_t>::max())
\r
6713 v.push_back(0xd3);
\r
6714 add_to_vector(v, 8, j.m_value.number_integer);
\r
6720 case value_t::number_unsigned:
\r
6722 if (j.m_value.number_unsigned < 128)
\r
6724 // positive fixnum
\r
6725 add_to_vector(v, 1, j.m_value.number_unsigned);
\r
6727 else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
\r
6730 v.push_back(0xcc);
\r
6731 add_to_vector(v, 1, j.m_value.number_unsigned);
\r
6733 else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
\r
6736 v.push_back(0xcd);
\r
6737 add_to_vector(v, 2, j.m_value.number_unsigned);
\r
6739 else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
\r
6742 v.push_back(0xce);
\r
6743 add_to_vector(v, 4, j.m_value.number_unsigned);
\r
6745 else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
\r
6748 v.push_back(0xcf);
\r
6749 add_to_vector(v, 8, j.m_value.number_unsigned);
\r
6754 case value_t::number_float:
\r
6757 v.push_back(0xcb);
\r
6758 const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
\r
6759 for (size_t i = 0; i < 8; ++i)
\r
6761 v.push_back(helper[7 - i]);
\r
6766 case value_t::string:
\r
6768 const auto N = j.m_value.string->size();
\r
6772 v.push_back(static_cast<uint8_t>(0xa0 | N));
\r
6774 else if (N <= 255)
\r
6777 v.push_back(0xd9);
\r
6778 add_to_vector(v, 1, N);
\r
6780 else if (N <= 65535)
\r
6783 v.push_back(0xda);
\r
6784 add_to_vector(v, 2, N);
\r
6786 else if (N <= 4294967295)
\r
6789 v.push_back(0xdb);
\r
6790 add_to_vector(v, 4, N);
\r
6794 std::copy(j.m_value.string->begin(), j.m_value.string->end(),
\r
6795 std::back_inserter(v));
\r
6799 case value_t::array:
\r
6801 const auto N = j.m_value.array->size();
\r
6805 v.push_back(static_cast<uint8_t>(0x90 | N));
\r
6807 else if (N <= 0xffff)
\r
6810 v.push_back(0xdc);
\r
6811 add_to_vector(v, 2, N);
\r
6813 else if (N <= 0xffffffff)
\r
6816 v.push_back(0xdd);
\r
6817 add_to_vector(v, 4, N);
\r
6820 // append each element
\r
6821 for (const auto& el : *j.m_value.array)
\r
6823 to_msgpack_internal(el, v);
\r
6828 case value_t::object:
\r
6830 const auto N = j.m_value.object->size();
\r
6834 v.push_back(static_cast<uint8_t>(0x80 | (N & 0xf)));
\r
6836 else if (N <= 65535)
\r
6839 v.push_back(0xde);
\r
6840 add_to_vector(v, 2, N);
\r
6842 else if (N <= 4294967295)
\r
6845 v.push_back(0xdf);
\r
6846 add_to_vector(v, 4, N);
\r
6849 // append each element
\r
6850 for (const auto& el : *j.m_value.object)
\r
6852 to_msgpack_internal(el.first, v);
\r
6853 to_msgpack_internal(el.second, v);
\r
6866 @brief create a CBOR serialization of a given JSON value
\r
6868 This is a straightforward implementation of the CBOR specification.
\r
6870 @param[in] j JSON value to serialize
\r
6871 @param[in,out] v byte vector to write the serialization to
\r
6873 @sa https://tools.ietf.org/html/rfc7049
\r
6875 static void to_cbor_internal(const basic_json& j, std::vector<uint8_t>& v)
\r
6879 case value_t::null:
\r
6881 v.push_back(0xf6);
\r
6885 case value_t::boolean:
\r
6887 v.push_back(j.m_value.boolean ? 0xf5 : 0xf4);
\r
6891 case value_t::number_integer:
\r
6893 if (j.m_value.number_integer >= 0)
\r
6895 // CBOR does not differentiate between positive signed
\r
6896 // integers and unsigned integers. Therefore, we used the
\r
6897 // code from the value_t::number_unsigned case here.
\r
6898 if (j.m_value.number_integer <= 0x17)
\r
6900 add_to_vector(v, 1, j.m_value.number_integer);
\r
6902 else if (j.m_value.number_integer <= std::numeric_limits<uint8_t>::max())
\r
6904 v.push_back(0x18);
\r
6905 // one-byte uint8_t
\r
6906 add_to_vector(v, 1, j.m_value.number_integer);
\r
6908 else if (j.m_value.number_integer <= std::numeric_limits<uint16_t>::max())
\r
6910 v.push_back(0x19);
\r
6911 // two-byte uint16_t
\r
6912 add_to_vector(v, 2, j.m_value.number_integer);
\r
6914 else if (j.m_value.number_integer <= std::numeric_limits<uint32_t>::max())
\r
6916 v.push_back(0x1a);
\r
6917 // four-byte uint32_t
\r
6918 add_to_vector(v, 4, j.m_value.number_integer);
\r
6922 v.push_back(0x1b);
\r
6923 // eight-byte uint64_t
\r
6924 add_to_vector(v, 8, j.m_value.number_integer);
\r
6929 // The conversions below encode the sign in the first
\r
6930 // byte, and the value is converted to a positive number.
\r
6931 const auto positive_number = -1 - j.m_value.number_integer;
\r
6932 if (j.m_value.number_integer >= -24)
\r
6934 v.push_back(static_cast<uint8_t>(0x20 + positive_number));
\r
6936 else if (positive_number <= std::numeric_limits<uint8_t>::max())
\r
6939 v.push_back(0x38);
\r
6940 add_to_vector(v, 1, positive_number);
\r
6942 else if (positive_number <= std::numeric_limits<uint16_t>::max())
\r
6945 v.push_back(0x39);
\r
6946 add_to_vector(v, 2, positive_number);
\r
6948 else if (positive_number <= std::numeric_limits<uint32_t>::max())
\r
6951 v.push_back(0x3a);
\r
6952 add_to_vector(v, 4, positive_number);
\r
6957 v.push_back(0x3b);
\r
6958 add_to_vector(v, 8, positive_number);
\r
6964 case value_t::number_unsigned:
\r
6966 if (j.m_value.number_unsigned <= 0x17)
\r
6968 v.push_back(static_cast<uint8_t>(j.m_value.number_unsigned));
\r
6970 else if (j.m_value.number_unsigned <= 0xff)
\r
6972 v.push_back(0x18);
\r
6973 // one-byte uint8_t
\r
6974 add_to_vector(v, 1, j.m_value.number_unsigned);
\r
6976 else if (j.m_value.number_unsigned <= 0xffff)
\r
6978 v.push_back(0x19);
\r
6979 // two-byte uint16_t
\r
6980 add_to_vector(v, 2, j.m_value.number_unsigned);
\r
6982 else if (j.m_value.number_unsigned <= 0xffffffff)
\r
6984 v.push_back(0x1a);
\r
6985 // four-byte uint32_t
\r
6986 add_to_vector(v, 4, j.m_value.number_unsigned);
\r
6988 else if (j.m_value.number_unsigned <= 0xffffffffffffffff)
\r
6990 v.push_back(0x1b);
\r
6991 // eight-byte uint64_t
\r
6992 add_to_vector(v, 8, j.m_value.number_unsigned);
\r
6997 case value_t::number_float:
\r
6999 // Double-Precision Float
\r
7000 v.push_back(0xfb);
\r
7001 const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
\r
7002 for (size_t i = 0; i < 8; ++i)
\r
7004 v.push_back(helper[7 - i]);
\r
7009 case value_t::string:
\r
7011 const auto N = j.m_value.string->size();
\r
7014 v.push_back(0x60 + static_cast<uint8_t>(N)); // 1 byte for string + size
\r
7016 else if (N <= 0xff)
\r
7018 v.push_back(0x78); // one-byte uint8_t for N
\r
7019 add_to_vector(v, 1, N);
\r
7021 else if (N <= 0xffff)
\r
7023 v.push_back(0x79); // two-byte uint16_t for N
\r
7024 add_to_vector(v, 2, N);
\r
7026 else if (N <= 0xffffffff)
\r
7028 v.push_back(0x7a); // four-byte uint32_t for N
\r
7029 add_to_vector(v, 4, N);
\r
7031 // LCOV_EXCL_START
\r
7032 else if (N <= 0xffffffffffffffff)
\r
7034 v.push_back(0x7b); // eight-byte uint64_t for N
\r
7035 add_to_vector(v, 8, N);
\r
7040 std::copy(j.m_value.string->begin(), j.m_value.string->end(),
\r
7041 std::back_inserter(v));
\r
7045 case value_t::array:
\r
7047 const auto N = j.m_value.array->size();
\r
7050 v.push_back(0x80 + static_cast<uint8_t>(N)); // 1 byte for array + size
\r
7052 else if (N <= 0xff)
\r
7054 v.push_back(0x98); // one-byte uint8_t for N
\r
7055 add_to_vector(v, 1, N);
\r
7057 else if (N <= 0xffff)
\r
7059 v.push_back(0x99); // two-byte uint16_t for N
\r
7060 add_to_vector(v, 2, N);
\r
7062 else if (N <= 0xffffffff)
\r
7064 v.push_back(0x9a); // four-byte uint32_t for N
\r
7065 add_to_vector(v, 4, N);
\r
7067 // LCOV_EXCL_START
\r
7068 else if (N <= 0xffffffffffffffff)
\r
7070 v.push_back(0x9b); // eight-byte uint64_t for N
\r
7071 add_to_vector(v, 8, N);
\r
7075 // append each element
\r
7076 for (const auto& el : *j.m_value.array)
\r
7078 to_cbor_internal(el, v);
\r
7083 case value_t::object:
\r
7085 const auto N = j.m_value.object->size();
\r
7088 v.push_back(0xa0 + static_cast<uint8_t>(N)); // 1 byte for object + size
\r
7090 else if (N <= 0xff)
\r
7092 v.push_back(0xb8);
\r
7093 add_to_vector(v, 1, N); // one-byte uint8_t for N
\r
7095 else if (N <= 0xffff)
\r
7097 v.push_back(0xb9);
\r
7098 add_to_vector(v, 2, N); // two-byte uint16_t for N
\r
7100 else if (N <= 0xffffffff)
\r
7102 v.push_back(0xba);
\r
7103 add_to_vector(v, 4, N); // four-byte uint32_t for N
\r
7105 // LCOV_EXCL_START
\r
7106 else if (N <= 0xffffffffffffffff)
\r
7108 v.push_back(0xbb);
\r
7109 add_to_vector(v, 8, N); // eight-byte uint64_t for N
\r
7113 // append each element
\r
7114 for (const auto& el : *j.m_value.object)
\r
7116 to_cbor_internal(el.first, v);
\r
7117 to_cbor_internal(el.second, v);
\r
7131 @brief checks if given lengths do not exceed the size of a given vector
\r
7133 To secure the access to the byte vector during CBOR/MessagePack
\r
7134 deserialization, bytes are copied from the vector into buffers. This
\r
7135 function checks if the number of bytes to copy (@a len) does not exceed
\r
7136 the size @s size of the vector. Additionally, an @a offset is given from
\r
7137 where to start reading the bytes.
\r
7139 This function checks whether reading the bytes is safe; that is, offset is
\r
7140 a valid index in the vector, offset+len
\r
7142 @param[in] size size of the byte vector
\r
7143 @param[in] len number of bytes to read
\r
7144 @param[in] offset offset where to start reading
\r
7146 vec: x x x x x X X X X X
\r
7150 @throws out_of_range if `len > v.size()`
\r
7152 static void check_length(const size_t size, const size_t len, const size_t offset)
\r
7154 // simple case: requested length is greater than the vector's length
\r
7155 if (len > size or offset > size)
\r
7157 JSON_THROW(std::out_of_range("len out of range"));
\r
7160 // second case: adding offset would result in overflow
\r
7161 if ((size > (std::numeric_limits<size_t>::max() - offset)))
\r
7163 JSON_THROW(std::out_of_range("len+offset out of range"));
\r
7166 // last case: reading past the end of the vector
\r
7167 if (len + offset > size)
\r
7169 JSON_THROW(std::out_of_range("len+offset out of range"));
\r
7174 @brief create a JSON value from a given MessagePack vector
\r
7176 @param[in] v MessagePack serialization
\r
7177 @param[in] idx byte index to start reading from @a v
\r
7179 @return deserialized JSON value
\r
7181 @throw std::invalid_argument if unsupported features from MessagePack were
\r
7182 used in the given vector @a v or if the input is not valid MessagePack
\r
7183 @throw std::out_of_range if the given vector ends prematurely
\r
7185 @sa https://github.com/msgpack/msgpack/blob/master/spec.md
\r
7187 static basic_json from_msgpack_internal(const std::vector<uint8_t>& v, size_t& idx)
\r
7189 // make sure reading 1 byte is safe
\r
7190 check_length(v.size(), 1, idx);
\r
7192 // store and increment index
\r
7193 const size_t current_idx = idx++;
\r
7195 if (v[current_idx] <= 0xbf)
\r
7197 if (v[current_idx] <= 0x7f) // positive fixint
\r
7199 return v[current_idx];
\r
7201 if (v[current_idx] <= 0x8f) // fixmap
\r
7203 basic_json result = value_t::object;
\r
7204 const size_t len = v[current_idx] & 0x0f;
\r
7205 for (size_t i = 0; i < len; ++i)
\r
7207 std::string key = from_msgpack_internal(v, idx);
\r
7208 result[key] = from_msgpack_internal(v, idx);
\r
7212 else if (v[current_idx] <= 0x9f) // fixarray
\r
7214 basic_json result = value_t::array;
\r
7215 const size_t len = v[current_idx] & 0x0f;
\r
7216 for (size_t i = 0; i < len; ++i)
\r
7218 result.push_back(from_msgpack_internal(v, idx));
\r
7224 const size_t len = v[current_idx] & 0x1f;
\r
7225 const size_t offset = current_idx + 1;
\r
7226 idx += len; // skip content bytes
\r
7227 check_length(v.size(), len, offset);
\r
7228 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7231 else if (v[current_idx] >= 0xe0) // negative fixint
\r
7233 return static_cast<int8_t>(v[current_idx]);
\r
7237 switch (v[current_idx])
\r
7241 return value_t::null;
\r
7244 case 0xc2: // false
\r
7249 case 0xc3: // true
\r
7254 case 0xca: // float 32
\r
7256 // copy bytes in reverse order into the double variable
\r
7258 for (size_t byte = 0; byte < sizeof(float); ++byte)
\r
7260 reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
\r
7262 idx += sizeof(float); // skip content bytes
\r
7266 case 0xcb: // float 64
\r
7268 // copy bytes in reverse order into the double variable
\r
7270 for (size_t byte = 0; byte < sizeof(double); ++byte)
\r
7272 reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
\r
7274 idx += sizeof(double); // skip content bytes
\r
7278 case 0xcc: // uint 8
\r
7280 idx += 1; // skip content byte
\r
7281 return get_from_vector<uint8_t>(v, current_idx);
\r
7284 case 0xcd: // uint 16
\r
7286 idx += 2; // skip 2 content bytes
\r
7287 return get_from_vector<uint16_t>(v, current_idx);
\r
7290 case 0xce: // uint 32
\r
7292 idx += 4; // skip 4 content bytes
\r
7293 return get_from_vector<uint32_t>(v, current_idx);
\r
7296 case 0xcf: // uint 64
\r
7298 idx += 8; // skip 8 content bytes
\r
7299 return get_from_vector<uint64_t>(v, current_idx);
\r
7302 case 0xd0: // int 8
\r
7304 idx += 1; // skip content byte
\r
7305 return get_from_vector<int8_t>(v, current_idx);
\r
7308 case 0xd1: // int 16
\r
7310 idx += 2; // skip 2 content bytes
\r
7311 return get_from_vector<int16_t>(v, current_idx);
\r
7314 case 0xd2: // int 32
\r
7316 idx += 4; // skip 4 content bytes
\r
7317 return get_from_vector<int32_t>(v, current_idx);
\r
7320 case 0xd3: // int 64
\r
7322 idx += 8; // skip 8 content bytes
\r
7323 return get_from_vector<int64_t>(v, current_idx);
\r
7326 case 0xd9: // str 8
\r
7328 const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
\r
7329 const size_t offset = current_idx + 2;
\r
7330 idx += len + 1; // skip size byte + content bytes
\r
7331 check_length(v.size(), len, offset);
\r
7332 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7335 case 0xda: // str 16
\r
7337 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
\r
7338 const size_t offset = current_idx + 3;
\r
7339 idx += len + 2; // skip 2 size bytes + content bytes
\r
7340 check_length(v.size(), len, offset);
\r
7341 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7344 case 0xdb: // str 32
\r
7346 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
\r
7347 const size_t offset = current_idx + 5;
\r
7348 idx += len + 4; // skip 4 size bytes + content bytes
\r
7349 check_length(v.size(), len, offset);
\r
7350 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7353 case 0xdc: // array 16
\r
7355 basic_json result = value_t::array;
\r
7356 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
\r
7357 idx += 2; // skip 2 size bytes
\r
7358 for (size_t i = 0; i < len; ++i)
\r
7360 result.push_back(from_msgpack_internal(v, idx));
\r
7365 case 0xdd: // array 32
\r
7367 basic_json result = value_t::array;
\r
7368 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
\r
7369 idx += 4; // skip 4 size bytes
\r
7370 for (size_t i = 0; i < len; ++i)
\r
7372 result.push_back(from_msgpack_internal(v, idx));
\r
7377 case 0xde: // map 16
\r
7379 basic_json result = value_t::object;
\r
7380 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
\r
7381 idx += 2; // skip 2 size bytes
\r
7382 for (size_t i = 0; i < len; ++i)
\r
7384 std::string key = from_msgpack_internal(v, idx);
\r
7385 result[key] = from_msgpack_internal(v, idx);
\r
7390 case 0xdf: // map 32
\r
7392 basic_json result = value_t::object;
\r
7393 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
\r
7394 idx += 4; // skip 4 size bytes
\r
7395 for (size_t i = 0; i < len; ++i)
\r
7397 std::string key = from_msgpack_internal(v, idx);
\r
7398 result[key] = from_msgpack_internal(v, idx);
\r
7405 JSON_THROW(std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
\r
7412 @brief create a JSON value from a given CBOR vector
\r
7414 @param[in] v CBOR serialization
\r
7415 @param[in] idx byte index to start reading from @a v
\r
7417 @return deserialized JSON value
\r
7419 @throw std::invalid_argument if unsupported features from CBOR were used in
\r
7420 the given vector @a v or if the input is not valid CBOR
\r
7421 @throw std::out_of_range if the given vector ends prematurely
\r
7423 @sa https://tools.ietf.org/html/rfc7049
\r
7425 static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
\r
7427 // store and increment index
\r
7428 const size_t current_idx = idx++;
\r
7430 switch (v.at(current_idx))
\r
7432 // Integer 0x00..0x17 (0..23)
\r
7458 return v[current_idx];
\r
7461 case 0x18: // Unsigned integer (one-byte uint8_t follows)
\r
7463 idx += 1; // skip content byte
\r
7464 return get_from_vector<uint8_t>(v, current_idx);
\r
7467 case 0x19: // Unsigned integer (two-byte uint16_t follows)
\r
7469 idx += 2; // skip 2 content bytes
\r
7470 return get_from_vector<uint16_t>(v, current_idx);
\r
7473 case 0x1a: // Unsigned integer (four-byte uint32_t follows)
\r
7475 idx += 4; // skip 4 content bytes
\r
7476 return get_from_vector<uint32_t>(v, current_idx);
\r
7479 case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
\r
7481 idx += 8; // skip 8 content bytes
\r
7482 return get_from_vector<uint64_t>(v, current_idx);
\r
7485 // Negative integer -1-0x00..-1-0x17 (-1..-24)
\r
7511 return static_cast<int8_t>(0x20 - 1 - v[current_idx]);
\r
7514 case 0x38: // Negative integer (one-byte uint8_t follows)
\r
7516 idx += 1; // skip content byte
\r
7517 // must be uint8_t !
\r
7518 return static_cast<number_integer_t>(-1) - get_from_vector<uint8_t>(v, current_idx);
\r
7521 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
\r
7523 idx += 2; // skip 2 content bytes
\r
7524 return static_cast<number_integer_t>(-1) - get_from_vector<uint16_t>(v, current_idx);
\r
7527 case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
\r
7529 idx += 4; // skip 4 content bytes
\r
7530 return static_cast<number_integer_t>(-1) - get_from_vector<uint32_t>(v, current_idx);
\r
7533 case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
\r
7535 idx += 8; // skip 8 content bytes
\r
7536 return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_from_vector<uint64_t>(v, current_idx));
\r
7539 // UTF-8 string (0x00..0x17 bytes follow)
\r
7565 const auto len = static_cast<size_t>(v[current_idx] - 0x60);
\r
7566 const size_t offset = current_idx + 1;
\r
7567 idx += len; // skip content bytes
\r
7568 check_length(v.size(), len, offset);
\r
7569 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7572 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
\r
7574 const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
\r
7575 const size_t offset = current_idx + 2;
\r
7576 idx += len + 1; // skip size byte + content bytes
\r
7577 check_length(v.size(), len, offset);
\r
7578 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7581 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
\r
7583 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
\r
7584 const size_t offset = current_idx + 3;
\r
7585 idx += len + 2; // skip 2 size bytes + content bytes
\r
7586 check_length(v.size(), len, offset);
\r
7587 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7590 case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
\r
7592 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
\r
7593 const size_t offset = current_idx + 5;
\r
7594 idx += len + 4; // skip 4 size bytes + content bytes
\r
7595 check_length(v.size(), len, offset);
\r
7596 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7599 case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
\r
7601 const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
\r
7602 const size_t offset = current_idx + 9;
\r
7603 idx += len + 8; // skip 8 size bytes + content bytes
\r
7604 check_length(v.size(), len, offset);
\r
7605 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
\r
7608 case 0x7f: // UTF-8 string (indefinite length)
\r
7610 std::string result;
\r
7611 while (v.at(idx) != 0xff)
\r
7613 string_t s = from_cbor_internal(v, idx);
\r
7616 // skip break byte (0xFF)
\r
7621 // array (0x00..0x17 data items follow)
\r
7647 basic_json result = value_t::array;
\r
7648 const auto len = static_cast<size_t>(v[current_idx] - 0x80);
\r
7649 for (size_t i = 0; i < len; ++i)
\r
7651 result.push_back(from_cbor_internal(v, idx));
\r
7656 case 0x98: // array (one-byte uint8_t for n follows)
\r
7658 basic_json result = value_t::array;
\r
7659 const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
\r
7660 idx += 1; // skip 1 size byte
\r
7661 for (size_t i = 0; i < len; ++i)
\r
7663 result.push_back(from_cbor_internal(v, idx));
\r
7668 case 0x99: // array (two-byte uint16_t for n follow)
\r
7670 basic_json result = value_t::array;
\r
7671 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
\r
7672 idx += 2; // skip 4 size bytes
\r
7673 for (size_t i = 0; i < len; ++i)
\r
7675 result.push_back(from_cbor_internal(v, idx));
\r
7680 case 0x9a: // array (four-byte uint32_t for n follow)
\r
7682 basic_json result = value_t::array;
\r
7683 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
\r
7684 idx += 4; // skip 4 size bytes
\r
7685 for (size_t i = 0; i < len; ++i)
\r
7687 result.push_back(from_cbor_internal(v, idx));
\r
7692 case 0x9b: // array (eight-byte uint64_t for n follow)
\r
7694 basic_json result = value_t::array;
\r
7695 const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
\r
7696 idx += 8; // skip 8 size bytes
\r
7697 for (size_t i = 0; i < len; ++i)
\r
7699 result.push_back(from_cbor_internal(v, idx));
\r
7704 case 0x9f: // array (indefinite length)
\r
7706 basic_json result = value_t::array;
\r
7707 while (v.at(idx) != 0xff)
\r
7709 result.push_back(from_cbor_internal(v, idx));
\r
7711 // skip break byte (0xFF)
\r
7716 // map (0x00..0x17 pairs of data items follow)
\r
7742 basic_json result = value_t::object;
\r
7743 const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
\r
7744 for (size_t i = 0; i < len; ++i)
\r
7746 std::string key = from_cbor_internal(v, idx);
\r
7747 result[key] = from_cbor_internal(v, idx);
\r
7752 case 0xb8: // map (one-byte uint8_t for n follows)
\r
7754 basic_json result = value_t::object;
\r
7755 const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
\r
7756 idx += 1; // skip 1 size byte
\r
7757 for (size_t i = 0; i < len; ++i)
\r
7759 std::string key = from_cbor_internal(v, idx);
\r
7760 result[key] = from_cbor_internal(v, idx);
\r
7765 case 0xb9: // map (two-byte uint16_t for n follow)
\r
7767 basic_json result = value_t::object;
\r
7768 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
\r
7769 idx += 2; // skip 2 size bytes
\r
7770 for (size_t i = 0; i < len; ++i)
\r
7772 std::string key = from_cbor_internal(v, idx);
\r
7773 result[key] = from_cbor_internal(v, idx);
\r
7778 case 0xba: // map (four-byte uint32_t for n follow)
\r
7780 basic_json result = value_t::object;
\r
7781 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
\r
7782 idx += 4; // skip 4 size bytes
\r
7783 for (size_t i = 0; i < len; ++i)
\r
7785 std::string key = from_cbor_internal(v, idx);
\r
7786 result[key] = from_cbor_internal(v, idx);
\r
7791 case 0xbb: // map (eight-byte uint64_t for n follow)
\r
7793 basic_json result = value_t::object;
\r
7794 const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
\r
7795 idx += 8; // skip 8 size bytes
\r
7796 for (size_t i = 0; i < len; ++i)
\r
7798 std::string key = from_cbor_internal(v, idx);
\r
7799 result[key] = from_cbor_internal(v, idx);
\r
7804 case 0xbf: // map (indefinite length)
\r
7806 basic_json result = value_t::object;
\r
7807 while (v.at(idx) != 0xff)
\r
7809 std::string key = from_cbor_internal(v, idx);
\r
7810 result[key] = from_cbor_internal(v, idx);
\r
7812 // skip break byte (0xFF)
\r
7817 case 0xf4: // false
\r
7822 case 0xf5: // true
\r
7827 case 0xf6: // null
\r
7829 return value_t::null;
\r
7832 case 0xf9: // Half-Precision Float (two-byte IEEE 754)
\r
7834 idx += 2; // skip two content bytes
\r
7836 // code from RFC 7049, Appendix D, Figure 3:
\r
7837 // As half-precision floating-point numbers were only added to
\r
7838 // IEEE 754 in 2008, today's programming platforms often still
\r
7839 // only have limited support for them. It is very easy to
\r
7840 // include at least decoding support for them even without such
\r
7841 // support. An example of a small decoder for half-precision
\r
7842 // floating-point numbers in the C language is shown in Fig. 3.
\r
7843 const int half = (v.at(current_idx + 1) << 8) + v.at(current_idx + 2);
\r
7844 const int exp = (half >> 10) & 0x1f;
\r
7845 const int mant = half & 0x3ff;
\r
7849 val = std::ldexp(mant, -24);
\r
7851 else if (exp != 31)
\r
7853 val = std::ldexp(mant + 1024, exp - 25);
\r
7858 ? std::numeric_limits<double>::infinity()
\r
7859 : std::numeric_limits<double>::quiet_NaN();
\r
7861 return (half & 0x8000) != 0 ? -val : val;
\r
7864 case 0xfa: // Single-Precision Float (four-byte IEEE 754)
\r
7866 // copy bytes in reverse order into the float variable
\r
7868 for (size_t byte = 0; byte < sizeof(float); ++byte)
\r
7870 reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
\r
7872 idx += sizeof(float); // skip content bytes
\r
7876 case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
\r
7878 // copy bytes in reverse order into the double variable
\r
7880 for (size_t byte = 0; byte < sizeof(double); ++byte)
\r
7882 reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
\r
7884 idx += sizeof(double); // skip content bytes
\r
7888 default: // anything else (0xFF is handled inside the other types)
\r
7890 JSON_THROW(std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
\r
7897 @brief create a MessagePack serialization of a given JSON value
\r
7899 Serializes a given JSON value @a j to a byte vector using the MessagePack
\r
7900 serialization format. MessagePack is a binary serialization format which
\r
7901 aims to be more compact than JSON itself, yet more efficient to parse.
\r
7903 @param[in] j JSON value to serialize
\r
7904 @return MessagePack serialization as byte vector
\r
7906 @complexity Linear in the size of the JSON value @a j.
\r
7908 @liveexample{The example shows the serialization of a JSON value to a byte
\r
7909 vector in MessagePack format.,to_msgpack}
\r
7911 @sa http://msgpack.org
\r
7912 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
\r
7913 analogous deserialization
\r
7914 @sa @ref to_cbor(const basic_json& for the related CBOR format
\r
7916 @since version 2.0.9
\r
7918 static std::vector<uint8_t> to_msgpack(const basic_json& j)
\r
7920 std::vector<uint8_t> result;
\r
7921 to_msgpack_internal(j, result);
\r
7926 @brief create a JSON value from a byte vector in MessagePack format
\r
7928 Deserializes a given byte vector @a v to a JSON value using the MessagePack
\r
7929 serialization format.
\r
7931 @param[in] v a byte vector in MessagePack format
\r
7932 @param[in] start_index the index to start reading from @a v (0 by default)
\r
7933 @return deserialized JSON value
\r
7935 @throw std::invalid_argument if unsupported features from MessagePack were
\r
7936 used in the given vector @a v or if the input is not valid MessagePack
\r
7937 @throw std::out_of_range if the given vector ends prematurely
\r
7939 @complexity Linear in the size of the byte vector @a v.
\r
7941 @liveexample{The example shows the deserialization of a byte vector in
\r
7942 MessagePack format to a JSON value.,from_msgpack}
\r
7944 @sa http://msgpack.org
\r
7945 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
\r
7946 @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
\r
7947 related CBOR format
\r
7949 @since version 2.0.9, parameter @a start_index since 2.1.1
\r
7951 static basic_json from_msgpack(const std::vector<uint8_t>& v,
\r
7952 const size_t start_index = 0)
\r
7954 size_t i = start_index;
\r
7955 return from_msgpack_internal(v, i);
\r
7959 @brief create a MessagePack serialization of a given JSON value
\r
7961 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
\r
7962 Binary Object Representation) serialization format. CBOR is a binary
\r
7963 serialization format which aims to be more compact than JSON itself, yet
\r
7964 more efficient to parse.
\r
7966 @param[in] j JSON value to serialize
\r
7967 @return MessagePack serialization as byte vector
\r
7969 @complexity Linear in the size of the JSON value @a j.
\r
7971 @liveexample{The example shows the serialization of a JSON value to a byte
\r
7972 vector in CBOR format.,to_cbor}
\r
7974 @sa http://cbor.io
\r
7975 @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
\r
7976 analogous deserialization
\r
7977 @sa @ref to_msgpack(const basic_json& for the related MessagePack format
\r
7979 @since version 2.0.9
\r
7981 static std::vector<uint8_t> to_cbor(const basic_json& j)
\r
7983 std::vector<uint8_t> result;
\r
7984 to_cbor_internal(j, result);
\r
7989 @brief create a JSON value from a byte vector in CBOR format
\r
7991 Deserializes a given byte vector @a v to a JSON value using the CBOR
\r
7992 (Concise Binary Object Representation) serialization format.
\r
7994 @param[in] v a byte vector in CBOR format
\r
7995 @param[in] start_index the index to start reading from @a v (0 by default)
\r
7996 @return deserialized JSON value
\r
7998 @throw std::invalid_argument if unsupported features from CBOR were used in
\r
7999 the given vector @a v or if the input is not valid MessagePack
\r
8000 @throw std::out_of_range if the given vector ends prematurely
\r
8002 @complexity Linear in the size of the byte vector @a v.
\r
8004 @liveexample{The example shows the deserialization of a byte vector in CBOR
\r
8005 format to a JSON value.,from_cbor}
\r
8007 @sa http://cbor.io
\r
8008 @sa @ref to_cbor(const basic_json&) for the analogous serialization
\r
8009 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
\r
8010 related MessagePack format
\r
8012 @since version 2.0.9, parameter @a start_index since 2.1.1
\r
8014 static basic_json from_cbor(const std::vector<uint8_t>& v,
\r
8015 const size_t start_index = 0)
\r
8017 size_t i = start_index;
\r
8018 return from_cbor_internal(v, i);
\r
8023 ///////////////////////////
\r
8024 // convenience functions //
\r
8025 ///////////////////////////
\r
8028 @brief return the type as string
\r
8030 Returns the type name as string to be used in error messages - usually to
\r
8031 indicate that a function was called on a wrong JSON type.
\r
8033 @return basically a string representation of a the @a m_type member
\r
8035 @complexity Constant.
\r
8037 @liveexample{The following code exemplifies `type_name()` for all JSON
\r
8040 @since version 1.0.0, public since 2.1.0
\r
8042 std::string type_name() const
\r
8047 case value_t::null:
\r
8049 case value_t::object:
\r
8051 case value_t::array:
\r
8053 case value_t::string:
\r
8055 case value_t::boolean:
\r
8057 case value_t::discarded:
\r
8058 return "discarded";
\r
8067 @brief calculates the extra space to escape a JSON string
\r
8069 @param[in] s the string to escape
\r
8070 @return the number of characters required to escape string @a s
\r
8072 @complexity Linear in the length of string @a s.
\r
8074 static std::size_t extra_space(const string_t& s) noexcept
\r
8076 return std::accumulate(s.begin(), s.end(), size_t{},
\r
8077 [](size_t res, typename string_t::value_type c)
\r
8089 // from c (1 byte) to \x (2 bytes)
\r
8095 if (c >= 0x00 and c <= 0x1f)
\r
8097 // from c (1 byte) to \uxxxx (6 bytes)
\r
8108 @brief escape a string
\r
8110 Escape a string by replacing certain special characters by a sequence of
\r
8111 an escape character (backslash) and another character and other control
\r
8112 characters by a sequence of "\u" followed by a four-digit hex
\r
8115 @param[in] s the string to escape
\r
8116 @return the escaped string
\r
8118 @complexity Linear in the length of string @a s.
\r
8120 static string_t escape_string(const string_t& s)
\r
8122 const auto space = extra_space(s);
\r
8128 // create a result string of necessary size
\r
8129 string_t result(s.size() + space, '\\');
\r
8130 std::size_t pos = 0;
\r
8132 for (const auto& c : s)
\r
8136 // quotation mark (0x22)
\r
8139 result[pos + 1] = '"';
\r
8144 // reverse solidus (0x5c)
\r
8147 // nothing to change
\r
8152 // backspace (0x08)
\r
8155 result[pos + 1] = 'b';
\r
8160 // formfeed (0x0c)
\r
8163 result[pos + 1] = 'f';
\r
8171 result[pos + 1] = 'n';
\r
8176 // carriage return (0x0d)
\r
8179 result[pos + 1] = 'r';
\r
8184 // horizontal tab (0x09)
\r
8187 result[pos + 1] = 't';
\r
8194 if (c >= 0x00 and c <= 0x1f)
\r
8196 // convert a number 0..15 to its hex representation
\r
8198 static const char hexify[16] =
\r
8200 '0', '1', '2', '3', '4', '5', '6', '7',
\r
8201 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
\r
8204 // print character c as \uxxxx
\r
8205 for (const char m :
\r
8206 { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
\r
8209 result[++pos] = m;
\r
8216 // all other characters are added as-is
\r
8217 result[pos++] = c;
\r
8229 @brief locale-independent serialization for built-in arithmetic types
\r
8234 template<typename NumberType>
\r
8235 numtostr(NumberType value)
\r
8237 x_write(value, std::is_integral<NumberType>());
\r
8240 const char* c_str() const
\r
8242 return m_buf.data();
\r
8246 /// a (hopefully) large enough character buffer
\r
8247 std::array < char, 64 > m_buf{{}};
\r
8249 template<typename NumberType>
\r
8250 void x_write(NumberType x, /*is_integral=*/std::true_type)
\r
8252 // special case for "0"
\r
8259 const bool is_negative = x < 0;
\r
8262 // spare 1 byte for '\0'
\r
8263 while (x != 0 and i < m_buf.size() - 1)
\r
8265 const auto digit = std::labs(static_cast<long>(x % 10));
\r
8266 m_buf[i++] = static_cast<char>('0' + digit);
\r
8270 // make sure the number has been processed completely
\r
8275 // make sure there is capacity for the '-'
\r
8276 assert(i < m_buf.size() - 2);
\r
8280 std::reverse(m_buf.begin(), m_buf.begin() + i);
\r
8283 template<typename NumberType>
\r
8284 void x_write(NumberType x, /*is_integral=*/std::false_type)
\r
8286 // special case for 0.0 and -0.0
\r
8290 if (std::signbit(x))
\r
8300 // get number of digits for a text -> float -> text round-trip
\r
8301 static constexpr auto d = std::numeric_limits<NumberType>::digits10;
\r
8303 // the actual conversion
\r
8304 const auto written_bytes = snprintf(m_buf.data(), m_buf.size(), "%.*g", d, (double)x);
\r
8306 // negative value indicates an error
\r
8307 assert(written_bytes > 0);
\r
8308 // check if buffer was large enough
\r
8309 assert(static_cast<size_t>(written_bytes) < m_buf.size());
\r
8311 // read information from locale
\r
8312 const auto loc = localeconv();
\r
8313 assert(loc != nullptr);
\r
8314 const char thousands_sep = !loc->thousands_sep ? '\0'
\r
8315 : loc->thousands_sep[0];
\r
8317 const char decimal_point = !loc->decimal_point ? '\0'
\r
8318 : loc->decimal_point[0];
\r
8320 // erase thousands separator
\r
8321 if (thousands_sep != '\0')
\r
8323 const auto end = std::remove(m_buf.begin(), m_buf.begin() + written_bytes, thousands_sep);
\r
8324 std::fill(end, m_buf.end(), '\0');
\r
8327 // convert decimal point to '.'
\r
8328 if (decimal_point != '\0' and decimal_point != '.')
\r
8330 for (auto& c : m_buf)
\r
8332 if (c == decimal_point)
\r
8340 // determine if need to append ".0"
\r
8342 bool value_is_int_like = true;
\r
8343 for (i = 0; i < m_buf.size(); ++i)
\r
8345 // break when end of number is reached
\r
8346 if (m_buf[i] == '\0')
\r
8351 // check if we find non-int character
\r
8352 value_is_int_like = value_is_int_like and m_buf[i] != '.' and
\r
8353 m_buf[i] != 'e' and m_buf[i] != 'E';
\r
8356 if (value_is_int_like)
\r
8358 // there must be 2 bytes left for ".0"
\r
8359 assert((i + 2) < m_buf.size());
\r
8360 // we write to the end of the number
\r
8361 assert(m_buf[i] == '\0');
\r
8362 assert(m_buf[i - 1] != '\0');
\r
8366 m_buf[i + 1] = '0';
\r
8368 // the resulting string is properly terminated
\r
8369 assert(m_buf[i + 2] == '\0');
\r
8376 @brief internal implementation of the serialization function
\r
8378 This function is called by the public member function dump and organizes
\r
8379 the serialization internally. The indentation level is propagated as
\r
8380 additional parameter. In case of arrays and objects, the function is
\r
8381 called recursively. Note that
\r
8383 - strings and object keys are escaped using `escape_string()`
\r
8384 - integer numbers are converted implicitly via `operator<<`
\r
8385 - floating-point numbers are converted to a string using `"%g"` format
\r
8387 @param[out] o stream to write to
\r
8388 @param[in] pretty_print whether the output shall be pretty-printed
\r
8389 @param[in] indent_step the indent level
\r
8390 @param[in] current_indent the current indent level (only used internally)
\r
8392 void dump(std::ostream& o,
\r
8393 const bool pretty_print,
\r
8394 const unsigned int indent_step,
\r
8395 const unsigned int current_indent = 0) const
\r
8397 // variable to hold indentation for recursive calls
\r
8398 unsigned int new_indent = current_indent;
\r
8402 case value_t::object:
\r
8404 if (m_value.object->empty())
\r
8412 // increase indentation
\r
8415 new_indent += indent_step;
\r
8419 for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
\r
8421 if (i != m_value.object->cbegin())
\r
8423 o << (pretty_print ? ",\n" : ",");
\r
8425 o << string_t(new_indent, ' ') << "\""
\r
8426 << escape_string(i->first) << "\":"
\r
8427 << (pretty_print ? " " : "");
\r
8428 i->second.dump(o, pretty_print, indent_step, new_indent);
\r
8431 // decrease indentation
\r
8434 new_indent -= indent_step;
\r
8438 o << string_t(new_indent, ' ') + "}";
\r
8442 case value_t::array:
\r
8444 if (m_value.array->empty())
\r
8452 // increase indentation
\r
8455 new_indent += indent_step;
\r
8459 for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
\r
8461 if (i != m_value.array->cbegin())
\r
8463 o << (pretty_print ? ",\n" : ",");
\r
8465 o << string_t(new_indent, ' ');
\r
8466 i->dump(o, pretty_print, indent_step, new_indent);
\r
8469 // decrease indentation
\r
8472 new_indent -= indent_step;
\r
8476 o << string_t(new_indent, ' ') << "]";
\r
8480 case value_t::string:
\r
8482 o << string_t("\"") << escape_string(*m_value.string) << "\"";
\r
8486 case value_t::boolean:
\r
8488 o << (m_value.boolean ? "true" : "false");
\r
8492 case value_t::number_integer:
\r
8494 o << numtostr(m_value.number_integer).c_str();
\r
8498 case value_t::number_unsigned:
\r
8500 o << numtostr(m_value.number_unsigned).c_str();
\r
8504 case value_t::number_float:
\r
8506 o << numtostr(m_value.number_float).c_str();
\r
8510 case value_t::discarded:
\r
8512 o << "<discarded>";
\r
8516 case value_t::null:
\r
8525 //////////////////////
\r
8526 // member variables //
\r
8527 //////////////////////
\r
8529 /// the type of the current element
\r
8530 value_t m_type = value_t::null;
\r
8532 /// the value of the current element
\r
8533 json_value m_value = {};
\r
8542 @brief an iterator for primitive JSON types
\r
8544 This class models an iterator for primitive JSON types (boolean, number,
\r
8545 string). It's only purpose is to allow the iterator/const_iterator classes
\r
8546 to "iterate" over primitive values. Internally, the iterator is modeled by
\r
8547 a `difference_type` variable. Value begin_value (`0`) models the begin,
\r
8548 end_value (`1`) models past the end.
\r
8550 class primitive_iterator_t
\r
8554 difference_type get_value() const noexcept
\r
8558 /// set iterator to a defined beginning
\r
8559 void set_begin() noexcept
\r
8561 m_it = begin_value;
\r
8564 /// set iterator to a defined past the end
\r
8565 void set_end() noexcept
\r
8570 /// return whether the iterator can be dereferenced
\r
8571 constexpr bool is_begin() const noexcept
\r
8573 return (m_it == begin_value);
\r
8576 /// return whether the iterator is at end
\r
8577 constexpr bool is_end() const noexcept
\r
8579 return (m_it == end_value);
\r
8582 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
\r
8584 return lhs.m_it == rhs.m_it;
\r
8587 friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
\r
8589 return !(lhs == rhs);
\r
8592 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
\r
8594 return lhs.m_it < rhs.m_it;
\r
8597 friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
\r
8599 return lhs.m_it <= rhs.m_it;
\r
8602 friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
\r
8604 return lhs.m_it > rhs.m_it;
\r
8607 friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
\r
8609 return lhs.m_it >= rhs.m_it;
\r
8612 primitive_iterator_t operator+(difference_type i)
\r
8614 auto result = *this;
\r
8619 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
\r
8621 return lhs.m_it - rhs.m_it;
\r
8624 friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
\r
8626 return os << it.m_it;
\r
8629 primitive_iterator_t& operator++()
\r
8635 primitive_iterator_t operator++(int)
\r
8637 auto result = *this;
\r
8642 primitive_iterator_t& operator--()
\r
8648 primitive_iterator_t operator--(int)
\r
8650 auto result = *this;
\r
8655 primitive_iterator_t& operator+=(difference_type n)
\r
8661 primitive_iterator_t& operator-=(difference_type n)
\r
8668 static constexpr difference_type begin_value = 0;
\r
8669 static constexpr difference_type end_value = begin_value + 1;
\r
8671 /// iterator as signed integer type
\r
8672 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
\r
8676 @brief an iterator value
\r
8678 @note This structure could easily be a union, but MSVC currently does not
\r
8679 allow unions members with complex constructors, see
\r
8680 https://github.com/nlohmann/json/pull/105.
\r
8682 struct internal_iterator
\r
8684 /// iterator for JSON objects
\r
8685 typename object_t::iterator object_iterator;
\r
8686 /// iterator for JSON arrays
\r
8687 typename array_t::iterator array_iterator;
\r
8688 /// generic iterator for all other types
\r
8689 primitive_iterator_t primitive_iterator;
\r
8691 /// create an uninitialized internal_iterator
\r
8692 internal_iterator() noexcept
\r
8693 : object_iterator(), array_iterator(), primitive_iterator()
\r
8697 /// proxy class for the iterator_wrapper functions
\r
8698 template<typename IteratorType>
\r
8699 class iteration_proxy
\r
8702 /// helper class for iteration
\r
8703 class iteration_proxy_internal
\r
8707 IteratorType anchor;
\r
8708 /// an index for arrays (used to create key names)
\r
8709 size_t array_index = 0;
\r
8712 explicit iteration_proxy_internal(IteratorType it) noexcept
\r
8716 /// dereference operator (needed for range-based for)
\r
8717 iteration_proxy_internal& operator*()
\r
8722 /// increment operator (needed for range-based for)
\r
8723 iteration_proxy_internal& operator++()
\r
8731 /// inequality operator (needed for range-based for)
\r
8732 bool operator!= (const iteration_proxy_internal& o) const
\r
8734 return anchor != o.anchor;
\r
8737 /// return key of the iterator
\r
8738 typename basic_json::string_t key() const
\r
8740 assert(anchor.m_object != nullptr);
\r
8742 switch (anchor.m_object->type())
\r
8744 // use integer array index as key
\r
8745 case value_t::array:
\r
8747 return std::to_string(array_index);
\r
8750 // use key from the object
\r
8751 case value_t::object:
\r
8753 return anchor.key();
\r
8756 // use an empty key for all primitive types
\r
8764 /// return value of the iterator
\r
8765 typename IteratorType::reference value() const
\r
8767 return anchor.value();
\r
8771 /// the container to iterate
\r
8772 typename IteratorType::reference container;
\r
8775 /// construct iteration proxy from a container
\r
8776 explicit iteration_proxy(typename IteratorType::reference cont)
\r
8780 /// return iterator begin (needed for range-based for)
\r
8781 iteration_proxy_internal begin() noexcept
\r
8783 return iteration_proxy_internal(container.begin());
\r
8786 /// return iterator end (needed for range-based for)
\r
8787 iteration_proxy_internal end() noexcept
\r
8789 return iteration_proxy_internal(container.end());
\r
8795 @brief a template for a random access iterator for the @ref basic_json class
\r
8797 This class implements a both iterators (iterator and const_iterator) for the
\r
8798 @ref basic_json class.
\r
8800 @note An iterator is called *initialized* when a pointer to a JSON value
\r
8801 has been set (e.g., by a constructor or a copy assignment). If the
\r
8802 iterator is default-constructed, it is *uninitialized* and most
\r
8803 methods are undefined. **The library uses assertions to detect calls
\r
8804 on uninitialized iterators.**
\r
8806 @requirement The class satisfies the following concept requirements:
\r
8807 - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
\r
8808 The iterator that can be moved to point (forward and backward) to any
\r
8809 element in constant time.
\r
8811 @since version 1.0.0, simplified in version 2.0.9
\r
8813 template<typename U>
\r
8814 class iter_impl : public std::iterator<std::random_access_iterator_tag, U>
\r
8816 /// allow basic_json to access private members
\r
8817 friend class basic_json;
\r
8819 // make sure U is basic_json or const basic_json
\r
8820 static_assert(std::is_same<U, basic_json>::value
\r
8821 or std::is_same<U, const basic_json>::value,
\r
8822 "iter_impl only accepts (const) basic_json");
\r
8825 /// the type of the values when the iterator is dereferenced
\r
8826 using value_type = typename basic_json::value_type;
\r
8827 /// a type to represent differences between iterators
\r
8828 using difference_type = typename basic_json::difference_type;
\r
8829 /// defines a pointer to the type iterated over (value_type)
\r
8830 using pointer = typename std::conditional<std::is_const<U>::value,
\r
8831 typename basic_json::const_pointer,
\r
8832 typename basic_json::pointer>::type;
\r
8833 /// defines a reference to the type iterated over (value_type)
\r
8834 using reference = typename std::conditional<std::is_const<U>::value,
\r
8835 typename basic_json::const_reference,
\r
8836 typename basic_json::reference>::type;
\r
8837 /// the category of the iterator
\r
8838 using iterator_category = std::bidirectional_iterator_tag;
\r
8840 /// default constructor
\r
8841 iter_impl() = default;
\r
8844 @brief constructor for a given JSON instance
\r
8845 @param[in] object pointer to a JSON object for this iterator
\r
8846 @pre object != nullptr
\r
8847 @post The iterator is initialized; i.e. `m_object != nullptr`.
\r
8849 explicit iter_impl(pointer object) noexcept
\r
8850 : m_object(object)
\r
8852 assert(m_object != nullptr);
\r
8854 switch (m_object->m_type)
\r
8856 case basic_json::value_t::object:
\r
8858 m_it.object_iterator = typename object_t::iterator();
\r
8862 case basic_json::value_t::array:
\r
8864 m_it.array_iterator = typename array_t::iterator();
\r
8870 m_it.primitive_iterator = primitive_iterator_t();
\r
8877 Use operator `const_iterator` instead of `const_iterator(const iterator&
\r
8878 other) noexcept` to avoid two class definitions for @ref iterator and
\r
8879 @ref const_iterator.
\r
8881 This function is only called if this class is an @ref iterator. If this
\r
8882 class is a @ref const_iterator this function is not called.
\r
8884 operator const_iterator() const
\r
8886 const_iterator ret;
\r
8890 ret.m_object = m_object;
\r
8898 @brief copy constructor
\r
8899 @param[in] other iterator to copy from
\r
8900 @note It is not checked whether @a other is initialized.
\r
8902 iter_impl(const iter_impl& other) noexcept
\r
8903 : m_object(other.m_object), m_it(other.m_it)
\r
8907 @brief copy assignment
\r
8908 @param[in,out] other iterator to copy from
\r
8909 @note It is not checked whether @a other is initialized.
\r
8911 iter_impl& operator=(iter_impl other) noexcept(
\r
8912 std::is_nothrow_move_constructible<pointer>::value and
\r
8913 std::is_nothrow_move_assignable<pointer>::value and
\r
8914 std::is_nothrow_move_constructible<internal_iterator>::value and
\r
8915 std::is_nothrow_move_assignable<internal_iterator>::value
\r
8918 std::swap(m_object, other.m_object);
\r
8919 std::swap(m_it, other.m_it);
\r
8925 @brief set the iterator to the first value
\r
8926 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
8928 void set_begin() noexcept
\r
8930 assert(m_object != nullptr);
\r
8932 switch (m_object->m_type)
\r
8934 case basic_json::value_t::object:
\r
8936 m_it.object_iterator = m_object->m_value.object->begin();
\r
8940 case basic_json::value_t::array:
\r
8942 m_it.array_iterator = m_object->m_value.array->begin();
\r
8946 case basic_json::value_t::null:
\r
8948 // set to end so begin()==end() is true: null is empty
\r
8949 m_it.primitive_iterator.set_end();
\r
8955 m_it.primitive_iterator.set_begin();
\r
8962 @brief set the iterator past the last value
\r
8963 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
8965 void set_end() noexcept
\r
8967 assert(m_object != nullptr);
\r
8969 switch (m_object->m_type)
\r
8971 case basic_json::value_t::object:
\r
8973 m_it.object_iterator = m_object->m_value.object->end();
\r
8977 case basic_json::value_t::array:
\r
8979 m_it.array_iterator = m_object->m_value.array->end();
\r
8985 m_it.primitive_iterator.set_end();
\r
8993 @brief return a reference to the value pointed to by the iterator
\r
8994 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
8996 reference operator*() const
\r
8998 assert(m_object != nullptr);
\r
9000 switch (m_object->m_type)
\r
9002 case basic_json::value_t::object:
\r
9004 assert(m_it.object_iterator != m_object->m_value.object->end());
\r
9005 return m_it.object_iterator->second;
\r
9008 case basic_json::value_t::array:
\r
9010 assert(m_it.array_iterator != m_object->m_value.array->end());
\r
9011 return *m_it.array_iterator;
\r
9014 case basic_json::value_t::null:
\r
9016 JSON_THROW(std::out_of_range("cannot get value"));
\r
9021 if (m_it.primitive_iterator.is_begin())
\r
9026 JSON_THROW(std::out_of_range("cannot get value"));
\r
9032 @brief dereference the iterator
\r
9033 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9035 pointer operator->() const
\r
9037 assert(m_object != nullptr);
\r
9039 switch (m_object->m_type)
\r
9041 case basic_json::value_t::object:
\r
9043 assert(m_it.object_iterator != m_object->m_value.object->end());
\r
9044 return &(m_it.object_iterator->second);
\r
9047 case basic_json::value_t::array:
\r
9049 assert(m_it.array_iterator != m_object->m_value.array->end());
\r
9050 return &*m_it.array_iterator;
\r
9055 if (m_it.primitive_iterator.is_begin())
\r
9060 JSON_THROW(std::out_of_range("cannot get value"));
\r
9066 @brief post-increment (it++)
\r
9067 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9069 iter_impl operator++(int)
\r
9071 auto result = *this;
\r
9077 @brief pre-increment (++it)
\r
9078 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9080 iter_impl& operator++()
\r
9082 assert(m_object != nullptr);
\r
9084 switch (m_object->m_type)
\r
9086 case basic_json::value_t::object:
\r
9088 std::advance(m_it.object_iterator, 1);
\r
9092 case basic_json::value_t::array:
\r
9094 std::advance(m_it.array_iterator, 1);
\r
9100 ++m_it.primitive_iterator;
\r
9109 @brief post-decrement (it--)
\r
9110 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9112 iter_impl operator--(int)
\r
9114 auto result = *this;
\r
9120 @brief pre-decrement (--it)
\r
9121 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9123 iter_impl& operator--()
\r
9125 assert(m_object != nullptr);
\r
9127 switch (m_object->m_type)
\r
9129 case basic_json::value_t::object:
\r
9131 std::advance(m_it.object_iterator, -1);
\r
9135 case basic_json::value_t::array:
\r
9137 std::advance(m_it.array_iterator, -1);
\r
9143 --m_it.primitive_iterator;
\r
9152 @brief comparison: equal
\r
9153 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9155 bool operator==(const iter_impl& other) const
\r
9157 // if objects are not the same, the comparison is undefined
\r
9158 if (m_object != other.m_object)
\r
9160 JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
\r
9163 assert(m_object != nullptr);
\r
9165 switch (m_object->m_type)
\r
9167 case basic_json::value_t::object:
\r
9169 return (m_it.object_iterator == other.m_it.object_iterator);
\r
9172 case basic_json::value_t::array:
\r
9174 return (m_it.array_iterator == other.m_it.array_iterator);
\r
9179 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
\r
9185 @brief comparison: not equal
\r
9186 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9188 bool operator!=(const iter_impl& other) const
\r
9190 return not operator==(other);
\r
9194 @brief comparison: smaller
\r
9195 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9197 bool operator<(const iter_impl& other) const
\r
9199 // if objects are not the same, the comparison is undefined
\r
9200 if (m_object != other.m_object)
\r
9202 JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
\r
9205 assert(m_object != nullptr);
\r
9207 switch (m_object->m_type)
\r
9209 case basic_json::value_t::object:
\r
9211 JSON_THROW(std::domain_error("cannot compare order of object iterators"));
\r
9214 case basic_json::value_t::array:
\r
9216 return (m_it.array_iterator < other.m_it.array_iterator);
\r
9221 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
\r
9227 @brief comparison: less than or equal
\r
9228 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9230 bool operator<=(const iter_impl& other) const
\r
9232 return not other.operator < (*this);
\r
9236 @brief comparison: greater than
\r
9237 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9239 bool operator>(const iter_impl& other) const
\r
9241 return not operator<=(other);
\r
9245 @brief comparison: greater than or equal
\r
9246 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9248 bool operator>=(const iter_impl& other) const
\r
9250 return not operator<(other);
\r
9254 @brief add to iterator
\r
9255 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9257 iter_impl& operator+=(difference_type i)
\r
9259 assert(m_object != nullptr);
\r
9261 switch (m_object->m_type)
\r
9263 case basic_json::value_t::object:
\r
9265 JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
\r
9268 case basic_json::value_t::array:
\r
9270 std::advance(m_it.array_iterator, i);
\r
9276 m_it.primitive_iterator += i;
\r
9285 @brief subtract from iterator
\r
9286 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9288 iter_impl& operator-=(difference_type i)
\r
9290 return operator+=(-i);
\r
9294 @brief add to iterator
\r
9295 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9297 iter_impl operator+(difference_type i)
\r
9299 auto result = *this;
\r
9305 @brief subtract from iterator
\r
9306 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9308 iter_impl operator-(difference_type i)
\r
9310 auto result = *this;
\r
9316 @brief return difference
\r
9317 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9319 difference_type operator-(const iter_impl& other) const
\r
9321 assert(m_object != nullptr);
\r
9323 switch (m_object->m_type)
\r
9325 case basic_json::value_t::object:
\r
9327 JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
\r
9330 case basic_json::value_t::array:
\r
9332 return m_it.array_iterator - other.m_it.array_iterator;
\r
9337 return m_it.primitive_iterator - other.m_it.primitive_iterator;
\r
9343 @brief access to successor
\r
9344 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9346 reference operator[](difference_type n) const
\r
9348 assert(m_object != nullptr);
\r
9350 switch (m_object->m_type)
\r
9352 case basic_json::value_t::object:
\r
9354 JSON_THROW(std::domain_error("cannot use operator[] for object iterators"));
\r
9357 case basic_json::value_t::array:
\r
9359 return *std::next(m_it.array_iterator, n);
\r
9362 case basic_json::value_t::null:
\r
9364 JSON_THROW(std::out_of_range("cannot get value"));
\r
9369 if (m_it.primitive_iterator.get_value() == -n)
\r
9374 JSON_THROW(std::out_of_range("cannot get value"));
\r
9380 @brief return the key of an object iterator
\r
9381 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9383 typename object_t::key_type key() const
\r
9385 assert(m_object != nullptr);
\r
9387 if (m_object->is_object())
\r
9389 return m_it.object_iterator->first;
\r
9392 JSON_THROW(std::domain_error("cannot use key() for non-object iterators"));
\r
9396 @brief return the value of an iterator
\r
9397 @pre The iterator is initialized; i.e. `m_object != nullptr`.
\r
9399 reference value() const
\r
9401 return operator*();
\r
9405 /// associated JSON instance
\r
9406 pointer m_object = nullptr;
\r
9407 /// the actual iterator of the associated instance
\r
9408 internal_iterator m_it = internal_iterator();
\r
9412 @brief a template for a reverse iterator class
\r
9414 @tparam Base the base iterator type to reverse. Valid types are @ref
\r
9415 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
\r
9416 create @ref const_reverse_iterator).
\r
9418 @requirement The class satisfies the following concept requirements:
\r
9419 - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
\r
9420 The iterator that can be moved to point (forward and backward) to any
\r
9421 element in constant time.
\r
9422 - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
\r
9423 It is possible to write to the pointed-to element (only if @a Base is
\r
9426 @since version 1.0.0
\r
9428 template<typename Base>
\r
9429 class json_reverse_iterator : public std::reverse_iterator<Base>
\r
9432 /// shortcut to the reverse iterator adaptor
\r
9433 using base_iterator = std::reverse_iterator<Base>;
\r
9434 /// the reference type for the pointed-to element
\r
9435 using reference = typename Base::reference;
\r
9437 /// create reverse iterator from iterator
\r
9438 json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
\r
9439 : base_iterator(it)
\r
9442 /// create reverse iterator from base class
\r
9443 json_reverse_iterator(const base_iterator& it) noexcept
\r
9444 : base_iterator(it)
\r
9447 /// post-increment (it++)
\r
9448 json_reverse_iterator operator++(int)
\r
9450 return base_iterator::operator++(1);
\r
9453 /// pre-increment (++it)
\r
9454 json_reverse_iterator& operator++()
\r
9456 base_iterator::operator++();
\r
9460 /// post-decrement (it--)
\r
9461 json_reverse_iterator operator--(int)
\r
9463 return base_iterator::operator--(1);
\r
9466 /// pre-decrement (--it)
\r
9467 json_reverse_iterator& operator--()
\r
9469 base_iterator::operator--();
\r
9473 /// add to iterator
\r
9474 json_reverse_iterator& operator+=(difference_type i)
\r
9476 base_iterator::operator+=(i);
\r
9480 /// add to iterator
\r
9481 json_reverse_iterator operator+(difference_type i) const
\r
9483 auto result = *this;
\r
9488 /// subtract from iterator
\r
9489 json_reverse_iterator operator-(difference_type i) const
\r
9491 auto result = *this;
\r
9496 /// return difference
\r
9497 difference_type operator-(const json_reverse_iterator& other) const
\r
9499 return this->base() - other.base();
\r
9502 /// access to successor
\r
9503 reference operator[](difference_type n) const
\r
9505 return *(this->operator+(n));
\r
9508 /// return the key of an object iterator
\r
9509 typename object_t::key_type key() const
\r
9511 auto it = --this->base();
\r
9515 /// return the value of an iterator
\r
9516 reference value() const
\r
9518 auto it = --this->base();
\r
9519 return it.operator * ();
\r
9525 //////////////////////
\r
9526 // lexer and parser //
\r
9527 //////////////////////
\r
9530 @brief lexical analysis
\r
9532 This class organizes the lexical analysis during JSON deserialization. The
\r
9533 core of it is a scanner generated by [re2c](http://re2c.org) that
\r
9534 processes a buffer and recognizes tokens according to RFC 7159.
\r
9539 /// token types for the parser
\r
9540 enum class token_type
\r
9542 uninitialized, ///< indicating the scanner is uninitialized
\r
9543 literal_true, ///< the `true` literal
\r
9544 literal_false, ///< the `false` literal
\r
9545 literal_null, ///< the `null` literal
\r
9546 value_string, ///< a string -- use get_string() for actual value
\r
9547 value_unsigned, ///< an unsigned integer -- use get_number() for actual value
\r
9548 value_integer, ///< a signed integer -- use get_number() for actual value
\r
9549 value_float, ///< an floating point number -- use get_number() for actual value
\r
9550 begin_array, ///< the character for array begin `[`
\r
9551 begin_object, ///< the character for object begin `{`
\r
9552 end_array, ///< the character for array end `]`
\r
9553 end_object, ///< the character for object end `}`
\r
9554 name_separator, ///< the name separator `:`
\r
9555 value_separator, ///< the value separator `,`
\r
9556 parse_error, ///< indicating a parse error
\r
9557 end_of_input ///< indicating the end of the input buffer
\r
9560 /// the char type to use in the lexer
\r
9561 using lexer_char_t = unsigned char;
\r
9563 /// a lexer from a buffer with given length
\r
9564 lexer(const lexer_char_t* buff, const size_t len) noexcept
\r
9567 assert(m_content != nullptr);
\r
9568 m_start = m_cursor = m_content;
\r
9569 m_limit = m_content + len;
\r
9572 /// a lexer from an input stream
\r
9573 explicit lexer(std::istream& s)
\r
9574 : m_stream(&s), m_line_buffer()
\r
9576 // immediately abort if stream is erroneous
\r
9579 JSON_THROW(std::invalid_argument("stream error"));
\r
9583 fill_line_buffer();
\r
9585 // skip UTF-8 byte-order mark
\r
9586 if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) == "\xEF\xBB\xBF")
\r
9588 m_line_buffer[0] = ' ';
\r
9589 m_line_buffer[1] = ' ';
\r
9590 m_line_buffer[2] = ' ';
\r
9594 // switch off unwanted functions (due to pointer members)
\r
9596 lexer(const lexer&) = delete;
\r
9597 lexer operator=(const lexer&) = delete;
\r
9600 @brief create a string from one or two Unicode code points
\r
9602 There are two cases: (1) @a codepoint1 is in the Basic Multilingual
\r
9603 Plane (U+0000 through U+FFFF) and @a codepoint2 is 0, or (2)
\r
9604 @a codepoint1 and @a codepoint2 are a UTF-16 surrogate pair to
\r
9605 represent a code point above U+FFFF.
\r
9607 @param[in] codepoint1 the code point (can be high surrogate)
\r
9608 @param[in] codepoint2 the code point (can be low surrogate or 0)
\r
9610 @return string representation of the code point; the length of the
\r
9611 result string is between 1 and 4 characters.
\r
9613 @throw std::out_of_range if code point is > 0x10ffff; example: `"code
\r
9614 points above 0x10FFFF are invalid"`
\r
9615 @throw std::invalid_argument if the low surrogate is invalid; example:
\r
9616 `""missing or wrong low surrogate""`
\r
9618 @complexity Constant.
\r
9620 @see <http://en.wikipedia.org/wiki/UTF-8#Sample_code>
\r
9622 static string_t to_unicode(const std::size_t codepoint1,
\r
9623 const std::size_t codepoint2 = 0)
\r
9625 // calculate the code point from the given code points
\r
9626 std::size_t codepoint = codepoint1;
\r
9628 // check if codepoint1 is a high surrogate
\r
9629 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
\r
9631 // check if codepoint2 is a low surrogate
\r
9632 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
\r
9635 // high surrogate occupies the most significant 22 bits
\r
9636 (codepoint1 << 10)
\r
9637 // low surrogate occupies the least significant 15 bits
\r
9639 // there is still the 0xD800, 0xDC00 and 0x10000 noise
\r
9640 // in the result so we have to subtract with:
\r
9641 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
\r
9646 JSON_THROW(std::invalid_argument("missing or wrong low surrogate"));
\r
9652 if (codepoint < 0x80)
\r
9654 // 1-byte characters: 0xxxxxxx (ASCII)
\r
9655 result.append(1, static_cast<typename string_t::value_type>(codepoint));
\r
9657 else if (codepoint <= 0x7ff)
\r
9659 // 2-byte characters: 110xxxxx 10xxxxxx
\r
9660 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
\r
9661 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
\r
9663 else if (codepoint <= 0xffff)
\r
9665 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
\r
9666 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
\r
9667 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
\r
9668 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
\r
9670 else if (codepoint <= 0x10ffff)
\r
9672 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
\r
9673 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
\r
9674 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
\r
9675 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
\r
9676 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
\r
9680 JSON_THROW(std::out_of_range("code points above 0x10FFFF are invalid"));
\r
9686 /// return name of values of type token_type (only used for errors)
\r
9687 static std::string token_type_name(const token_type t)
\r
9691 case token_type::uninitialized:
\r
9692 return "<uninitialized>";
\r
9693 case token_type::literal_true:
\r
9694 return "true literal";
\r
9695 case token_type::literal_false:
\r
9696 return "false literal";
\r
9697 case token_type::literal_null:
\r
9698 return "null literal";
\r
9699 case token_type::value_string:
\r
9700 return "string literal";
\r
9701 case lexer::token_type::value_unsigned:
\r
9702 case lexer::token_type::value_integer:
\r
9703 case lexer::token_type::value_float:
\r
9704 return "number literal";
\r
9705 case token_type::begin_array:
\r
9707 case token_type::begin_object:
\r
9709 case token_type::end_array:
\r
9711 case token_type::end_object:
\r
9713 case token_type::name_separator:
\r
9715 case token_type::value_separator:
\r
9717 case token_type::parse_error:
\r
9718 return "<parse error>";
\r
9719 case token_type::end_of_input:
\r
9720 return "end of input";
\r
9723 // catch non-enum values
\r
9724 return "unknown token"; // LCOV_EXCL_LINE
\r
9730 This function implements a scanner for JSON. It is specified using
\r
9731 regular expressions that try to follow RFC 7159 as close as possible.
\r
9732 These regular expressions are then translated into a minimized
\r
9733 deterministic finite automaton (DFA) by the tool
\r
9734 [re2c](http://re2c.org). As a result, the translated code for this
\r
9735 function consists of a large block of code with `goto` jumps.
\r
9737 @return the class of the next token read from the buffer
\r
9739 @complexity Linear in the length of the input.\n
\r
9741 Proposition: The loop below will always terminate for finite input.\n
\r
9743 Proof (by contradiction): Assume a finite input. To loop forever, the
\r
9744 loop must never hit code with a `break` statement. The only code
\r
9745 snippets without a `break` statement are the continue statements for
\r
9746 whitespace and byte-order-marks. To loop forever, the input must be an
\r
9747 infinite sequence of whitespace or byte-order-marks. This contradicts
\r
9748 the assumption of finite input, q.e.d.
\r
9754 // pointer for backtracking information
\r
9755 m_marker = nullptr;
\r
9757 // remember the begin of the token
\r
9758 m_start = m_cursor;
\r
9759 assert(m_start != nullptr);
\r
9763 lexer_char_t yych;
\r
9764 unsigned int yyaccept = 0;
\r
9765 static const unsigned char yybm[] =
\r
9767 0, 0, 0, 0, 0, 0, 0, 0,
\r
9768 0, 32, 32, 0, 0, 32, 0, 0,
\r
9769 0, 0, 0, 0, 0, 0, 0, 0,
\r
9770 0, 0, 0, 0, 0, 0, 0, 0,
\r
9771 160, 128, 0, 128, 128, 128, 128, 128,
\r
9772 128, 128, 128, 128, 128, 128, 128, 128,
\r
9773 192, 192, 192, 192, 192, 192, 192, 192,
\r
9774 192, 192, 128, 128, 128, 128, 128, 128,
\r
9775 128, 128, 128, 128, 128, 128, 128, 128,
\r
9776 128, 128, 128, 128, 128, 128, 128, 128,
\r
9777 128, 128, 128, 128, 128, 128, 128, 128,
\r
9778 128, 128, 128, 128, 0, 128, 128, 128,
\r
9779 128, 128, 128, 128, 128, 128, 128, 128,
\r
9780 128, 128, 128, 128, 128, 128, 128, 128,
\r
9781 128, 128, 128, 128, 128, 128, 128, 128,
\r
9782 128, 128, 128, 128, 128, 128, 128, 128,
\r
9783 0, 0, 0, 0, 0, 0, 0, 0,
\r
9784 0, 0, 0, 0, 0, 0, 0, 0,
\r
9785 0, 0, 0, 0, 0, 0, 0, 0,
\r
9786 0, 0, 0, 0, 0, 0, 0, 0,
\r
9787 0, 0, 0, 0, 0, 0, 0, 0,
\r
9788 0, 0, 0, 0, 0, 0, 0, 0,
\r
9789 0, 0, 0, 0, 0, 0, 0, 0,
\r
9790 0, 0, 0, 0, 0, 0, 0, 0,
\r
9791 0, 0, 0, 0, 0, 0, 0, 0,
\r
9792 0, 0, 0, 0, 0, 0, 0, 0,
\r
9793 0, 0, 0, 0, 0, 0, 0, 0,
\r
9794 0, 0, 0, 0, 0, 0, 0, 0,
\r
9795 0, 0, 0, 0, 0, 0, 0, 0,
\r
9796 0, 0, 0, 0, 0, 0, 0, 0,
\r
9797 0, 0, 0, 0, 0, 0, 0, 0,
\r
9798 0, 0, 0, 0, 0, 0, 0, 0,
\r
9800 if ((m_limit - m_cursor) < 5)
\r
9802 fill_line_buffer(5); // LCOV_EXCL_LINE
\r
9805 if (yybm[0 + yych] & 32)
\r
9807 goto basic_json_parser_6;
\r
9817 goto basic_json_parser_2;
\r
9821 goto basic_json_parser_4;
\r
9823 goto basic_json_parser_9;
\r
9829 goto basic_json_parser_4;
\r
9833 goto basic_json_parser_10;
\r
9835 goto basic_json_parser_12;
\r
9844 goto basic_json_parser_4;
\r
9848 goto basic_json_parser_13;
\r
9850 goto basic_json_parser_15;
\r
9856 goto basic_json_parser_17;
\r
9860 goto basic_json_parser_4;
\r
9862 goto basic_json_parser_19;
\r
9874 goto basic_json_parser_21;
\r
9876 goto basic_json_parser_4;
\r
9882 goto basic_json_parser_23;
\r
9886 goto basic_json_parser_4;
\r
9888 goto basic_json_parser_24;
\r
9897 goto basic_json_parser_25;
\r
9899 goto basic_json_parser_4;
\r
9905 goto basic_json_parser_26;
\r
9909 goto basic_json_parser_28;
\r
9911 goto basic_json_parser_4;
\r
9915 basic_json_parser_2:
\r
9918 last_token_type = token_type::end_of_input;
\r
9921 basic_json_parser_4:
\r
9923 basic_json_parser_5:
\r
9925 last_token_type = token_type::parse_error;
\r
9928 basic_json_parser_6:
\r
9930 if (m_limit <= m_cursor)
\r
9932 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
9935 if (yybm[0 + yych] & 32)
\r
9937 goto basic_json_parser_6;
\r
9942 basic_json_parser_9:
\r
9944 yych = *(m_marker = ++m_cursor);
\r
9947 goto basic_json_parser_5;
\r
9951 goto basic_json_parser_31;
\r
9955 goto basic_json_parser_5;
\r
9959 goto basic_json_parser_31;
\r
9961 goto basic_json_parser_5;
\r
9962 basic_json_parser_10:
\r
9965 last_token_type = token_type::value_separator;
\r
9968 basic_json_parser_12:
\r
9969 yych = *++m_cursor;
\r
9972 goto basic_json_parser_5;
\r
9976 goto basic_json_parser_43;
\r
9980 goto basic_json_parser_45;
\r
9982 goto basic_json_parser_5;
\r
9983 basic_json_parser_13:
\r
9985 yych = *(m_marker = ++m_cursor);
\r
9990 goto basic_json_parser_47;
\r
9994 goto basic_json_parser_48;
\r
10003 goto basic_json_parser_51;
\r
10010 goto basic_json_parser_51;
\r
10014 basic_json_parser_14:
\r
10016 last_token_type = token_type::value_unsigned;
\r
10019 basic_json_parser_15:
\r
10021 m_marker = ++m_cursor;
\r
10022 if ((m_limit - m_cursor) < 3)
\r
10024 fill_line_buffer(3); // LCOV_EXCL_LINE
\r
10026 yych = *m_cursor;
\r
10027 if (yybm[0 + yych] & 64)
\r
10029 goto basic_json_parser_15;
\r
10035 goto basic_json_parser_47;
\r
10037 goto basic_json_parser_14;
\r
10043 goto basic_json_parser_51;
\r
10047 goto basic_json_parser_51;
\r
10049 goto basic_json_parser_14;
\r
10051 basic_json_parser_17:
\r
10054 last_token_type = token_type::name_separator;
\r
10057 basic_json_parser_19:
\r
10060 last_token_type = token_type::begin_array;
\r
10063 basic_json_parser_21:
\r
10066 last_token_type = token_type::end_array;
\r
10069 basic_json_parser_23:
\r
10071 yych = *(m_marker = ++m_cursor);
\r
10074 goto basic_json_parser_52;
\r
10076 goto basic_json_parser_5;
\r
10077 basic_json_parser_24:
\r
10079 yych = *(m_marker = ++m_cursor);
\r
10082 goto basic_json_parser_53;
\r
10084 goto basic_json_parser_5;
\r
10085 basic_json_parser_25:
\r
10087 yych = *(m_marker = ++m_cursor);
\r
10090 goto basic_json_parser_54;
\r
10092 goto basic_json_parser_5;
\r
10093 basic_json_parser_26:
\r
10096 last_token_type = token_type::begin_object;
\r
10099 basic_json_parser_28:
\r
10102 last_token_type = token_type::end_object;
\r
10105 basic_json_parser_30:
\r
10107 if (m_limit <= m_cursor)
\r
10109 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10111 yych = *m_cursor;
\r
10112 basic_json_parser_31:
\r
10113 if (yybm[0 + yych] & 128)
\r
10115 goto basic_json_parser_30;
\r
10117 if (yych <= 0xE0)
\r
10119 if (yych <= '\\')
\r
10121 if (yych <= 0x1F)
\r
10123 goto basic_json_parser_32;
\r
10127 goto basic_json_parser_33;
\r
10129 goto basic_json_parser_35;
\r
10133 if (yych <= 0xC1)
\r
10135 goto basic_json_parser_32;
\r
10137 if (yych <= 0xDF)
\r
10139 goto basic_json_parser_36;
\r
10141 goto basic_json_parser_37;
\r
10146 if (yych <= 0xEF)
\r
10148 if (yych == 0xED)
\r
10150 goto basic_json_parser_39;
\r
10152 goto basic_json_parser_38;
\r
10156 if (yych <= 0xF0)
\r
10158 goto basic_json_parser_40;
\r
10160 if (yych <= 0xF3)
\r
10162 goto basic_json_parser_41;
\r
10164 if (yych <= 0xF4)
\r
10166 goto basic_json_parser_42;
\r
10170 basic_json_parser_32:
\r
10171 m_cursor = m_marker;
\r
10172 if (yyaccept <= 1)
\r
10174 if (yyaccept == 0)
\r
10176 goto basic_json_parser_5;
\r
10180 goto basic_json_parser_14;
\r
10185 if (yyaccept == 2)
\r
10187 goto basic_json_parser_44;
\r
10191 goto basic_json_parser_58;
\r
10194 basic_json_parser_33:
\r
10197 last_token_type = token_type::value_string;
\r
10200 basic_json_parser_35:
\r
10202 if (m_limit <= m_cursor)
\r
10204 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10206 yych = *m_cursor;
\r
10213 goto basic_json_parser_30;
\r
10217 goto basic_json_parser_32;
\r
10219 goto basic_json_parser_30;
\r
10223 if (yych <= '\\')
\r
10227 goto basic_json_parser_32;
\r
10229 goto basic_json_parser_30;
\r
10235 goto basic_json_parser_30;
\r
10237 goto basic_json_parser_32;
\r
10247 goto basic_json_parser_30;
\r
10251 goto basic_json_parser_30;
\r
10253 goto basic_json_parser_32;
\r
10261 goto basic_json_parser_30;
\r
10263 goto basic_json_parser_32;
\r
10269 goto basic_json_parser_30;
\r
10273 goto basic_json_parser_55;
\r
10275 goto basic_json_parser_32;
\r
10279 basic_json_parser_36:
\r
10281 if (m_limit <= m_cursor)
\r
10283 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10285 yych = *m_cursor;
\r
10286 if (yych <= 0x7F)
\r
10288 goto basic_json_parser_32;
\r
10290 if (yych <= 0xBF)
\r
10292 goto basic_json_parser_30;
\r
10294 goto basic_json_parser_32;
\r
10295 basic_json_parser_37:
\r
10297 if (m_limit <= m_cursor)
\r
10299 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10301 yych = *m_cursor;
\r
10302 if (yych <= 0x9F)
\r
10304 goto basic_json_parser_32;
\r
10306 if (yych <= 0xBF)
\r
10308 goto basic_json_parser_36;
\r
10310 goto basic_json_parser_32;
\r
10311 basic_json_parser_38:
\r
10313 if (m_limit <= m_cursor)
\r
10315 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10317 yych = *m_cursor;
\r
10318 if (yych <= 0x7F)
\r
10320 goto basic_json_parser_32;
\r
10322 if (yych <= 0xBF)
\r
10324 goto basic_json_parser_36;
\r
10326 goto basic_json_parser_32;
\r
10327 basic_json_parser_39:
\r
10329 if (m_limit <= m_cursor)
\r
10331 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10333 yych = *m_cursor;
\r
10334 if (yych <= 0x7F)
\r
10336 goto basic_json_parser_32;
\r
10338 if (yych <= 0x9F)
\r
10340 goto basic_json_parser_36;
\r
10342 goto basic_json_parser_32;
\r
10343 basic_json_parser_40:
\r
10345 if (m_limit <= m_cursor)
\r
10347 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10349 yych = *m_cursor;
\r
10350 if (yych <= 0x8F)
\r
10352 goto basic_json_parser_32;
\r
10354 if (yych <= 0xBF)
\r
10356 goto basic_json_parser_38;
\r
10358 goto basic_json_parser_32;
\r
10359 basic_json_parser_41:
\r
10361 if (m_limit <= m_cursor)
\r
10363 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10365 yych = *m_cursor;
\r
10366 if (yych <= 0x7F)
\r
10368 goto basic_json_parser_32;
\r
10370 if (yych <= 0xBF)
\r
10372 goto basic_json_parser_38;
\r
10374 goto basic_json_parser_32;
\r
10375 basic_json_parser_42:
\r
10377 if (m_limit <= m_cursor)
\r
10379 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10381 yych = *m_cursor;
\r
10382 if (yych <= 0x7F)
\r
10384 goto basic_json_parser_32;
\r
10386 if (yych <= 0x8F)
\r
10388 goto basic_json_parser_38;
\r
10390 goto basic_json_parser_32;
\r
10391 basic_json_parser_43:
\r
10393 yych = *(m_marker = ++m_cursor);
\r
10398 goto basic_json_parser_47;
\r
10402 goto basic_json_parser_48;
\r
10411 goto basic_json_parser_51;
\r
10418 goto basic_json_parser_51;
\r
10422 basic_json_parser_44:
\r
10424 last_token_type = token_type::value_integer;
\r
10427 basic_json_parser_45:
\r
10429 m_marker = ++m_cursor;
\r
10430 if ((m_limit - m_cursor) < 3)
\r
10432 fill_line_buffer(3); // LCOV_EXCL_LINE
\r
10434 yych = *m_cursor;
\r
10439 goto basic_json_parser_47;
\r
10443 goto basic_json_parser_44;
\r
10445 goto basic_json_parser_45;
\r
10453 goto basic_json_parser_44;
\r
10455 goto basic_json_parser_51;
\r
10461 goto basic_json_parser_51;
\r
10463 goto basic_json_parser_44;
\r
10466 basic_json_parser_47:
\r
10467 yych = *++m_cursor;
\r
10470 goto basic_json_parser_32;
\r
10474 goto basic_json_parser_56;
\r
10476 goto basic_json_parser_32;
\r
10477 basic_json_parser_48:
\r
10479 if (m_limit <= m_cursor)
\r
10481 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10483 yych = *m_cursor;
\r
10486 goto basic_json_parser_50;
\r
10490 goto basic_json_parser_48;
\r
10492 basic_json_parser_50:
\r
10494 last_token_type = token_type::parse_error;
\r
10497 basic_json_parser_51:
\r
10498 yych = *++m_cursor;
\r
10503 goto basic_json_parser_59;
\r
10505 goto basic_json_parser_32;
\r
10511 goto basic_json_parser_59;
\r
10515 goto basic_json_parser_32;
\r
10519 goto basic_json_parser_60;
\r
10521 goto basic_json_parser_32;
\r
10523 basic_json_parser_52:
\r
10524 yych = *++m_cursor;
\r
10527 goto basic_json_parser_62;
\r
10529 goto basic_json_parser_32;
\r
10530 basic_json_parser_53:
\r
10531 yych = *++m_cursor;
\r
10534 goto basic_json_parser_63;
\r
10536 goto basic_json_parser_32;
\r
10537 basic_json_parser_54:
\r
10538 yych = *++m_cursor;
\r
10541 goto basic_json_parser_64;
\r
10543 goto basic_json_parser_32;
\r
10544 basic_json_parser_55:
\r
10546 if (m_limit <= m_cursor)
\r
10548 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10550 yych = *m_cursor;
\r
10555 goto basic_json_parser_32;
\r
10559 goto basic_json_parser_65;
\r
10561 goto basic_json_parser_32;
\r
10567 goto basic_json_parser_65;
\r
10571 goto basic_json_parser_32;
\r
10575 goto basic_json_parser_65;
\r
10577 goto basic_json_parser_32;
\r
10579 basic_json_parser_56:
\r
10581 m_marker = ++m_cursor;
\r
10582 if ((m_limit - m_cursor) < 3)
\r
10584 fill_line_buffer(3); // LCOV_EXCL_LINE
\r
10586 yych = *m_cursor;
\r
10591 goto basic_json_parser_58;
\r
10595 goto basic_json_parser_56;
\r
10602 goto basic_json_parser_51;
\r
10606 goto basic_json_parser_51;
\r
10609 basic_json_parser_58:
\r
10611 last_token_type = token_type::value_float;
\r
10614 basic_json_parser_59:
\r
10615 yych = *++m_cursor;
\r
10618 goto basic_json_parser_32;
\r
10622 goto basic_json_parser_32;
\r
10624 basic_json_parser_60:
\r
10626 if (m_limit <= m_cursor)
\r
10628 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10630 yych = *m_cursor;
\r
10633 goto basic_json_parser_58;
\r
10637 goto basic_json_parser_60;
\r
10639 goto basic_json_parser_58;
\r
10640 basic_json_parser_62:
\r
10641 yych = *++m_cursor;
\r
10644 goto basic_json_parser_66;
\r
10646 goto basic_json_parser_32;
\r
10647 basic_json_parser_63:
\r
10648 yych = *++m_cursor;
\r
10651 goto basic_json_parser_67;
\r
10653 goto basic_json_parser_32;
\r
10654 basic_json_parser_64:
\r
10655 yych = *++m_cursor;
\r
10658 goto basic_json_parser_69;
\r
10660 goto basic_json_parser_32;
\r
10661 basic_json_parser_65:
\r
10663 if (m_limit <= m_cursor)
\r
10665 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10667 yych = *m_cursor;
\r
10672 goto basic_json_parser_32;
\r
10676 goto basic_json_parser_71;
\r
10678 goto basic_json_parser_32;
\r
10684 goto basic_json_parser_71;
\r
10688 goto basic_json_parser_32;
\r
10692 goto basic_json_parser_71;
\r
10694 goto basic_json_parser_32;
\r
10696 basic_json_parser_66:
\r
10697 yych = *++m_cursor;
\r
10700 goto basic_json_parser_72;
\r
10702 goto basic_json_parser_32;
\r
10703 basic_json_parser_67:
\r
10706 last_token_type = token_type::literal_null;
\r
10709 basic_json_parser_69:
\r
10712 last_token_type = token_type::literal_true;
\r
10715 basic_json_parser_71:
\r
10717 if (m_limit <= m_cursor)
\r
10719 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10721 yych = *m_cursor;
\r
10726 goto basic_json_parser_32;
\r
10730 goto basic_json_parser_74;
\r
10732 goto basic_json_parser_32;
\r
10738 goto basic_json_parser_74;
\r
10742 goto basic_json_parser_32;
\r
10746 goto basic_json_parser_74;
\r
10748 goto basic_json_parser_32;
\r
10750 basic_json_parser_72:
\r
10753 last_token_type = token_type::literal_false;
\r
10756 basic_json_parser_74:
\r
10758 if (m_limit <= m_cursor)
\r
10760 fill_line_buffer(1); // LCOV_EXCL_LINE
\r
10762 yych = *m_cursor;
\r
10767 goto basic_json_parser_32;
\r
10771 goto basic_json_parser_30;
\r
10773 goto basic_json_parser_32;
\r
10779 goto basic_json_parser_30;
\r
10783 goto basic_json_parser_32;
\r
10787 goto basic_json_parser_30;
\r
10789 goto basic_json_parser_32;
\r
10795 return last_token_type;
\r
10799 @brief append data from the stream to the line buffer
\r
10801 This function is called by the scan() function when the end of the
\r
10802 buffer (`m_limit`) is reached and the `m_cursor` pointer cannot be
\r
10803 incremented without leaving the limits of the line buffer. Note re2c
\r
10804 decides when to call this function.
\r
10806 If the lexer reads from contiguous storage, there is no trailing null
\r
10807 byte. Therefore, this function must make sure to add these padding
\r
10810 If the lexer reads from an input stream, this function reads the next
\r
10811 line of the input.
\r
10814 p p p p p p u u u u u x . . . . . .
\r
10816 m_content m_start | m_limit
\r
10820 u u u u u x x x x x x x . . . . . .
\r
10822 | m_cursor m_limit
\r
10826 void fill_line_buffer(size_t n = 0)
\r
10828 // if line buffer is used, m_content points to its data
\r
10829 assert(m_line_buffer.empty()
\r
10830 or m_content == reinterpret_cast<const lexer_char_t*>(m_line_buffer.data()));
\r
10832 // if line buffer is used, m_limit is set past the end of its data
\r
10833 assert(m_line_buffer.empty()
\r
10834 or m_limit == m_content + m_line_buffer.size());
\r
10836 // pointer relationships
\r
10837 assert(m_content <= m_start);
\r
10838 assert(m_start <= m_cursor);
\r
10839 assert(m_cursor <= m_limit);
\r
10840 assert(m_marker == nullptr or m_marker <= m_limit);
\r
10842 // number of processed characters (p)
\r
10843 const auto num_processed_chars = static_cast<size_t>(m_start - m_content);
\r
10844 // offset for m_marker wrt. to m_start
\r
10845 const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start;
\r
10846 // number of unprocessed characters (u)
\r
10847 const auto offset_cursor = m_cursor - m_start;
\r
10849 // no stream is used or end of file is reached
\r
10850 if (m_stream == nullptr or m_stream->eof())
\r
10852 // m_start may or may not be pointing into m_line_buffer at
\r
10853 // this point. We trust the standard library to do the right
\r
10854 // thing. See http://stackoverflow.com/q/28142011/266378
\r
10855 m_line_buffer.assign(m_start, m_limit);
\r
10857 // append n characters to make sure that there is sufficient
\r
10858 // space between m_cursor and m_limit
\r
10859 m_line_buffer.append(1, '\x00');
\r
10862 m_line_buffer.append(n - 1, '\x01');
\r
10867 // delete processed characters from line buffer
\r
10868 m_line_buffer.erase(0, num_processed_chars);
\r
10869 // read next line from input stream
\r
10870 m_line_buffer_tmp.clear();
\r
10871 std::getline(*m_stream, m_line_buffer_tmp, '\n');
\r
10873 // add line with newline symbol to the line buffer
\r
10874 m_line_buffer += m_line_buffer_tmp;
\r
10875 m_line_buffer.push_back('\n');
\r
10879 m_content = reinterpret_cast<const lexer_char_t*>(m_line_buffer.data());
\r
10880 assert(m_content != nullptr);
\r
10881 m_start = m_content;
\r
10882 m_marker = m_start + offset_marker;
\r
10883 m_cursor = m_start + offset_cursor;
\r
10884 m_limit = m_start + m_line_buffer.size();
\r
10887 /// return string representation of last read token
\r
10888 string_t get_token_string() const
\r
10890 assert(m_start != nullptr);
\r
10891 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
\r
10892 static_cast<size_t>(m_cursor - m_start));
\r
10896 @brief return string value for string tokens
\r
10898 The function iterates the characters between the opening and closing
\r
10899 quotes of the string value. The complete string is the range
\r
10900 [m_start,m_cursor). Consequently, we iterate from m_start+1 to
\r
10903 We differentiate two cases:
\r
10905 1. Escaped characters. In this case, a new character is constructed
\r
10906 according to the nature of the escape. Some escapes create new
\r
10907 characters (e.g., `"\\n"` is replaced by `"\n"`), some are copied
\r
10908 as is (e.g., `"\\\\"`). Furthermore, Unicode escapes of the shape
\r
10909 `"\\uxxxx"` need special care. In this case, to_unicode takes care
\r
10910 of the construction of the values.
\r
10911 2. Unescaped characters are copied as is.
\r
10913 @pre `m_cursor - m_start >= 2`, meaning the length of the last token
\r
10914 is at least 2 bytes which is trivially true for any string (which
\r
10915 consists of at least two quotes).
\r
10921 @complexity Linear in the length of the string.\n
\r
10923 Lemma: The loop body will always terminate.\n
\r
10925 Proof (by contradiction): Assume the loop body does not terminate. As
\r
10926 the loop body does not contain another loop, one of the called
\r
10927 functions must never return. The called functions are `std::strtoul`
\r
10928 and to_unicode. Neither function can loop forever, so the loop body
\r
10929 will never loop forever which contradicts the assumption that the loop
\r
10930 body does not terminate, q.e.d.\n
\r
10932 Lemma: The loop condition for the for loop is eventually false.\n
\r
10934 Proof (by contradiction): Assume the loop does not terminate. Due to
\r
10935 the above lemma, this can only be due to a tautological loop
\r
10936 condition; that is, the loop condition i < m_cursor - 1 must always be
\r
10937 true. Let x be the change of i for any loop iteration. Then
\r
10938 m_start + 1 + x < m_cursor - 1 must hold to loop indefinitely. This
\r
10939 can be rephrased to m_cursor - m_start - 2 > x. With the
\r
10940 precondition, we x <= 0, meaning that the loop condition holds
\r
10941 indefinitely if i is always decreased. However, observe that the value
\r
10942 of i is strictly increasing with each iteration, as it is incremented
\r
10943 by 1 in the iteration expression and never decremented inside the loop
\r
10944 body. Hence, the loop condition will eventually be false which
\r
10945 contradicts the assumption that the loop condition is a tautology,
\r
10948 @return string value of current token without opening and closing
\r
10950 @throw std::out_of_range if to_unicode fails
\r
10952 string_t get_string() const
\r
10954 assert(m_cursor - m_start >= 2);
\r
10957 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
\r
10959 // iterate the result between the quotes
\r
10960 for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
\r
10962 // find next escape character
\r
10963 auto e = std::find(i, m_cursor - 1, '\\');
\r
10966 // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705
\r
10967 for (auto k = i; k < e; k++)
\r
10969 result.push_back(static_cast<typename string_t::value_type>(*k));
\r
10971 i = e - 1; // -1 because of ++i
\r
10975 // processing escaped character
\r
10976 // read next character
\r
10981 // the default escapes
\r
11026 // get code xxxx from uxxxx
\r
11027 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
\r
11028 4).c_str(), nullptr, 16);
\r
11030 // check if codepoint is a high surrogate
\r
11031 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
\r
11033 // make sure there is a subsequent unicode
\r
11034 if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
\r
11036 JSON_THROW(std::invalid_argument("missing low surrogate"));
\r
11039 // get code yyyy from uxxxx\uyyyy
\r
11040 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
\r
11041 (i + 7), 4).c_str(), nullptr, 16);
\r
11042 result += to_unicode(codepoint, codepoint2);
\r
11043 // skip the next 10 characters (xxxx\uyyyy)
\r
11046 else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
\r
11048 // we found a lone low surrogate
\r
11049 JSON_THROW(std::invalid_argument("missing high surrogate"));
\r
11053 // add unicode character(s)
\r
11054 result += to_unicode(codepoint);
\r
11055 // skip the next four characters (xxxx)
\r
11069 @brief parse string into a built-in arithmetic type as if the current
\r
11072 @note in floating-point case strtod may parse past the token's end -
\r
11073 this is not an error
\r
11075 @note any leading blanks are not handled
\r
11080 strtonum(const char* start, const char* end)
\r
11081 : m_start(start), m_end(end)
\r
11085 @return true iff parsed successfully as number of type T
\r
11087 @param[in,out] val shall contain parsed value, or undefined value
\r
11088 if could not parse
\r
11090 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
\r
11091 bool to(T& val) const
\r
11093 return parse(val, std::is_integral<T>());
\r
11097 const char* const m_start = nullptr;
\r
11098 const char* const m_end = nullptr;
\r
11100 // floating-point conversion
\r
11102 // overloaded wrappers for strtod/strtof/strtold
\r
11103 // that will be called from parse<floating_point_t>
\r
11104 static void strtof(float& f, const char* str, char** endptr)
\r
11106 f = std::strtof(str, endptr);
\r
11109 static void strtof(double& f, const char* str, char** endptr)
\r
11111 f = std::strtod(str, endptr);
\r
11114 static void strtof(long double& f, const char* str, char** endptr)
\r
11116 f = std::strtold(str, endptr);
\r
11119 template<typename T>
\r
11120 bool parse(T& value, /*is_integral=*/std::false_type) const
\r
11122 // replace decimal separator with locale-specific version,
\r
11123 // when necessary; data will point to either the original
\r
11124 // string, or buf, or tempstr containing the fixed string.
\r
11125 std::string tempstr;
\r
11126 std::array<char, 64> buf;
\r
11127 const size_t len = static_cast<size_t>(m_end - m_start);
\r
11129 // lexer will reject empty numbers
\r
11132 // since dealing with strtod family of functions, we're
\r
11133 // getting the decimal point char from the C locale facilities
\r
11134 // instead of C++'s numpunct facet of the current std::locale
\r
11135 const auto loc = localeconv();
\r
11136 assert(loc != nullptr);
\r
11137 const char decimal_point_char = (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
\r
11139 const char* data = m_start;
\r
11141 if (decimal_point_char != '.')
\r
11143 const size_t ds_pos = static_cast<size_t>(std::find(m_start, m_end, '.') - m_start);
\r
11145 if (ds_pos != len)
\r
11147 // copy the data into the local buffer or tempstr, if
\r
11148 // buffer is too small; replace decimal separator, and
\r
11149 // update data to point to the modified bytes
\r
11150 if ((len + 1) < buf.size())
\r
11152 std::copy(m_start, m_end, buf.begin());
\r
11154 buf[ds_pos] = decimal_point_char;
\r
11155 data = buf.data();
\r
11159 tempstr.assign(m_start, m_end);
\r
11160 tempstr[ds_pos] = decimal_point_char;
\r
11161 data = tempstr.c_str();
\r
11166 char* endptr = nullptr;
\r
11168 // this calls appropriate overload depending on T
\r
11169 strtof(value, data, &endptr);
\r
11171 // parsing was successful iff strtof parsed exactly the number
\r
11172 // of characters determined by the lexer (len)
\r
11173 const bool ok = (endptr == (data + len));
\r
11175 if (ok and (value == static_cast<T>(0.0)) and (*data == '-'))
\r
11177 // some implementations forget to negate the zero
\r
11184 // integral conversion
\r
11186 signed long long parse_integral(char** endptr, /*is_signed*/std::true_type) const
\r
11188 return std::strtoll(m_start, endptr, 10);
\r
11191 unsigned long long parse_integral(char** endptr, /*is_signed*/std::false_type) const
\r
11193 return std::strtoull(m_start, endptr, 10);
\r
11196 template<typename T>
\r
11197 bool parse(T& value, /*is_integral=*/std::true_type) const
\r
11199 char* endptr = nullptr;
\r
11200 errno = 0; // these are thread-local
\r
11201 const auto x = parse_integral(&endptr, std::is_signed<T>());
\r
11203 // called right overload?
\r
11204 static_assert(std::is_signed<T>() == std::is_signed<decltype(x)>(), "");
\r
11206 value = static_cast<T>(x);
\r
11208 return (x == static_cast<decltype(x)>(value)) // x fits into destination T
\r
11209 and (x < 0) == (value < 0) // preserved sign
\r
11210 //and ((x != 0) or is_integral()) // strto[u]ll did nto fail
\r
11211 and (errno == 0) // strto[u]ll did not overflow
\r
11212 and (m_start < m_end) // token was not empty
\r
11213 and (endptr == m_end); // parsed entire token exactly
\r
11218 @brief return number value for number tokens
\r
11220 This function translates the last token into the most appropriate
\r
11221 number type (either integer, unsigned integer or floating point),
\r
11222 which is passed back to the caller via the result parameter.
\r
11224 integral numbers that don't fit into the the range of the respective
\r
11225 type are parsed as number_float_t
\r
11227 floating-point values do not satisfy std::isfinite predicate
\r
11228 are converted to value_t::null
\r
11230 throws if the entire string [m_start .. m_cursor) cannot be
\r
11231 interpreted as a number
\r
11233 @param[out] result @ref basic_json object to receive the number.
\r
11234 @param[in] token the type of the number token
\r
11236 bool get_number(basic_json& result, const token_type token) const
\r
11238 assert(m_start != nullptr);
\r
11239 assert(m_start < m_cursor);
\r
11240 assert((token == token_type::value_unsigned) or
\r
11241 (token == token_type::value_integer) or
\r
11242 (token == token_type::value_float));
\r
11244 strtonum num_converter(reinterpret_cast<const char*>(m_start),
\r
11245 reinterpret_cast<const char*>(m_cursor));
\r
11249 case lexer::token_type::value_unsigned:
\r
11251 number_unsigned_t val;
\r
11252 if (num_converter.to(val))
\r
11254 // parsing successful
\r
11255 result.m_type = value_t::number_unsigned;
\r
11256 result.m_value = val;
\r
11262 case lexer::token_type::value_integer:
\r
11264 number_integer_t val;
\r
11265 if (num_converter.to(val))
\r
11267 // parsing successful
\r
11268 result.m_type = value_t::number_integer;
\r
11269 result.m_value = val;
\r
11281 // parse float (either explicitly or because a previous conversion
\r
11283 number_float_t val;
\r
11284 if (num_converter.to(val))
\r
11286 // parsing successful
\r
11287 result.m_type = value_t::number_float;
\r
11288 result.m_value = val;
\r
11290 // replace infinity and NAN by null
\r
11291 if (not std::isfinite(result.m_value.number_float))
\r
11293 result.m_type = value_t::null;
\r
11294 result.m_value = basic_json::json_value();
\r
11300 // couldn't parse number in any format
\r
11305 /// optional input stream
\r
11306 std::istream* m_stream = nullptr;
\r
11307 /// line buffer buffer for m_stream
\r
11308 string_t m_line_buffer {};
\r
11309 /// used for filling m_line_buffer
\r
11310 string_t m_line_buffer_tmp {};
\r
11311 /// the buffer pointer
\r
11312 const lexer_char_t* m_content = nullptr;
\r
11313 /// pointer to the beginning of the current symbol
\r
11314 const lexer_char_t* m_start = nullptr;
\r
11315 /// pointer for backtracking information
\r
11316 const lexer_char_t* m_marker = nullptr;
\r
11317 /// pointer to the current symbol
\r
11318 const lexer_char_t* m_cursor = nullptr;
\r
11319 /// pointer to the end of the buffer
\r
11320 const lexer_char_t* m_limit = nullptr;
\r
11321 /// the last token type
\r
11322 token_type last_token_type = token_type::end_of_input;
\r
11326 @brief syntax analysis
\r
11328 This class implements a recursive decent parser.
\r
11333 /// a parser reading from a string literal
\r
11334 parser(const char* buff, const parser_callback_t cb = nullptr)
\r
11336 m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), std::strlen(buff))
\r
11339 /// a parser reading from an input stream
\r
11340 parser(std::istream& is, const parser_callback_t cb = nullptr)
\r
11341 : callback(cb), m_lexer(is)
\r
11344 /// a parser reading from an iterator range with contiguous storage
\r
11345 template<class IteratorType, typename std::enable_if<
\r
11346 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
\r
11349 parser(IteratorType first, IteratorType last, const parser_callback_t cb = nullptr)
\r
11351 m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(&(*first)),
\r
11352 static_cast<size_t>(std::distance(first, last)))
\r
11355 /// public parser interface
\r
11356 basic_json parse()
\r
11358 // read first token
\r
11361 basic_json result = parse_internal(true);
\r
11362 result.assert_invariant();
\r
11364 expect(lexer::token_type::end_of_input);
\r
11366 // return parser result and replace it with null in case the
\r
11367 // top-level value was discarded by the callback function
\r
11368 return result.is_discarded() ? basic_json() : std::move(result);
\r
11372 /// the actual parser
\r
11373 basic_json parse_internal(bool keep)
\r
11375 auto result = basic_json(value_t::discarded);
\r
11377 switch (last_token)
\r
11379 case lexer::token_type::begin_object:
\r
11381 if (keep and (not callback
\r
11382 or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
\r
11384 // explicitly set result to object to cope with {}
\r
11385 result.m_type = value_t::object;
\r
11386 result.m_value = value_t::object;
\r
11389 // read next token
\r
11392 // closing } -> we are done
\r
11393 if (last_token == lexer::token_type::end_object)
\r
11396 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
\r
11398 result = basic_json(value_t::discarded);
\r
11403 // no comma is expected here
\r
11404 unexpect(lexer::token_type::value_separator);
\r
11406 // otherwise: parse key-value pairs
\r
11409 // ugly, but could be fixed with loop reorganization
\r
11410 if (last_token == lexer::token_type::value_separator)
\r
11416 expect(lexer::token_type::value_string);
\r
11417 const auto key = m_lexer.get_string();
\r
11419 bool keep_tag = false;
\r
11424 basic_json k(key);
\r
11425 keep_tag = callback(depth, parse_event_t::key, k);
\r
11433 // parse separator (:)
\r
11435 expect(lexer::token_type::name_separator);
\r
11437 // parse and add value
\r
11439 auto value = parse_internal(keep);
\r
11440 if (keep and keep_tag and not value.is_discarded())
\r
11442 result[key] = std::move(value);
\r
11445 while (last_token == lexer::token_type::value_separator);
\r
11448 expect(lexer::token_type::end_object);
\r
11450 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
\r
11452 result = basic_json(value_t::discarded);
\r
11458 case lexer::token_type::begin_array:
\r
11460 if (keep and (not callback
\r
11461 or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
\r
11463 // explicitly set result to object to cope with []
\r
11464 result.m_type = value_t::array;
\r
11465 result.m_value = value_t::array;
\r
11468 // read next token
\r
11471 // closing ] -> we are done
\r
11472 if (last_token == lexer::token_type::end_array)
\r
11475 if (callback and not callback(--depth, parse_event_t::array_end, result))
\r
11477 result = basic_json(value_t::discarded);
\r
11482 // no comma is expected here
\r
11483 unexpect(lexer::token_type::value_separator);
\r
11485 // otherwise: parse values
\r
11488 // ugly, but could be fixed with loop reorganization
\r
11489 if (last_token == lexer::token_type::value_separator)
\r
11495 auto value = parse_internal(keep);
\r
11496 if (keep and not value.is_discarded())
\r
11498 result.push_back(std::move(value));
\r
11501 while (last_token == lexer::token_type::value_separator);
\r
11504 expect(lexer::token_type::end_array);
\r
11506 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
\r
11508 result = basic_json(value_t::discarded);
\r
11514 case lexer::token_type::literal_null:
\r
11517 result.m_type = value_t::null;
\r
11521 case lexer::token_type::value_string:
\r
11523 const auto s = m_lexer.get_string();
\r
11525 result = basic_json(s);
\r
11529 case lexer::token_type::literal_true:
\r
11532 result.m_type = value_t::boolean;
\r
11533 result.m_value = true;
\r
11537 case lexer::token_type::literal_false:
\r
11540 result.m_type = value_t::boolean;
\r
11541 result.m_value = false;
\r
11545 case lexer::token_type::value_unsigned:
\r
11546 case lexer::token_type::value_integer:
\r
11547 case lexer::token_type::value_float:
\r
11549 m_lexer.get_number(result, last_token);
\r
11556 // the last token was unexpected
\r
11557 unexpect(last_token);
\r
11561 if (keep and callback and not callback(depth, parse_event_t::value, result))
\r
11563 result = basic_json(value_t::discarded);
\r
11568 /// get next token from lexer
\r
11569 typename lexer::token_type get_token()
\r
11571 last_token = m_lexer.scan();
\r
11572 return last_token;
\r
11575 void expect(typename lexer::token_type t) const
\r
11577 if (t != last_token)
\r
11579 std::string error_msg = "parse error - unexpected ";
\r
11580 error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
\r
11582 lexer::token_type_name(last_token));
\r
11583 error_msg += "; expected " + lexer::token_type_name(t);
\r
11584 JSON_THROW(std::invalid_argument(error_msg));
\r
11588 void unexpect(typename lexer::token_type t) const
\r
11590 if (t == last_token)
\r
11592 std::string error_msg = "parse error - unexpected ";
\r
11593 error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
\r
11595 lexer::token_type_name(last_token));
\r
11596 JSON_THROW(std::invalid_argument(error_msg));
\r
11601 /// current level of recursion
\r
11603 /// callback function
\r
11604 const parser_callback_t callback = nullptr;
\r
11605 /// the type of the last read token
\r
11606 typename lexer::token_type last_token = lexer::token_type::uninitialized;
\r
11613 @brief JSON Pointer
\r
11615 A JSON pointer defines a string syntax for identifying a specific value
\r
11616 within a JSON document. It can be used with functions `at` and
\r
11617 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
\r
11619 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
\r
11621 @since version 2.0.0
\r
11623 class json_pointer
\r
11625 /// allow basic_json to access private members
\r
11626 friend class basic_json;
\r
11630 @brief create JSON pointer
\r
11632 Create a JSON pointer according to the syntax described in
\r
11633 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
\r
11635 @param[in] s string representing the JSON pointer; if omitted, the
\r
11636 empty string is assumed which references the whole JSON
\r
11639 @throw std::domain_error if reference token is nonempty and does not
\r
11640 begin with a slash (`/`); example: `"JSON pointer must be empty or
\r
11642 @throw std::domain_error if a tilde (`~`) is not followed by `0`
\r
11643 (representing `~`) or `1` (representing `/`); example: `"escape error:
\r
11644 ~ must be followed with 0 or 1"`
\r
11646 @liveexample{The example shows the construction several valid JSON
\r
11647 pointers as well as the exceptional behavior.,json_pointer}
\r
11649 @since version 2.0.0
\r
11651 explicit json_pointer(const std::string& s = "")
\r
11652 : reference_tokens(split(s))
\r
11656 @brief return a string representation of the JSON pointer
\r
11658 @invariant For each JSON pointer `ptr`, it holds:
\r
11660 ptr == json_pointer(ptr.to_string());
\r
11663 @return a string representation of the JSON pointer
\r
11665 @liveexample{The example shows the result of `to_string`.,
\r
11666 json_pointer__to_string}
\r
11668 @since version 2.0.0
\r
11670 std::string to_string() const noexcept
\r
11672 return std::accumulate(reference_tokens.begin(),
\r
11673 reference_tokens.end(), std::string{},
\r
11674 [](const std::string & a, const std::string & b)
\r
11676 return a + "/" + escape(b);
\r
11680 /// @copydoc to_string()
\r
11681 operator std::string() const
\r
11683 return to_string();
\r
11687 /// remove and return last reference pointer
\r
11688 std::string pop_back()
\r
11692 JSON_THROW(std::domain_error("JSON pointer has no parent"));
\r
11695 auto last = reference_tokens.back();
\r
11696 reference_tokens.pop_back();
\r
11700 /// return whether pointer points to the root document
\r
11701 bool is_root() const
\r
11703 return reference_tokens.empty();
\r
11706 json_pointer top() const
\r
11710 JSON_THROW(std::domain_error("JSON pointer has no parent"));
\r
11713 json_pointer result = *this;
\r
11714 result.reference_tokens = {reference_tokens[0]};
\r
11719 @brief create and return a reference to the pointed to value
\r
11721 @complexity Linear in the number of reference tokens.
\r
11723 reference get_and_create(reference j) const
\r
11725 pointer result = &j;
\r
11727 // in case no reference tokens exist, return a reference to the
\r
11728 // JSON value j which will be overwritten by a primitive value
\r
11729 for (const auto& reference_token : reference_tokens)
\r
11731 switch (result->m_type)
\r
11733 case value_t::null:
\r
11735 if (reference_token == "0")
\r
11737 // start a new array if reference token is 0
\r
11738 result = &result->operator[](0);
\r
11742 // start a new object otherwise
\r
11743 result = &result->operator[](reference_token);
\r
11748 case value_t::object:
\r
11750 // create an entry in the object
\r
11751 result = &result->operator[](reference_token);
\r
11755 case value_t::array:
\r
11757 // create an entry in the array
\r
11758 result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
\r
11763 The following code is only reached if there exists a
\r
11764 reference token _and_ the current value is primitive. In
\r
11765 this case, we have an error situation, because primitive
\r
11766 values may only occur as single value; that is, with an
\r
11767 empty list of reference tokens.
\r
11771 JSON_THROW(std::domain_error("invalid value to unflatten"));
\r
11780 @brief return a reference to the pointed to value
\r
11782 @note This version does not throw if a value is not present, but tries
\r
11783 to create nested values instead. For instance, calling this function
\r
11784 with pointer `"/this/that"` on a null value is equivalent to calling
\r
11785 `operator[]("this").operator[]("that")` on that value, effectively
\r
11786 changing the null value to an object.
\r
11788 @param[in] ptr a JSON value
\r
11790 @return reference to the JSON value pointed to by the JSON pointer
\r
11792 @complexity Linear in the length of the JSON pointer.
\r
11794 @throw std::out_of_range if the JSON pointer can not be resolved
\r
11795 @throw std::domain_error if an array index begins with '0'
\r
11796 @throw std::invalid_argument if an array index was not a number
\r
11798 reference get_unchecked(pointer ptr) const
\r
11800 for (const auto& reference_token : reference_tokens)
\r
11802 // convert null values to arrays or objects before continuing
\r
11803 if (ptr->m_type == value_t::null)
\r
11805 // check if reference token is a number
\r
11806 const bool nums = std::all_of(reference_token.begin(),
\r
11807 reference_token.end(),
\r
11810 return std::isdigit(x);
\r
11813 // change value to array for numbers or "-" or to object
\r
11815 if (nums or reference_token == "-")
\r
11817 *ptr = value_t::array;
\r
11821 *ptr = value_t::object;
\r
11825 switch (ptr->m_type)
\r
11827 case value_t::object:
\r
11829 // use unchecked object access
\r
11830 ptr = &ptr->operator[](reference_token);
\r
11834 case value_t::array:
\r
11836 // error condition (cf. RFC 6901, Sect. 4)
\r
11837 if (reference_token.size() > 1 and reference_token[0] == '0')
\r
11839 JSON_THROW(std::domain_error("array index must not begin with '0'"));
\r
11842 if (reference_token == "-")
\r
11844 // explicitly treat "-" as index beyond the end
\r
11845 ptr = &ptr->operator[](ptr->m_value.array->size());
\r
11849 // convert array index to number; unchecked access
\r
11850 ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
\r
11857 JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
\r
11865 reference get_checked(pointer ptr) const
\r
11867 for (const auto& reference_token : reference_tokens)
\r
11869 switch (ptr->m_type)
\r
11871 case value_t::object:
\r
11873 // note: at performs range check
\r
11874 ptr = &ptr->at(reference_token);
\r
11878 case value_t::array:
\r
11880 if (reference_token == "-")
\r
11882 // "-" always fails the range check
\r
11883 JSON_THROW(std::out_of_range("array index '-' (" +
\r
11884 std::to_string(ptr->m_value.array->size()) +
\r
11885 ") is out of range"));
\r
11888 // error condition (cf. RFC 6901, Sect. 4)
\r
11889 if (reference_token.size() > 1 and reference_token[0] == '0')
\r
11891 JSON_THROW(std::domain_error("array index must not begin with '0'"));
\r
11894 // note: at performs range check
\r
11895 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
\r
11901 JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
\r
11910 @brief return a const reference to the pointed to value
\r
11912 @param[in] ptr a JSON value
\r
11914 @return const reference to the JSON value pointed to by the JSON
\r
11917 const_reference get_unchecked(const_pointer ptr) const
\r
11919 for (const auto& reference_token : reference_tokens)
\r
11921 switch (ptr->m_type)
\r
11923 case value_t::object:
\r
11925 // use unchecked object access
\r
11926 ptr = &ptr->operator[](reference_token);
\r
11930 case value_t::array:
\r
11932 if (reference_token == "-")
\r
11934 // "-" cannot be used for const access
\r
11935 JSON_THROW(std::out_of_range("array index '-' (" +
\r
11936 std::to_string(ptr->m_value.array->size()) +
\r
11937 ") is out of range"));
\r
11940 // error condition (cf. RFC 6901, Sect. 4)
\r
11941 if (reference_token.size() > 1 and reference_token[0] == '0')
\r
11943 JSON_THROW(std::domain_error("array index must not begin with '0'"));
\r
11946 // use unchecked array access
\r
11947 ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
\r
11953 JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
\r
11961 const_reference get_checked(const_pointer ptr) const
\r
11963 for (const auto& reference_token : reference_tokens)
\r
11965 switch (ptr->m_type)
\r
11967 case value_t::object:
\r
11969 // note: at performs range check
\r
11970 ptr = &ptr->at(reference_token);
\r
11974 case value_t::array:
\r
11976 if (reference_token == "-")
\r
11978 // "-" always fails the range check
\r
11979 JSON_THROW(std::out_of_range("array index '-' (" +
\r
11980 std::to_string(ptr->m_value.array->size()) +
\r
11981 ") is out of range"));
\r
11984 // error condition (cf. RFC 6901, Sect. 4)
\r
11985 if (reference_token.size() > 1 and reference_token[0] == '0')
\r
11987 JSON_THROW(std::domain_error("array index must not begin with '0'"));
\r
11990 // note: at performs range check
\r
11991 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
\r
11997 JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
\r
12005 /// split the string input to reference tokens
\r
12006 static std::vector<std::string> split(const std::string& reference_string)
\r
12008 std::vector<std::string> result;
\r
12010 // special case: empty reference string -> no reference tokens
\r
12011 if (reference_string.empty())
\r
12016 // check if nonempty reference string begins with slash
\r
12017 if (reference_string[0] != '/')
\r
12019 JSON_THROW(std::domain_error("JSON pointer must be empty or begin with '/'"));
\r
12022 // extract the reference tokens:
\r
12023 // - slash: position of the last read slash (or end of string)
\r
12024 // - start: position after the previous slash
\r
12026 // search for the first slash after the first character
\r
12027 size_t slash = reference_string.find_first_of('/', 1),
\r
12028 // set the beginning of the first reference token
\r
12030 // we can stop if start == string::npos+1 = 0
\r
12032 // set the beginning of the next reference token
\r
12033 // (will eventually be 0 if slash == std::string::npos)
\r
12034 start = slash + 1,
\r
12035 // find next slash
\r
12036 slash = reference_string.find_first_of('/', start))
\r
12038 // use the text between the beginning of the reference token
\r
12039 // (start) and the last slash (slash).
\r
12040 auto reference_token = reference_string.substr(start, slash - start);
\r
12042 // check reference tokens are properly escaped
\r
12043 for (size_t pos = reference_token.find_first_of('~');
\r
12044 pos != std::string::npos;
\r
12045 pos = reference_token.find_first_of('~', pos + 1))
\r
12047 assert(reference_token[pos] == '~');
\r
12049 // ~ must be followed by 0 or 1
\r
12050 if (pos == reference_token.size() - 1 or
\r
12051 (reference_token[pos + 1] != '0' and
\r
12052 reference_token[pos + 1] != '1'))
\r
12054 JSON_THROW(std::domain_error("escape error: '~' must be followed with '0' or '1'"));
\r
12058 // finally, store the reference token
\r
12059 unescape(reference_token);
\r
12060 result.push_back(reference_token);
\r
12068 @brief replace all occurrences of a substring by another string
\r
12070 @param[in,out] s the string to manipulate; changed so that all
\r
12071 occurrences of @a f are replaced with @a t
\r
12072 @param[in] f the substring to replace with @a t
\r
12073 @param[in] t the string to replace @a f
\r
12075 @pre The search string @a f must not be empty.
\r
12077 @since version 2.0.0
\r
12079 static void replace_substring(std::string& s,
\r
12080 const std::string& f,
\r
12081 const std::string& t)
\r
12083 assert(not f.empty());
\r
12086 size_t pos = s.find(f); // find first occurrence of f
\r
12087 pos != std::string::npos; // make sure f was found
\r
12088 s.replace(pos, f.size(), t), // replace with t
\r
12089 pos = s.find(f, pos + t.size()) // find next occurrence of f
\r
12093 /// escape tilde and slash
\r
12094 static std::string escape(std::string s)
\r
12096 // escape "~"" to "~0" and "/" to "~1"
\r
12097 replace_substring(s, "~", "~0");
\r
12098 replace_substring(s, "/", "~1");
\r
12102 /// unescape tilde and slash
\r
12103 static void unescape(std::string& s)
\r
12105 // first transform any occurrence of the sequence '~1' to '/'
\r
12106 replace_substring(s, "~1", "/");
\r
12107 // then transform any occurrence of the sequence '~0' to '~'
\r
12108 replace_substring(s, "~0", "~");
\r
12112 @param[in] reference_string the reference string to the current value
\r
12113 @param[in] value the value to consider
\r
12114 @param[in,out] result the result object to insert values to
\r
12116 @note Empty objects or arrays are flattened to `null`.
\r
12118 static void flatten(const std::string& reference_string,
\r
12119 const basic_json& value,
\r
12120 basic_json& result)
\r
12122 switch (value.m_type)
\r
12124 case value_t::array:
\r
12126 if (value.m_value.array->empty())
\r
12128 // flatten empty array as null
\r
12129 result[reference_string] = nullptr;
\r
12133 // iterate array and use index as reference string
\r
12134 for (size_t i = 0; i < value.m_value.array->size(); ++i)
\r
12136 flatten(reference_string + "/" + std::to_string(i),
\r
12137 value.m_value.array->operator[](i), result);
\r
12143 case value_t::object:
\r
12145 if (value.m_value.object->empty())
\r
12147 // flatten empty object as null
\r
12148 result[reference_string] = nullptr;
\r
12152 // iterate object and use keys as reference string
\r
12153 for (const auto& element : *value.m_value.object)
\r
12155 flatten(reference_string + "/" + escape(element.first),
\r
12156 element.second, result);
\r
12164 // add primitive value with its reference string
\r
12165 result[reference_string] = value;
\r
12172 @param[in] value flattened JSON
\r
12174 @return unflattened JSON
\r
12176 static basic_json unflatten(const basic_json& value)
\r
12178 if (not value.is_object())
\r
12180 JSON_THROW(std::domain_error("only objects can be unflattened"));
\r
12183 basic_json result;
\r
12185 // iterate the JSON object values
\r
12186 for (const auto& element : *value.m_value.object)
\r
12188 if (not element.second.is_primitive())
\r
12190 JSON_THROW(std::domain_error("values in object must be primitive"));
\r
12193 // assign value to reference pointed to by JSON pointer; Note
\r
12194 // that if the JSON pointer is "" (i.e., points to the whole
\r
12195 // value), function get_and_create returns a reference to
\r
12196 // result itself. An assignment will then create a primitive
\r
12198 json_pointer(element.first).get_and_create(result) = element.second;
\r
12205 friend bool operator==(json_pointer const& lhs,
\r
12206 json_pointer const& rhs) noexcept
\r
12208 return lhs.reference_tokens == rhs.reference_tokens;
\r
12211 friend bool operator!=(json_pointer const& lhs,
\r
12212 json_pointer const& rhs) noexcept
\r
12214 return !(lhs == rhs);
\r
12217 /// the reference tokens
\r
12218 std::vector<std::string> reference_tokens {};
\r
12221 //////////////////////////
\r
12222 // JSON Pointer support //
\r
12223 //////////////////////////
\r
12225 /// @name JSON Pointer functions
\r
12229 @brief access specified element via JSON Pointer
\r
12231 Uses a JSON pointer to retrieve a reference to the respective JSON value.
\r
12232 No bound checking is performed. Similar to @ref operator[](const typename
\r
12233 object_t::key_type&), `null` values are created in arrays and objects if
\r
12237 - If the JSON pointer points to an object key that does not exist, it
\r
12238 is created an filled with a `null` value before a reference to it
\r
12240 - If the JSON pointer points to an array index that does not exist, it
\r
12241 is created an filled with a `null` value before a reference to it
\r
12242 is returned. All indices between the current maximum and the given
\r
12243 index are also filled with `null`.
\r
12244 - The special value `-` is treated as a synonym for the index past the
\r
12247 @param[in] ptr a JSON pointer
\r
12249 @return reference to the element pointed to by @a ptr
\r
12251 @complexity Constant.
\r
12253 @throw std::out_of_range if the JSON pointer can not be resolved
\r
12254 @throw std::domain_error if an array index begins with '0'
\r
12255 @throw std::invalid_argument if an array index was not a number
\r
12257 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
\r
12259 @since version 2.0.0
\r
12261 reference operator[](const json_pointer& ptr)
\r
12263 return ptr.get_unchecked(this);
\r
12267 @brief access specified element via JSON Pointer
\r
12269 Uses a JSON pointer to retrieve a reference to the respective JSON value.
\r
12270 No bound checking is performed. The function does not change the JSON
\r
12271 value; no `null` values are created. In particular, the the special value
\r
12272 `-` yields an exception.
\r
12274 @param[in] ptr JSON pointer to the desired element
\r
12276 @return const reference to the element pointed to by @a ptr
\r
12278 @complexity Constant.
\r
12280 @throw std::out_of_range if the JSON pointer can not be resolved
\r
12281 @throw std::domain_error if an array index begins with '0'
\r
12282 @throw std::invalid_argument if an array index was not a number
\r
12284 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
\r
12286 @since version 2.0.0
\r
12288 const_reference operator[](const json_pointer& ptr) const
\r
12290 return ptr.get_unchecked(this);
\r
12294 @brief access specified element via JSON Pointer
\r
12296 Returns a reference to the element at with specified JSON pointer @a ptr,
\r
12297 with bounds checking.
\r
12299 @param[in] ptr JSON pointer to the desired element
\r
12301 @return reference to the element pointed to by @a ptr
\r
12303 @complexity Constant.
\r
12305 @throw std::out_of_range if the JSON pointer can not be resolved
\r
12306 @throw std::domain_error if an array index begins with '0'
\r
12307 @throw std::invalid_argument if an array index was not a number
\r
12309 @liveexample{The behavior is shown in the example.,at_json_pointer}
\r
12311 @since version 2.0.0
\r
12313 reference at(const json_pointer& ptr)
\r
12315 return ptr.get_checked(this);
\r
12319 @brief access specified element via JSON Pointer
\r
12321 Returns a const reference to the element at with specified JSON pointer @a
\r
12322 ptr, with bounds checking.
\r
12324 @param[in] ptr JSON pointer to the desired element
\r
12326 @return reference to the element pointed to by @a ptr
\r
12328 @complexity Constant.
\r
12330 @throw std::out_of_range if the JSON pointer can not be resolved
\r
12331 @throw std::domain_error if an array index begins with '0'
\r
12332 @throw std::invalid_argument if an array index was not a number
\r
12334 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
\r
12336 @since version 2.0.0
\r
12338 const_reference at(const json_pointer& ptr) const
\r
12340 return ptr.get_checked(this);
\r
12344 @brief return flattened JSON value
\r
12346 The function creates a JSON object whose keys are JSON pointers (see [RFC
\r
12347 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
\r
12348 primitive. The original JSON value can be restored using the @ref
\r
12349 unflatten() function.
\r
12351 @return an object that maps JSON pointers to primitive values
\r
12353 @note Empty objects and arrays are flattened to `null` and will not be
\r
12354 reconstructed correctly by the @ref unflatten() function.
\r
12356 @complexity Linear in the size the JSON value.
\r
12358 @liveexample{The following code shows how a JSON object is flattened to an
\r
12359 object whose keys consist of JSON pointers.,flatten}
\r
12361 @sa @ref unflatten() for the reverse function
\r
12363 @since version 2.0.0
\r
12365 basic_json flatten() const
\r
12367 basic_json result(value_t::object);
\r
12368 json_pointer::flatten("", *this, result);
\r
12373 @brief unflatten a previously flattened JSON value
\r
12375 The function restores the arbitrary nesting of a JSON value that has been
\r
12376 flattened before using the @ref flatten() function. The JSON value must
\r
12377 meet certain constraints:
\r
12378 1. The value must be an object.
\r
12379 2. The keys must be JSON pointers (see
\r
12380 [RFC 6901](https://tools.ietf.org/html/rfc6901))
\r
12381 3. The mapped values must be primitive JSON types.
\r
12383 @return the original JSON from a flattened version
\r
12385 @note Empty objects and arrays are flattened by @ref flatten() to `null`
\r
12386 values and can not unflattened to their original type. Apart from
\r
12387 this example, for a JSON value `j`, the following is always true:
\r
12388 `j == j.flatten().unflatten()`.
\r
12390 @complexity Linear in the size the JSON value.
\r
12392 @liveexample{The following code shows how a flattened JSON object is
\r
12393 unflattened into the original nested JSON object.,unflatten}
\r
12395 @sa @ref flatten() for the reverse function
\r
12397 @since version 2.0.0
\r
12399 basic_json unflatten() const
\r
12401 return json_pointer::unflatten(*this);
\r
12406 //////////////////////////
\r
12407 // JSON Patch functions //
\r
12408 //////////////////////////
\r
12410 /// @name JSON Patch functions
\r
12414 @brief applies a JSON patch
\r
12416 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
\r
12417 expressing a sequence of operations to apply to a JSON) document. With
\r
12418 this function, a JSON Patch is applied to the current JSON value by
\r
12419 executing all operations from the patch.
\r
12421 @param[in] json_patch JSON patch document
\r
12422 @return patched document
\r
12424 @note The application of a patch is atomic: Either all operations succeed
\r
12425 and the patched document is returned or an exception is thrown. In
\r
12426 any case, the original value is not changed: the patch is applied
\r
12427 to a copy of the value.
\r
12429 @throw std::out_of_range if a JSON pointer inside the patch could not
\r
12430 be resolved successfully in the current JSON value; example: `"key baz
\r
12432 @throw invalid_argument if the JSON patch is malformed (e.g., mandatory
\r
12433 attributes are missing); example: `"operation add must have member path"`
\r
12435 @complexity Linear in the size of the JSON value and the length of the
\r
12436 JSON patch. As usually only a fraction of the JSON value is affected by
\r
12437 the patch, the complexity can usually be neglected.
\r
12439 @liveexample{The following code shows how a JSON patch is applied to a
\r
12442 @sa @ref diff -- create a JSON patch by comparing two JSON values
\r
12444 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
\r
12445 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
\r
12447 @since version 2.0.0
\r
12449 basic_json patch(const basic_json& json_patch) const
\r
12451 // make a working copy to apply the patch to
\r
12452 basic_json result = *this;
\r
12454 // the valid JSON Patch operations
\r
12455 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
\r
12457 const auto get_op = [](const std::string op)
\r
12461 return patch_operations::add;
\r
12463 if (op == "remove")
\r
12465 return patch_operations::remove;
\r
12467 if (op == "replace")
\r
12469 return patch_operations::replace;
\r
12471 if (op == "move")
\r
12473 return patch_operations::move;
\r
12475 if (op == "copy")
\r
12477 return patch_operations::copy;
\r
12479 if (op == "test")
\r
12481 return patch_operations::test;
\r
12484 return patch_operations::invalid;
\r
12487 // wrapper for "add" operation; add value at ptr
\r
12488 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
\r
12490 // adding to the root of the target document means replacing it
\r
12491 if (ptr.is_root())
\r
12497 // make sure the top element of the pointer exists
\r
12498 json_pointer top_pointer = ptr.top();
\r
12499 if (top_pointer != ptr)
\r
12501 result.at(top_pointer);
\r
12504 // get reference to parent of JSON pointer ptr
\r
12505 const auto last_path = ptr.pop_back();
\r
12506 basic_json& parent = result[ptr];
\r
12508 switch (parent.m_type)
\r
12510 case value_t::null:
\r
12511 case value_t::object:
\r
12513 // use operator[] to add value
\r
12514 parent[last_path] = val;
\r
12518 case value_t::array:
\r
12520 if (last_path == "-")
\r
12522 // special case: append to back
\r
12523 parent.push_back(val);
\r
12527 const auto idx = std::stoi(last_path);
\r
12528 if (static_cast<size_type>(idx) > parent.size())
\r
12530 // avoid undefined behavior
\r
12531 JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
\r
12535 // default case: insert add offset
\r
12536 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
\r
12544 // if there exists a parent it cannot be primitive
\r
12545 assert(false); // LCOV_EXCL_LINE
\r
12551 // wrapper for "remove" operation; remove value at ptr
\r
12552 const auto operation_remove = [&result](json_pointer & ptr)
\r
12554 // get reference to parent of JSON pointer ptr
\r
12555 const auto last_path = ptr.pop_back();
\r
12556 basic_json& parent = result.at(ptr);
\r
12559 if (parent.is_object())
\r
12561 // perform range check
\r
12562 auto it = parent.find(last_path);
\r
12563 if (it != parent.end())
\r
12565 parent.erase(it);
\r
12569 JSON_THROW(std::out_of_range("key '" + last_path + "' not found"));
\r
12572 else if (parent.is_array())
\r
12574 // note erase performs range check
\r
12575 parent.erase(static_cast<size_type>(std::stoi(last_path)));
\r
12580 if (not json_patch.is_array())
\r
12582 // a JSON patch must be an array of objects
\r
12583 JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
\r
12586 // iterate and apply the operations
\r
12587 for (const auto& val : json_patch)
\r
12589 // wrapper to get a value for an operation
\r
12590 const auto get_value = [&val](const std::string & op,
\r
12591 const std::string & member,
\r
12592 bool string_type) -> basic_json&
\r
12595 auto it = val.m_value.object->find(member);
\r
12597 // context-sensitive error message
\r
12598 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
\r
12600 // check if desired value is present
\r
12601 if (it == val.m_value.object->end())
\r
12603 JSON_THROW(std::invalid_argument(error_msg + " must have member '" + member + "'"));
\r
12606 // check if result is of type string
\r
12607 if (string_type and not it->second.is_string())
\r
12609 JSON_THROW(std::invalid_argument(error_msg + " must have string member '" + member + "'"));
\r
12612 // no error: return value
\r
12613 return it->second;
\r
12617 if (not val.is_object())
\r
12619 JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
\r
12622 // collect mandatory members
\r
12623 const std::string op = get_value("op", "op", true);
\r
12624 const std::string path = get_value(op, "path", true);
\r
12625 json_pointer ptr(path);
\r
12627 switch (get_op(op))
\r
12629 case patch_operations::add:
\r
12631 operation_add(ptr, get_value("add", "value", false));
\r
12635 case patch_operations::remove:
\r
12637 operation_remove(ptr);
\r
12641 case patch_operations::replace:
\r
12643 // the "path" location must exist - use at()
\r
12644 result.at(ptr) = get_value("replace", "value", false);
\r
12648 case patch_operations::move:
\r
12650 const std::string from_path = get_value("move", "from", true);
\r
12651 json_pointer from_ptr(from_path);
\r
12653 // the "from" location must exist - use at()
\r
12654 basic_json v = result.at(from_ptr);
\r
12656 // The move operation is functionally identical to a
\r
12657 // "remove" operation on the "from" location, followed
\r
12658 // immediately by an "add" operation at the target
\r
12659 // location with the value that was just removed.
\r
12660 operation_remove(from_ptr);
\r
12661 operation_add(ptr, v);
\r
12665 case patch_operations::copy:
\r
12667 const std::string from_path = get_value("copy", "from", true);;
\r
12668 const json_pointer from_ptr(from_path);
\r
12670 // the "from" location must exist - use at()
\r
12671 result[ptr] = result.at(from_ptr);
\r
12675 case patch_operations::test:
\r
12677 bool success = false;
\r
12680 // check if "value" matches the one at "path"
\r
12681 // the "path" location must exist - use at()
\r
12682 success = (result.at(ptr) == get_value("test", "value", false));
\r
12684 JSON_CATCH (std::out_of_range&)
\r
12686 // ignore out of range errors: success remains false
\r
12689 // throw an exception if test fails
\r
12692 JSON_THROW(std::domain_error("unsuccessful: " + val.dump()));
\r
12698 case patch_operations::invalid:
\r
12700 // op must be "add", "remove", "replace", "move", "copy", or
\r
12702 JSON_THROW(std::invalid_argument("operation value '" + op + "' is invalid"));
\r
12711 @brief creates a diff as a JSON patch
\r
12713 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
\r
12714 be changed into the value @a target by calling @ref patch function.
\r
12716 @invariant For two JSON values @a source and @a target, the following code
\r
12717 yields always `true`:
\r
12719 source.patch(diff(source, target)) == target;
\r
12722 @note Currently, only `remove`, `add`, and `replace` operations are
\r
12725 @param[in] source JSON value to compare from
\r
12726 @param[in] target JSON value to compare against
\r
12727 @param[in] path helper value to create JSON pointers
\r
12729 @return a JSON patch to convert the @a source to @a target
\r
12731 @complexity Linear in the lengths of @a source and @a target.
\r
12733 @liveexample{The following code shows how a JSON patch is created as a
\r
12734 diff for two JSON values.,diff}
\r
12736 @sa @ref patch -- apply a JSON patch
\r
12738 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
\r
12740 @since version 2.0.0
\r
12742 static basic_json diff(const basic_json& source,
\r
12743 const basic_json& target,
\r
12744 const std::string& path = "")
\r
12747 basic_json result(value_t::array);
\r
12749 // if the values are the same, return empty patch
\r
12750 if (source == target)
\r
12755 if (source.type() != target.type())
\r
12757 // different types: replace value
\r
12758 result.push_back(
\r
12760 {"op", "replace"},
\r
12762 {"value", target}
\r
12767 switch (source.type())
\r
12769 case value_t::array:
\r
12771 // first pass: traverse common elements
\r
12773 while (i < source.size() and i < target.size())
\r
12775 // recursive call to compare array values at index i
\r
12776 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
\r
12777 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
\r
12781 // i now reached the end of at least one array
\r
12782 // in a second pass, traverse the remaining elements
\r
12784 // remove my remaining elements
\r
12785 const auto end_index = static_cast<difference_type>(result.size());
\r
12786 while (i < source.size())
\r
12788 // add operations in reverse order to avoid invalid
\r
12790 result.insert(result.begin() + end_index, object(
\r
12792 {"op", "remove"},
\r
12793 {"path", path + "/" + std::to_string(i)}
\r
12798 // add other remaining elements
\r
12799 while (i < target.size())
\r
12801 result.push_back(
\r
12804 {"path", path + "/" + std::to_string(i)},
\r
12805 {"value", target[i]}
\r
12813 case value_t::object:
\r
12815 // first pass: traverse this object's elements
\r
12816 for (auto it = source.begin(); it != source.end(); ++it)
\r
12818 // escape the key name to be used in a JSON patch
\r
12819 const auto key = json_pointer::escape(it.key());
\r
12821 if (target.find(it.key()) != target.end())
\r
12823 // recursive call to compare object values at key it
\r
12824 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
\r
12825 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
\r
12829 // found a key that is not in o -> remove it
\r
12830 result.push_back(object(
\r
12832 {"op", "remove"},
\r
12833 {"path", path + "/" + key}
\r
12838 // second pass: traverse other object's elements
\r
12839 for (auto it = target.begin(); it != target.end(); ++it)
\r
12841 if (source.find(it.key()) == source.end())
\r
12843 // found a key that is not in this -> add it
\r
12844 const auto key = json_pointer::escape(it.key());
\r
12845 result.push_back(
\r
12848 {"path", path + "/" + key},
\r
12849 {"value", it.value()}
\r
12859 // both primitive type: replace value
\r
12860 result.push_back(
\r
12862 {"op", "replace"},
\r
12864 {"value", target}
\r
12882 @brief default JSON class
\r
12884 This type is the default specialization of the @ref basic_json class which
\r
12885 uses the standard template types.
\r
12887 @since version 1.0.0
\r
12889 using json = basic_json<>;
\r
12890 } // namespace nlohmann
\r
12893 ///////////////////////
\r
12894 // nonmember support //
\r
12895 ///////////////////////
\r
12897 // specialization of std::swap, and std::hash
\r
12901 @brief exchanges the values of two JSON objects
\r
12903 @since version 1.0.0
\r
12906 inline void swap(nlohmann::json& j1,
\r
12907 nlohmann::json& j2) noexcept(
\r
12908 is_nothrow_move_constructible<nlohmann::json>::value and
\r
12909 is_nothrow_move_assignable<nlohmann::json>::value
\r
12915 /// hash value for JSON objects
\r
12917 struct hash<nlohmann::json>
\r
12920 @brief return a hash value for a JSON object
\r
12922 @since version 1.0.0
\r
12924 std::size_t operator()(const nlohmann::json& j) const
\r
12926 // a naive hashing via the string representation
\r
12927 const auto& h = hash<nlohmann::json::string_t>();
\r
12928 return h(j.dump());
\r
12931 } // namespace std
\r
12934 @brief user-defined string literal for JSON values
\r
12936 This operator implements a user-defined string literal for JSON objects. It
\r
12937 can be used by adding `"_json"` to a string literal and returns a JSON object
\r
12938 if no parse error occurred.
\r
12940 @param[in] s a string representation of a JSON object
\r
12941 @param[in] n the length of string @a s
\r
12942 @return a JSON object
\r
12944 @since version 1.0.0
\r
12946 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
\r
12948 return nlohmann::json::parse(s, s + n);
\r
12952 @brief user-defined string literal for JSON pointer
\r
12954 This operator implements a user-defined string literal for JSON Pointers. It
\r
12955 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
\r
12956 object if no parse error occurred.
\r
12958 @param[in] s a string representation of a JSON Pointer
\r
12959 @param[in] n the length of string @a s
\r
12960 @return a JSON pointer object
\r
12962 @since version 2.0.0
\r
12964 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
\r
12966 return nlohmann::json::json_pointer(std::string(s, n));
\r
12970 #undef JSON_CATCH
\r
12971 #undef JSON_DEPRECATED
\r
12972 #undef JSON_THROW
\r