Logo ROOT   6.16/01
Reference Guide
json.hpp
Go to the documentation of this file.
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 2.1.1
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27*/
28
29#ifndef NLOHMANN_JSON_HPP
30#define NLOHMANN_JSON_HPP
31
32#include <algorithm> // all_of, copy, fill, find, for_each, none_of, remove, reverse, transform
33#include <array> // array
34#include <cassert> // assert
35#include <cctype> // isdigit
36#include <ciso646> // and, not, or
37#include <cmath> // isfinite, labs, ldexp, signbit
38#include <cstddef> // nullptr_t, ptrdiff_t, size_t
39#include <cstdint> // int64_t, uint64_t
40#include <cstdlib> // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull
41#include <cstring> // strlen
42#include <forward_list> // forward_list
43#include <functional> // function, hash, less
44#include <initializer_list> // initializer_list
45#include <iomanip> // setw
46#include <iostream> // istream, ostream
47#include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
48#include <limits> // numeric_limits
49#include <locale> // locale
50#include <map> // map
51#include <memory> // addressof, allocator, allocator_traits, unique_ptr
52#include <numeric> // accumulate
53#include <sstream> // stringstream
54#include <stdexcept> // domain_error, invalid_argument, out_of_range
55#include <string> // getline, stoi, string, to_string
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
57#include <utility> // declval, forward, make_pair, move, pair, swap
58#include <vector> // vector
59
60// exclude unsupported compilers
61#if defined(__clang__)
62 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
63 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
64 #endif
65#elif defined(__GNUC__)
66 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
67// #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
68 #endif
69#endif
70
71// disable float-equal warnings on GCC/clang
72#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
73 #pragma GCC diagnostic push
74 #pragma GCC diagnostic ignored "-Wfloat-equal"
75#endif
76
77// disable documentation warnings on clang
78#if defined(__clang__)
79 #pragma GCC diagnostic push
80 #pragma GCC diagnostic ignored "-Wdocumentation"
81#endif
82
83// allow for portable deprecation warnings
84#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
85 #define JSON_DEPRECATED __attribute__((deprecated))
86#elif defined(_MSC_VER)
87 #define JSON_DEPRECATED __declspec(deprecated)
88#else
89 #define JSON_DEPRECATED
90#endif
91
92// allow to disable exceptions
93#if not defined(JSON_NOEXCEPTION) || defined(__EXCEPTIONS)
94 #define JSON_THROW(exception) throw exception
95 #define JSON_TRY try
96 #define JSON_CATCH(exception) catch(exception)
97#else
98 #define JSON_THROW(exception) std::abort()
99 #define JSON_TRY if(true)
100 #define JSON_CATCH(exception) if(false)
101#endif
102
103/*!
104@brief namespace for Niels Lohmann
105@see https://github.com/nlohmann
106@since version 1.0.0
107*/
108namespace nlohmann
109{
110
111/*!
112@brief unnamed namespace with internal helper functions
113
114This namespace collects some functions that could not be defined inside the
115@ref basic_json class.
116
117@since version 2.1.0
118*/
119namespace detail
120{
121///////////////////////////
122// JSON type enumeration //
123///////////////////////////
124
125/*!
126@brief the JSON type enumeration
127
128This enumeration collects the different JSON types. It is internally used to
129distinguish the stored values, and the functions @ref basic_json::is_null(),
130@ref basic_json::is_object(), @ref basic_json::is_array(),
131@ref basic_json::is_string(), @ref basic_json::is_boolean(),
132@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
133@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
134@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
135@ref basic_json::is_structured() rely on it.
136
137@note There are three enumeration entries (number_integer, number_unsigned, and
138number_float), because the library distinguishes these three types for numbers:
139@ref basic_json::number_unsigned_t is used for unsigned integers,
140@ref basic_json::number_integer_t is used for signed integers, and
141@ref basic_json::number_float_t is used for floating-point numbers or to
142approximate integers which do not fit in the limits of their respective type.
143
144@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
145value with the default value for a given type
146
147@since version 1.0.0
148*/
149enum class value_t : uint8_t
150{
151 null, ///< null value
152 object, ///< object (unordered set of name/value pairs)
153 array, ///< array (ordered collection of values)
154 string, ///< string value
155 boolean, ///< boolean value
156 number_integer, ///< number value (signed integer)
157 number_unsigned, ///< number value (unsigned integer)
158 number_float, ///< number value (floating-point)
159 discarded ///< discarded by the the parser callback function
160};
161
162/*!
163@brief comparison operator for JSON types
164
165Returns an ordering that is similar to Python:
166- order: null < boolean < number < object < array < string
167- furthermore, each type is not smaller than itself
168
169@since version 1.0.0
170*/
171inline bool operator<(const value_t lhs, const value_t rhs) noexcept
172{
173 static constexpr std::array<uint8_t, 8> order = {{
174 0, // null
175 3, // object
176 4, // array
177 5, // string
178 1, // boolean
179 2, // integer
180 2, // unsigned
181 2, // float
182 }
183 };
184
185 // discarded values are not comparable
186 if (lhs == value_t::discarded or rhs == value_t::discarded)
187 {
188 return false;
189 }
190
191 return order[static_cast<std::size_t>(lhs)] <
192 order[static_cast<std::size_t>(rhs)];
193}
194
195
196/////////////
197// helpers //
198/////////////
199
200// alias templates to reduce boilerplate
201template<bool B, typename T = void>
203
204template<typename T>
206
207// taken from http://stackoverflow.com/a/26936864/266378
208template<typename T>
210 std::integral_constant<bool, std::is_convertible<T, int>::value and
211 std::is_enum<T>::value>;
212
213/*
214Implementation of two C++17 constructs: conjunction, negation. This is needed
215to avoid evaluating all the traits in a condition
216
217For example: not std::is_same<void, T>::value and has_value_type<T>::value
218will not compile when T = void (on MSVC at least). Whereas
219conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
220stop evaluating if negation<...>::value == false
221
222Please note that those constructs must be used with caution, since symbols can
223become very long quickly (which can slow down compilation and cause MSVC
224internal compiler errors). Only use it when you have to (see example ahead).
225*/
226template<class...> struct conjunction : std::true_type {};
227template<class B1> struct conjunction<B1> : B1 {};
228template<class B1, class... Bn>
229struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
230
231template<class B> struct negation : std::integral_constant < bool, !B::value > {};
232
233// dispatch utility (taken from ranges-v3)
234template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
235template<> struct priority_tag<0> {};
236
237
238//////////////////
239// constructors //
240//////////////////
241
242template<value_t> struct external_constructor;
243
244template<>
246{
247 template<typename BasicJsonType>
248 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
249 {
250 j.m_type = value_t::boolean;
251 j.m_value = b;
252 j.assert_invariant();
253 }
254};
255
256template<>
258{
259 template<typename BasicJsonType>
260 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
261 {
262 j.m_type = value_t::string;
263 j.m_value = s;
264 j.assert_invariant();
265 }
266};
267
268template<>
270{
271 template<typename BasicJsonType>
272 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
273 {
274 // replace infinity and NAN by null
275 if (not std::isfinite(val))
276 {
277 j = BasicJsonType{};
278 }
279 else
280 {
281 j.m_type = value_t::number_float;
282 j.m_value = val;
283 }
284 j.assert_invariant();
285 }
286};
287
288template<>
290{
291 template<typename BasicJsonType>
292 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
293 {
294 j.m_type = value_t::number_unsigned;
295 j.m_value = val;
296 j.assert_invariant();
297 }
298};
299
300template<>
302{
303 template<typename BasicJsonType>
304 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
305 {
306 j.m_type = value_t::number_integer;
307 j.m_value = val;
308 j.assert_invariant();
309 }
310};
311
312template<>
314{
315 template<typename BasicJsonType>
316 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
317 {
318 j.m_type = value_t::array;
319 j.m_value = arr;
320 j.assert_invariant();
321 }
322
323 template<typename BasicJsonType, typename CompatibleArrayType,
324 enable_if_t<not std::is_same<CompatibleArrayType,
325 typename BasicJsonType::array_t>::value,
326 int> = 0>
327 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
328 {
329 using std::begin;
330 using std::end;
331 j.m_type = value_t::array;
332 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
333 j.assert_invariant();
334 }
335};
336
337template<>
339{
340 template<typename BasicJsonType>
341 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
342 {
343 j.m_type = value_t::object;
344 j.m_value = obj;
345 j.assert_invariant();
346 }
347
348 template<typename BasicJsonType, typename CompatibleObjectType,
349 enable_if_t<not std::is_same<CompatibleObjectType,
350 typename BasicJsonType::object_t>::value,
351 int> = 0>
352 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
353 {
354 using std::begin;
355 using std::end;
356
357 j.m_type = value_t::object;
358 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
359 j.assert_invariant();
360 }
361};
362
363
364////////////////////////
365// has_/is_ functions //
366////////////////////////
367
368/*!
369@brief Helper to determine whether there's a key_type for T.
370
371This helper is used to tell associative containers apart from other containers
372such as sequence containers. For instance, `std::map` passes the test as it
373contains a `mapped_type`, whereas `std::vector` fails the test.
374
375@sa http://stackoverflow.com/a/7728728/266378
376@since version 1.0.0, overworked in version 2.0.6
377*/
378#define NLOHMANN_JSON_HAS_HELPER(type) \
379 template<typename T> struct has_##type { \
380 private: \
381 template<typename U, typename = typename U::type> \
382 static int detect(U &&); \
383 static void detect(...); \
384 public: \
385 static constexpr bool value = \
386 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
387 }
388
393
394#undef NLOHMANN_JSON_HAS_HELPER
395
396
397template<bool B, class RealType, class CompatibleObjectType>
398struct is_compatible_object_type_impl : std::false_type {};
399
400template<class RealType, class CompatibleObjectType>
401struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
402{
403 static constexpr auto value =
404 std::is_constructible<typename RealType::key_type,
405 typename CompatibleObjectType::key_type>::value and
406 std::is_constructible<typename RealType::mapped_type,
407 typename CompatibleObjectType::mapped_type>::value;
408};
409
410template<class BasicJsonType, class CompatibleObjectType>
412{
413 static auto constexpr value = is_compatible_object_type_impl <
415 has_mapped_type<CompatibleObjectType>,
416 has_key_type<CompatibleObjectType>>::value,
417 typename BasicJsonType::object_t, CompatibleObjectType >::value;
418};
419
420template<typename BasicJsonType, typename T>
422{
423 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
424 std::is_same<T, typename BasicJsonType::const_iterator>::value or
425 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
426 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value or
427 std::is_same<T, typename BasicJsonType::json_pointer>::value;
428};
429
430template<class BasicJsonType, class CompatibleArrayType>
432{
433 static auto constexpr value =
436 BasicJsonType, CompatibleArrayType>>,
437 negation<std::is_constructible<typename BasicJsonType::string_t,
438 CompatibleArrayType>>,
440 has_value_type<CompatibleArrayType>,
441 has_iterator<CompatibleArrayType>>::value;
442};
443
444template<bool, typename, typename>
445struct is_compatible_integer_type_impl : std::false_type {};
446
447template<typename RealIntegerType, typename CompatibleNumberIntegerType>
448struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
449{
450 // is there an assert somewhere on overflows?
451 using RealLimits = std::numeric_limits<RealIntegerType>;
452 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
453
454 static constexpr auto value =
455 std::is_constructible<RealIntegerType,
456 CompatibleNumberIntegerType>::value and
457 CompatibleLimits::is_integer and
458 RealLimits::is_signed == CompatibleLimits::is_signed;
459};
460
461template<typename RealIntegerType, typename CompatibleNumberIntegerType>
463{
464 static constexpr auto value =
466 std::is_integral<CompatibleNumberIntegerType>::value and
467 not std::is_same<bool, CompatibleNumberIntegerType>::value,
468 RealIntegerType, CompatibleNumberIntegerType > ::value;
469};
470
471
472// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
473template<typename BasicJsonType, typename T>
475{
476 private:
477 // also check the return type of from_json
478 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
479 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
480 static int detect(U&&);
481 static void detect(...);
482
483 public:
484 static constexpr bool value = std::is_integral<decltype(
485 detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
486};
487
488// This trait checks if JSONSerializer<T>::from_json(json const&) exists
489// this overload is used for non-default-constructible user-defined-types
490template<typename BasicJsonType, typename T>
492{
493 private:
494 template <
495 typename U,
496 typename = enable_if_t<std::is_same<
497 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
498 static int detect(U&&);
499 static void detect(...);
500
501 public:
502 static constexpr bool value = std::is_integral<decltype(detect(
503 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
504};
505
506// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
507template<typename BasicJsonType, typename T>
509{
510 private:
511 template<typename U, typename = decltype(uncvref_t<U>::to_json(
512 std::declval<BasicJsonType&>(), std::declval<T>()))>
513 static int detect(U&&);
514 static void detect(...);
515
516 public:
517 static constexpr bool value = std::is_integral<decltype(detect(
518 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
519};
520
521
522/////////////
523// to_json //
524/////////////
525
526template<typename BasicJsonType, typename T, enable_if_t<
527 std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
528void to_json(BasicJsonType& j, T b) noexcept
529{
531}
532
533template<typename BasicJsonType, typename CompatibleString,
534 enable_if_t<std::is_constructible<typename BasicJsonType::string_t,
535 CompatibleString>::value, int> = 0>
536void to_json(BasicJsonType& j, const CompatibleString& s)
537{
539}
540
541template<typename BasicJsonType, typename FloatType,
542 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
543void to_json(BasicJsonType& j, FloatType val) noexcept
544{
545 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
546}
547
548template <
549 typename BasicJsonType, typename CompatibleNumberUnsignedType,
550 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
551 CompatibleNumberUnsignedType>::value, int> = 0 >
552void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
553{
554 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
555}
556
557template <
558 typename BasicJsonType, typename CompatibleNumberIntegerType,
559 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
560 CompatibleNumberIntegerType>::value, int> = 0 >
561void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
562{
563 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
564}
565
566template<typename BasicJsonType, typename UnscopedEnumType,
567 enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
568void to_json(BasicJsonType& j, UnscopedEnumType e) noexcept
569{
571}
572
573template <
574 typename BasicJsonType, typename CompatibleArrayType,
577 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
578 int > = 0 >
579void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
580{
582}
583
584template <
585 typename BasicJsonType, typename CompatibleObjectType,
586 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
587 int> = 0 >
588void to_json(BasicJsonType& j, const CompatibleObjectType& arr)
589{
591}
592
593
594///////////////
595// from_json //
596///////////////
597
598// overloads for basic_json template parameters
599template<typename BasicJsonType, typename ArithmeticType,
600 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
601 not std::is_same<ArithmeticType,
602 typename BasicJsonType::boolean_t>::value,
603 int> = 0>
604void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
605{
606 switch (static_cast<value_t>(j))
607 {
609 {
610 val = static_cast<ArithmeticType>(
611 *j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
612 break;
613 }
615 {
616 val = static_cast<ArithmeticType>(
617 *j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
618 break;
619 }
621 {
622 val = static_cast<ArithmeticType>(
623 *j.template get_ptr<const typename BasicJsonType::number_float_t*>());
624 break;
625 }
626 default:
627 {
629 std::domain_error("type must be number, but is " + j.type_name()));
630 }
631 }
632}
633
634template<typename BasicJsonType>
635void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
636{
637 if (not j.is_boolean())
638 {
639 JSON_THROW(std::domain_error("type must be boolean, but is " + j.type_name()));
640 }
641 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
642}
643
644template<typename BasicJsonType>
645void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
646{
647 if (not j.is_string())
648 {
649 JSON_THROW(std::domain_error("type must be string, but is " + j.type_name()));
650 }
651 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
652}
653
654template<typename BasicJsonType>
655void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
656{
657 get_arithmetic_value(j, val);
658}
659
660template<typename BasicJsonType>
661void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
662{
663 get_arithmetic_value(j, val);
664}
665
666template<typename BasicJsonType>
667void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
668{
669 get_arithmetic_value(j, val);
670}
671
672template<typename BasicJsonType, typename UnscopedEnumType,
673 enable_if_t<is_unscoped_enum<UnscopedEnumType>::value, int> = 0>
674void from_json(const BasicJsonType& j, UnscopedEnumType& e)
675{
677 get_arithmetic_value(j, val);
678 e = static_cast<UnscopedEnumType>(val);
679}
680
681template<typename BasicJsonType>
682void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
683{
684 if (not j.is_array())
685 {
686 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
687 }
688 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
689}
690
691// forward_list doesn't have an insert method
692template<typename BasicJsonType, typename T, typename Allocator>
693void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
694{
695 // do not perform the check when user wants to retrieve jsons
696 // (except when it's null.. ?)
697 if (j.is_null())
698 {
699 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
700 }
701 if (not std::is_same<T, BasicJsonType>::value)
702 {
703 if (not j.is_array())
704 {
705 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
706 }
707 }
708 for (auto it = j.rbegin(), end = j.rend(); it != end; ++it)
709 {
710 l.push_front(it->template get<T>());
711 }
712}
713
714template<typename BasicJsonType, typename CompatibleArrayType>
715void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>)
716{
717 using std::begin;
718 using std::end;
719
720 std::transform(j.begin(), j.end(),
721 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
722 {
723 // get<BasicJsonType>() returns *this, this won't call a from_json
724 // method when value_type is BasicJsonType
725 return i.template get<typename CompatibleArrayType::value_type>();
726 });
727}
728
729template<typename BasicJsonType, typename CompatibleArrayType>
730auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>)
731-> decltype(
732 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
733 void())
734{
735 using std::begin;
736 using std::end;
737
738 arr.reserve(j.size());
739 std::transform(
740 j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i)
741 {
742 // get<BasicJsonType>() returns *this, this won't call a from_json
743 // method when value_type is BasicJsonType
744 return i.template get<typename CompatibleArrayType::value_type>();
745 });
746}
747
748template<typename BasicJsonType, typename CompatibleArrayType,
749 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
750 not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
751void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
752{
753 if (j.is_null())
754 {
755 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
756 }
757
758 // when T == BasicJsonType, do not check if value_t is correct
759 if (not std::is_same<typename CompatibleArrayType::value_type, BasicJsonType>::value)
760 {
761 if (not j.is_array())
762 {
763 JSON_THROW(std::domain_error("type must be array, but is " + j.type_name()));
764 }
765 }
767}
768
769template<typename BasicJsonType, typename CompatibleObjectType,
770 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
771void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
772{
773 if (not j.is_object())
774 {
775 JSON_THROW(std::domain_error("type must be object, but is " + j.type_name()));
776 }
777
778 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
779 using std::begin;
780 using std::end;
781 // we could avoid the assignment, but this might require a for loop, which
782 // might be less efficient than the container constructor for some
783 // containers (would it?)
784 obj = CompatibleObjectType(begin(*inner_object), end(*inner_object));
785}
786
787// overload for arithmetic types, not chosen for basic_json template arguments
788// (BooleanType, etc..); note: Is it really necessary to provide explicit
789// overloads for boolean_t etc. in case of a custom BooleanType which is not
790// an arithmetic type?
791template<typename BasicJsonType, typename ArithmeticType,
793 std::is_arithmetic<ArithmeticType>::value and
794 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
795 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
796 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
797 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
798 int> = 0>
799void from_json(const BasicJsonType& j, ArithmeticType& val)
800{
801 switch (static_cast<value_t>(j))
802 {
804 {
805 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
806 break;
807 }
809 {
810 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
811 break;
812 }
814 {
815 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
816 break;
817 }
818 case value_t::boolean:
819 {
820 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
821 break;
822 }
823 default:
824 {
825 JSON_THROW(std::domain_error("type must be number, but is " + j.type_name()));
826 }
827 }
828}
829
831{
832 private:
833 template<typename BasicJsonType, typename T>
834 auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
835 -> decltype(to_json(j, std::forward<T>(val)), void())
836 {
837 return to_json(j, std::forward<T>(val));
838 }
839
840 template<typename BasicJsonType, typename T>
841 void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept
842 {
843 static_assert(sizeof(BasicJsonType) == 0,
844 "could not find to_json() method in T's namespace");
845 }
846
847 public:
848 template<typename BasicJsonType, typename T>
849 void operator()(BasicJsonType& j, T&& val) const
850 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
851 {
852 return call(j, std::forward<T>(val), priority_tag<1> {});
853 }
854};
855
857{
858 private:
859 template<typename BasicJsonType, typename T>
860 auto call(const BasicJsonType& j, T& val, priority_tag<1>) const
861 noexcept(noexcept(from_json(j, val)))
862 -> decltype(from_json(j, val), void())
863 {
864 return from_json(j, val);
865 }
866
867 template<typename BasicJsonType, typename T>
868 void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept
869 {
870 static_assert(sizeof(BasicJsonType) == 0,
871 "could not find from_json() method in T's namespace");
872 }
873
874 public:
875 template<typename BasicJsonType, typename T>
876 void operator()(const BasicJsonType& j, T& val) const
877 noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
878 {
879 return call(j, val, priority_tag<1> {});
880 }
881};
882
883// taken from ranges-v3
884template<typename T>
886{
887 static constexpr T value{};
888};
889
890template<typename T>
891constexpr T static_const<T>::value;
892} // namespace detail
893
894
895/// namespace to hold default `to_json` / `from_json` functions
896namespace
897{
900}
901
902
903/*!
904@brief default JSONSerializer template argument
905
906This serializer ignores the template arguments and uses ADL
907([argument-dependent lookup](http://en.cppreference.com/w/cpp/language/adl))
908for serialization.
909*/
910template<typename = void, typename = void>
912{
913 /*!
914 @brief convert a JSON value to any value type
915
916 This function is usually called by the `get()` function of the
917 @ref basic_json class (either explicit or via conversion operators).
918
919 @param[in] j JSON value to read from
920 @param[in,out] val value to write to
921 */
922 template<typename BasicJsonType, typename ValueType>
923 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
924 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
925 {
926 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
927 }
928
929 /*!
930 @brief convert any value type to a JSON value
931
932 This function is usually called by the constructors of the @ref basic_json
933 class.
934
935 @param[in,out] j JSON value to write to
936 @param[in] val value to read from
937 */
938 template<typename BasicJsonType, typename ValueType>
939 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
940 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
941 {
942 ::nlohmann::to_json(j, std::forward<ValueType>(val));
943 }
944};
945
946
947/*!
948@brief a class to store JSON values
949
950@tparam ObjectType type for JSON objects (`std::map` by default; will be used
951in @ref object_t)
952@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
953in @ref array_t)
954@tparam StringType type for JSON strings and object keys (`std::string` by
955default; will be used in @ref string_t)
956@tparam BooleanType type for JSON booleans (`bool` by default; will be used
957in @ref boolean_t)
958@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
959default; will be used in @ref number_integer_t)
960@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
961`uint64_t` by default; will be used in @ref number_unsigned_t)
962@tparam NumberFloatType type for JSON floating-point numbers (`double` by
963default; will be used in @ref number_float_t)
964@tparam AllocatorType type of the allocator to use (`std::allocator` by
965default)
966@tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
967and `from_json()` (@ref adl_serializer by default)
968
969@requirement The class satisfies the following concept requirements:
970- Basic
971 - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
972 JSON values can be default constructed. The result will be a JSON null
973 value.
974 - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
975 A JSON value can be constructed from an rvalue argument.
976 - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
977 A JSON value can be copy-constructed from an lvalue expression.
978 - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
979 A JSON value van be assigned from an rvalue argument.
980 - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
981 A JSON value can be copy-assigned from an lvalue expression.
982 - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
983 JSON values can be destructed.
984- Layout
985 - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
986 JSON values have
987 [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
988 All non-static data members are private and standard layout types, the
989 class has no virtual functions or (virtual) base classes.
990- Library-wide
991 - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
992 JSON values can be compared with `==`, see @ref
993 operator==(const_reference,const_reference).
994 - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
995 JSON values can be compared with `<`, see @ref
996 operator<(const_reference,const_reference).
997 - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
998 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
999 other compatible types, using unqualified function call @ref swap().
1000 - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
1001 JSON values can be compared against `std::nullptr_t` objects which are used
1002 to model the `null` value.
1003- Container
1004 - [Container](http://en.cppreference.com/w/cpp/concept/Container):
1005 JSON values can be used like STL containers and provide iterator access.
1006 - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
1007 JSON values can be used like STL containers and provide reverse iterator
1008 access.
1009
1010@invariant The member variables @a m_value and @a m_type have the following
1011relationship:
1012- If `m_type == value_t::object`, then `m_value.object != nullptr`.
1013- If `m_type == value_t::array`, then `m_value.array != nullptr`.
1014- If `m_type == value_t::string`, then `m_value.string != nullptr`.
1015The invariants are checked by member function assert_invariant().
1016
1017@internal
1018@note ObjectType trick from http://stackoverflow.com/a/9860911
1019@endinternal
1020
1021@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
1022Format](http://rfc7159.net/rfc7159)
1023
1024@since version 1.0.0
1025
1026@nosubgrouping
1027*/
1028template <
1029 template<typename U, typename V, typename... Args> class ObjectType = std::map,
1030 template<typename U, typename... Args> class ArrayType = std::vector,
1031 class StringType = std::string,
1032 class BooleanType = bool,
1033 class NumberIntegerType = std::int64_t,
1034 class NumberUnsignedType = std::uint64_t,
1035 class NumberFloatType = double,
1036 template<typename U> class AllocatorType = std::allocator,
1037 template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer
1038 >
1040{
1041 private:
1042 template<detail::value_t> friend struct detail::external_constructor;
1043 /// workaround type for MSVC
1044 using basic_json_t = basic_json<ObjectType, ArrayType, StringType,
1045 BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType,
1046 AllocatorType, JSONSerializer>;
1047
1048 public:
1050 // forward declarations
1051 template<typename U> class iter_impl;
1052 template<typename Base> class json_reverse_iterator;
1053 class json_pointer;
1054 template<typename T, typename SFINAE>
1055 using json_serializer = JSONSerializer<T, SFINAE>;
1056
1057 /////////////////////
1058 // container types //
1059 /////////////////////
1060
1061 /// @name container types
1062 /// The canonic container types to use @ref basic_json like any other STL
1063 /// container.
1064 /// @{
1065
1066 /// the type of elements in a basic_json container
1068
1069 /// the type of an element reference
1071 /// the type of an element const reference
1073
1074 /// a type to represent differences between iterators
1075 using difference_type = std::ptrdiff_t;
1076 /// a type to represent container sizes
1077 using size_type = std::size_t;
1078
1079 /// the allocator type
1080 using allocator_type = AllocatorType<basic_json>;
1081
1082 /// the type of an element pointer
1083 using pointer = typename std::allocator_traits<allocator_type>::pointer;
1084 /// the type of an element const pointer
1085 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
1086
1087 /// an iterator for a basic_json container
1089 /// a const iterator for a basic_json container
1091 /// a reverse iterator for a basic_json container
1093 /// a const reverse iterator for a basic_json container
1095
1096 /// @}
1097
1098
1099 /*!
1100 @brief returns the allocator associated with the container
1101 */
1103 {
1104 return allocator_type();
1105 }
1106
1107 /*!
1108 @brief returns version information on the library
1109
1110 This function returns a JSON object with information about the library,
1111 including the version number and information on the platform and compiler.
1112
1113 @return JSON object holding version information
1114 key | description
1115 ----------- | ---------------
1116 `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).
1117 `copyright` | The copyright line for the library as string.
1118 `name` | The name of the library as string.
1119 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
1120 `url` | The URL of the project as string.
1121 `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).
1122
1123 @liveexample{The following code shows an example output of the `meta()`
1124 function.,meta}
1125
1126 @complexity Constant.
1127
1128 @since 2.1.0
1129 */
1131 {
1132 basic_json result;
1133
1134 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
1135 result["name"] = "JSON for Modern C++";
1136 result["url"] = "https://github.com/nlohmann/json";
1137 result["version"] =
1138 {
1139 {"string", "2.1.1"},
1140 {"major", 2},
1141 {"minor", 1},
1142 {"patch", 1}
1143 };
1144
1145#ifdef _WIN32
1146 result["platform"] = "win32";
1147#elif defined __linux__
1148 result["platform"] = "linux";
1149#elif defined __APPLE__
1150 result["platform"] = "apple";
1151#elif defined __unix__
1152 result["platform"] = "unix";
1153#else
1154 result["platform"] = "unknown";
1155#endif
1156
1157#if defined(__clang__)
1158 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
1159#elif defined(__ICC) || defined(__INTEL_COMPILER)
1160 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
1161#elif defined(__GNUC__) || defined(__GNUG__)
1162 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
1163#elif defined(__HP_cc) || defined(__HP_aCC)
1164 result["compiler"] = "hp"
1165#elif defined(__IBMCPP__)
1166 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
1167#elif defined(_MSC_VER)
1168 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
1169#elif defined(__PGI)
1170 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
1171#elif defined(__SUNPRO_CC)
1172 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
1173#else
1174 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
1175#endif
1176
1177#ifdef __cplusplus
1178 result["compiler"]["c++"] = std::to_string(__cplusplus);
1179#else
1180 result["compiler"]["c++"] = "unknown";
1181#endif
1182 return result;
1183 }
1184
1185
1186 ///////////////////////////
1187 // JSON value data types //
1188 ///////////////////////////
1189
1190 /// @name JSON value data types
1191 /// The data types to store a JSON value. These types are derived from
1192 /// the template arguments passed to class @ref basic_json.
1193 /// @{
1194
1195 /*!
1196 @brief a type for an object
1197
1198 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
1199 > An object is an unordered collection of zero or more name/value pairs,
1200 > where a name is a string and a value is a string, number, boolean, null,
1201 > object, or array.
1202
1203 To store objects in C++, a type is defined by the template parameters
1204 described below.
1205
1206 @tparam ObjectType the container to store objects (e.g., `std::map` or
1207 `std::unordered_map`)
1208 @tparam StringType the type of the keys or names (e.g., `std::string`).
1209 The comparison function `std::less<StringType>` is used to order elements
1210 inside the container.
1211 @tparam AllocatorType the allocator to use for objects (e.g.,
1212 `std::allocator`)
1213
1214 #### Default type
1215
1216 With the default values for @a ObjectType (`std::map`), @a StringType
1217 (`std::string`), and @a AllocatorType (`std::allocator`), the default
1218 value for @a object_t is:
1219
1220 @code {.cpp}
1221 std::map<
1222 std::string, // key_type
1223 basic_json, // value_type
1224 std::less<std::string>, // key_compare
1225 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
1226 >
1227 @endcode
1228
1229 #### Behavior
1230
1231 The choice of @a object_t influences the behavior of the JSON class. With
1232 the default type, objects have the following behavior:
1233
1234 - When all names are unique, objects will be interoperable in the sense
1235 that all software implementations receiving that object will agree on
1236 the name-value mappings.
1237 - When the names within an object are not unique, later stored name/value
1238 pairs overwrite previously stored name/value pairs, leaving the used
1239 names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will
1240 be treated as equal and both stored as `{"key": 1}`.
1241 - Internally, name/value pairs are stored in lexicographical order of the
1242 names. Objects will also be serialized (see @ref dump) in this order.
1243 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
1244 and serialized as `{"a": 2, "b": 1}`.
1245 - When comparing objects, the order of the name/value pairs is irrelevant.
1246 This makes objects interoperable in the sense that they will not be
1247 affected by these differences. For instance, `{"b": 1, "a": 2}` and
1248 `{"a": 2, "b": 1}` will be treated as equal.
1249
1250 #### Limits
1251
1252 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
1253 > An implementation may set limits on the maximum depth of nesting.
1254
1255 In this class, the object's limit of nesting is not constraint explicitly.
1256 However, a maximum depth of nesting may be introduced by the compiler or
1257 runtime environment. A theoretical limit can be queried by calling the
1258 @ref max_size function of a JSON object.
1259
1260 #### Storage
1261
1262 Objects are stored as pointers in a @ref basic_json type. That is, for any
1263 access to object values, a pointer of type `object_t*` must be
1264 dereferenced.
1265
1266 @sa @ref array_t -- type for an array value
1267
1268 @since version 1.0.0
1269
1270 @note The order name/value pairs are added to the object is *not*
1271 preserved by the library. Therefore, iterating an object may return
1272 name/value pairs in a different order than they were originally stored. In
1273 fact, keys will be traversed in alphabetical order as `std::map` with
1274 `std::less` is used by default. Please note this behavior conforms to [RFC
1275 7159](http://rfc7159.net/rfc7159), because any order implements the
1276 specified "unordered" nature of JSON objects.
1277 */
1278 using object_t = ObjectType<StringType,
1279 basic_json,
1280 std::less<StringType>,
1281 AllocatorType<std::pair<const StringType,
1282 basic_json>>>;
1283
1284 /*!
1285 @brief a type for an array
1286
1287 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
1288 > An array is an ordered sequence of zero or more values.
1289
1290 To store objects in C++, a type is defined by the template parameters
1291 explained below.
1292
1293 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
1294 `std::list`)
1295 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
1296
1297 #### Default type
1298
1299 With the default values for @a ArrayType (`std::vector`) and @a
1300 AllocatorType (`std::allocator`), the default value for @a array_t is:
1301
1302 @code {.cpp}
1303 std::vector<
1304 basic_json, // value_type
1305 std::allocator<basic_json> // allocator_type
1306 >
1307 @endcode
1308
1309 #### Limits
1310
1311 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
1312 > An implementation may set limits on the maximum depth of nesting.
1313
1314 In this class, the array's limit of nesting is not constraint explicitly.
1315 However, a maximum depth of nesting may be introduced by the compiler or
1316 runtime environment. A theoretical limit can be queried by calling the
1317 @ref max_size function of a JSON array.
1318
1319 #### Storage
1320
1321 Arrays are stored as pointers in a @ref basic_json type. That is, for any
1322 access to array values, a pointer of type `array_t*` must be dereferenced.
1323
1324 @sa @ref object_t -- type for an object value
1325
1326 @since version 1.0.0
1327 */
1328 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
1329
1330 /*!
1331 @brief a type for a string
1332
1333 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
1334 > A string is a sequence of zero or more Unicode characters.
1335
1336 To store objects in C++, a type is defined by the template parameter
1337 described below. Unicode values are split by the JSON class into
1338 byte-sized characters during deserialization.
1339
1340 @tparam StringType the container to store strings (e.g., `std::string`).
1341 Note this container is used for keys/names in objects, see @ref object_t.
1342
1343 #### Default type
1344
1345 With the default values for @a StringType (`std::string`), the default
1346 value for @a string_t is:
1347
1348 @code {.cpp}
1349 std::string
1350 @endcode
1351
1352 #### Encoding
1353
1354 Strings are stored in UTF-8 encoding. Therefore, functions like
1355 `std::string::size()` or `std::string::length()` return the number of
1356 bytes in the string rather than the number of characters or glyphs.
1357
1358 #### String comparison
1359
1360 [RFC 7159](http://rfc7159.net/rfc7159) states:
1361 > Software implementations are typically required to test names of object
1362 > members for equality. Implementations that transform the textual
1363 > representation into sequences of Unicode code units and then perform the
1364 > comparison numerically, code unit by code unit, are interoperable in the
1365 > sense that implementations will agree in all cases on equality or
1366 > inequality of two strings. For example, implementations that compare
1367 > strings with escaped characters unconverted may incorrectly find that
1368 > `"a\\b"` and `"a\u005Cb"` are not equal.
1369
1370 This implementation is interoperable as it does compare strings code unit
1371 by code unit.
1372
1373 #### Storage
1374
1375 String values are stored as pointers in a @ref basic_json type. That is,
1376 for any access to string values, a pointer of type `string_t*` must be
1377 dereferenced.
1378
1379 @since version 1.0.0
1380 */
1381 using string_t = StringType;
1382
1383 /*!
1384 @brief a type for a boolean
1385
1386 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
1387 type which differentiates the two literals `true` and `false`.
1388
1389 To store objects in C++, a type is defined by the template parameter @a
1390 BooleanType which chooses the type to use.
1391
1392 #### Default type
1393
1394 With the default values for @a BooleanType (`bool`), the default value for
1395 @a boolean_t is:
1396
1397 @code {.cpp}
1398 bool
1399 @endcode
1400
1401 #### Storage
1402
1403 Boolean values are stored directly inside a @ref basic_json type.
1404
1405 @since version 1.0.0
1406 */
1407 using boolean_t = BooleanType;
1408
1409 /*!
1410 @brief a type for a number (integer)
1411
1412 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
1413 > The representation of numbers is similar to that used in most
1414 > programming languages. A number is represented in base 10 using decimal
1415 > digits. It contains an integer component that may be prefixed with an
1416 > optional minus sign, which may be followed by a fraction part and/or an
1417 > exponent part. Leading zeros are not allowed. (...) Numeric values that
1418 > cannot be represented in the grammar below (such as Infinity and NaN)
1419 > are not permitted.
1420
1421 This description includes both integer and floating-point numbers.
1422 However, C++ allows more precise storage if it is known whether the number
1423 is a signed integer, an unsigned integer or a floating-point number.
1424 Therefore, three different types, @ref number_integer_t, @ref
1425 number_unsigned_t and @ref number_float_t are used.
1426
1427 To store integer numbers in C++, a type is defined by the template
1428 parameter @a NumberIntegerType which chooses the type to use.
1429
1430 #### Default type
1431
1432 With the default values for @a NumberIntegerType (`int64_t`), the default
1433 value for @a number_integer_t is:
1434
1435 @code {.cpp}
1436 int64_t
1437 @endcode
1438
1439 #### Default behavior
1440
1441 - The restrictions about leading zeros is not enforced in C++. Instead,
1442 leading zeros in integer literals lead to an interpretation as octal
1443 number. Internally, the value will be stored as decimal number. For
1444 instance, the C++ integer literal `010` will be serialized to `8`.
1445 During deserialization, leading zeros yield an error.
1446 - Not-a-number (NaN) values will be serialized to `null`.
1447
1448 #### Limits
1449
1450 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
1451 > An implementation may set limits on the range and precision of numbers.
1452
1453 When the default type is used, the maximal integer number that can be
1454 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
1455 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
1456 that are out of range will yield over/underflow when used in a
1457 constructor. During deserialization, too large or small integer numbers
1458 will be automatically be stored as @ref number_unsigned_t or @ref
1459 number_float_t.
1460
1461 [RFC 7159](http://rfc7159.net/rfc7159) further states:
1462 > Note that when such software is used, numbers that are integers and are
1463 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
1464 > that implementations will agree exactly on their numeric values.
1465
1466 As this range is a subrange of the exactly supported range [INT64_MIN,
1467 INT64_MAX], this class's integer type is interoperable.
1468
1469 #### Storage
1470
1471 Integer number values are stored directly inside a @ref basic_json type.
1472
1473 @sa @ref number_float_t -- type for number values (floating-point)
1474
1475 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
1476
1477 @since version 1.0.0
1478 */
1479 using number_integer_t = NumberIntegerType;
1480
1481 /*!
1482 @brief a type for a number (unsigned)
1483
1484 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
1485 > The representation of numbers is similar to that used in most
1486 > programming languages. A number is represented in base 10 using decimal
1487 > digits. It contains an integer component that may be prefixed with an
1488 > optional minus sign, which may be followed by a fraction part and/or an
1489 > exponent part. Leading zeros are not allowed. (...) Numeric values that
1490 > cannot be represented in the grammar below (such as Infinity and NaN)
1491 > are not permitted.
1492
1493 This description includes both integer and floating-point numbers.
1494 However, C++ allows more precise storage if it is known whether the number
1495 is a signed integer, an unsigned integer or a floating-point number.
1496 Therefore, three different types, @ref number_integer_t, @ref
1497 number_unsigned_t and @ref number_float_t are used.
1498
1499 To store unsigned integer numbers in C++, a type is defined by the
1500 template parameter @a NumberUnsignedType which chooses the type to use.
1501
1502 #### Default type
1503
1504 With the default values for @a NumberUnsignedType (`uint64_t`), the
1505 default value for @a number_unsigned_t is:
1506
1507 @code {.cpp}
1508 uint64_t
1509 @endcode
1510
1511 #### Default behavior
1512
1513 - The restrictions about leading zeros is not enforced in C++. Instead,
1514 leading zeros in integer literals lead to an interpretation as octal
1515 number. Internally, the value will be stored as decimal number. For
1516 instance, the C++ integer literal `010` will be serialized to `8`.
1517 During deserialization, leading zeros yield an error.
1518 - Not-a-number (NaN) values will be serialized to `null`.
1519
1520 #### Limits
1521
1522 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
1523 > An implementation may set limits on the range and precision of numbers.
1524
1525 When the default type is used, the maximal integer number that can be
1526 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
1527 number that can be stored is `0`. Integer numbers that are out of range
1528 will yield over/underflow when used in a constructor. During
1529 deserialization, too large or small integer numbers will be automatically
1530 be stored as @ref number_integer_t or @ref number_float_t.
1531
1532 [RFC 7159](http://rfc7159.net/rfc7159) further states:
1533 > Note that when such software is used, numbers that are integers and are
1534 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
1535 > that implementations will agree exactly on their numeric values.
1536
1537 As this range is a subrange (when considered in conjunction with the
1538 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
1539 this class's integer type is interoperable.
1540
1541 #### Storage
1542
1543 Integer number values are stored directly inside a @ref basic_json type.
1544
1545 @sa @ref number_float_t -- type for number values (floating-point)
1546 @sa @ref number_integer_t -- type for number values (integer)
1547
1548 @since version 2.0.0
1549 */
1550 using number_unsigned_t = NumberUnsignedType;
1551
1552 /*!
1553 @brief a type for a number (floating-point)
1554
1555 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
1556 > The representation of numbers is similar to that used in most
1557 > programming languages. A number is represented in base 10 using decimal
1558 > digits. It contains an integer component that may be prefixed with an
1559 > optional minus sign, which may be followed by a fraction part and/or an
1560 > exponent part. Leading zeros are not allowed. (...) Numeric values that
1561 > cannot be represented in the grammar below (such as Infinity and NaN)
1562 > are not permitted.
1563
1564 This description includes both integer and floating-point numbers.
1565 However, C++ allows more precise storage if it is known whether the number
1566 is a signed integer, an unsigned integer or a floating-point number.
1567 Therefore, three different types, @ref number_integer_t, @ref
1568 number_unsigned_t and @ref number_float_t are used.
1569
1570 To store floating-point numbers in C++, a type is defined by the template
1571 parameter @a NumberFloatType which chooses the type to use.
1572
1573 #### Default type
1574
1575 With the default values for @a NumberFloatType (`double`), the default
1576 value for @a number_float_t is:
1577
1578 @code {.cpp}
1579 double
1580 @endcode
1581
1582 #### Default behavior
1583
1584 - The restrictions about leading zeros is not enforced in C++. Instead,
1585 leading zeros in floating-point literals will be ignored. Internally,
1586 the value will be stored as decimal number. For instance, the C++
1587 floating-point literal `01.2` will be serialized to `1.2`. During
1588 deserialization, leading zeros yield an error.
1589 - Not-a-number (NaN) values will be serialized to `null`.
1590
1591 #### Limits
1592
1593 [RFC 7159](http://rfc7159.net/rfc7159) states:
1594 > This specification allows implementations to set limits on the range and
1595 > precision of numbers accepted. Since software that implements IEEE
1596 > 754-2008 binary64 (double precision) numbers is generally available and
1597 > widely used, good interoperability can be achieved by implementations
1598 > that expect no more precision or range than these provide, in the sense
1599 > that implementations will approximate JSON numbers within the expected
1600 > precision.
1601
1602 This implementation does exactly follow this approach, as it uses double
1603 precision floating-point numbers. Note values smaller than
1604 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
1605 will be stored as NaN internally and be serialized to `null`.
1606
1607 #### Storage
1608
1609 Floating-point number values are stored directly inside a @ref basic_json
1610 type.
1611
1612 @sa @ref number_integer_t -- type for number values (integer)
1613
1614 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
1615
1616 @since version 1.0.0
1617 */
1618 using number_float_t = NumberFloatType;
1619
1620 /// @}
1621
1622 private:
1623
1624 /// helper for exception-safe object creation
1625 template<typename T, typename... Args>
1626 static T* create(Args&& ... args)
1627 {
1628 AllocatorType<T> alloc;
1629 auto deleter = [&](T * object)
1630 {
1631 alloc.deallocate(object, 1);
1632 };
1633 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
1634 alloc.construct(object.get(), std::forward<Args>(args)...);
1635 assert(object != nullptr);
1636 return object.release();
1637 }
1638
1639 ////////////////////////
1640 // JSON value storage //
1641 ////////////////////////
1642
1643 /*!
1644 @brief a JSON value
1645
1646 The actual storage for a JSON value of the @ref basic_json class. This
1647 union combines the different storage types for the JSON value types
1648 defined in @ref value_t.
1649
1650 JSON type | value_t type | used type
1651 --------- | --------------- | ------------------------
1652 object | object | pointer to @ref object_t
1653 array | array | pointer to @ref array_t
1654 string | string | pointer to @ref string_t
1655 boolean | boolean | @ref boolean_t
1656 number | number_integer | @ref number_integer_t
1657 number | number_unsigned | @ref number_unsigned_t
1658 number | number_float | @ref number_float_t
1659 null | null | *no value is stored*
1660
1661 @note Variable-length types (objects, arrays, and strings) are stored as
1662 pointers. The size of the union should not exceed 64 bits if the default
1663 value types are used.
1664
1665 @since version 1.0.0
1666 */
1668 {
1669 /// object (stored with pointer to save storage)
1671 /// array (stored with pointer to save storage)
1673 /// string (stored with pointer to save storage)
1675 /// boolean
1677 /// number (integer)
1679 /// number (unsigned integer)
1681 /// number (floating-point)
1683
1684 /// default constructor (for null values)
1685 json_value() = default;
1686 /// constructor for booleans
1688 /// constructor for numbers (integer)
1690 /// constructor for numbers (unsigned)
1692 /// constructor for numbers (floating-point)
1694 /// constructor for empty values of a given type
1696 {
1697 switch (t)
1698 {
1699 case value_t::object:
1700 {
1701 object = create<object_t>();
1702 break;
1703 }
1704
1705 case value_t::array:
1706 {
1707 array = create<array_t>();
1708 break;
1709 }
1710
1711 case value_t::string:
1712 {
1713 string = create<string_t>("");
1714 break;
1715 }
1716
1717 case value_t::boolean:
1718 {
1719 boolean = boolean_t(false);
1720 break;
1721 }
1722
1724 {
1726 break;
1727 }
1728
1730 {
1732 break;
1733 }
1734
1736 {
1738 break;
1739 }
1740
1741 case value_t::null:
1742 {
1743 break;
1744 }
1745
1746 default:
1747 {
1748 if (t == value_t::null)
1749 {
1750 JSON_THROW(std::domain_error("961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
1751 }
1752 break;
1753 }
1754 }
1755 }
1756
1757 /// constructor for strings
1759 {
1760 string = create<string_t>(value);
1761 }
1762
1763 /// constructor for objects
1765 {
1766 object = create<object_t>(value);
1767 }
1768
1769 /// constructor for arrays
1771 {
1772 array = create<array_t>(value);
1773 }
1774 };
1775
1776 /*!
1777 @brief checks the class invariants
1778
1779 This function asserts the class invariants. It needs to be called at the
1780 end of every constructor to make sure that created objects respect the
1781 invariant. Furthermore, it has to be called each time the type of a JSON
1782 value is changed, because the invariant expresses a relationship between
1783 @a m_type and @a m_value.
1784 */
1785 void assert_invariant() const
1786 {
1787 assert(m_type != value_t::object or m_value.object != nullptr);
1788 assert(m_type != value_t::array or m_value.array != nullptr);
1789 assert(m_type != value_t::string or m_value.string != nullptr);
1790 }
1791
1792 public:
1793 //////////////////////////
1794 // JSON parser callback //
1795 //////////////////////////
1796
1797 /*!
1798 @brief JSON callback events
1799
1800 This enumeration lists the parser events that can trigger calling a
1801 callback function of type @ref parser_callback_t during parsing.
1802
1803 @image html callback_events.png "Example when certain parse events are triggered"
1804
1805 @since version 1.0.0
1806 */
1807 enum class parse_event_t : uint8_t
1808 {
1809 /// the parser read `{` and started to process a JSON object
1811 /// the parser read `}` and finished processing a JSON object
1812 object_end,
1813 /// the parser read `[` and started to process a JSON array
1815 /// the parser read `]` and finished processing a JSON array
1816 array_end,
1817 /// the parser read a key of a value in an object
1818 key,
1819 /// the parser finished reading a JSON value
1820 value
1821 };
1822
1823 /*!
1824 @brief per-element parser callback type
1825
1826 With a parser callback function, the result of parsing a JSON text can be
1827 influenced. When passed to @ref parse(std::istream&, const
1828 parser_callback_t) or @ref parse(const CharT, const parser_callback_t),
1829 it is called on certain events (passed as @ref parse_event_t via parameter
1830 @a event) with a set recursion depth @a depth and context JSON value
1831 @a parsed. The return value of the callback function is a boolean
1832 indicating whether the element that emitted the callback shall be kept or
1833 not.
1834
1835 We distinguish six scenarios (determined by the event type) in which the
1836 callback function can be called. The following table describes the values
1837 of the parameters @a depth, @a event, and @a parsed.
1838
1839 parameter @a event | description | parameter @a depth | parameter @a parsed
1840 ------------------ | ----------- | ------------------ | -------------------
1841 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
1842 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
1843 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
1844 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
1845 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
1846 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
1847
1848 @image html callback_events.png "Example when certain parse events are triggered"
1849
1850 Discarding a value (i.e., returning `false`) has different effects
1851 depending on the context in which function was called:
1852
1853 - Discarded values in structured types are skipped. That is, the parser
1854 will behave as if the discarded value was never read.
1855 - In case a value outside a structured type is skipped, it is replaced
1856 with `null`. This case happens if the top-level element is skipped.
1857
1858 @param[in] depth the depth of the recursion during parsing
1859
1860 @param[in] event an event of type parse_event_t indicating the context in
1861 the callback function has been called
1862
1863 @param[in,out] parsed the current intermediate parse result; note that
1864 writing to this value has no effect for parse_event_t::key events
1865
1866 @return Whether the JSON value which called the function during parsing
1867 should be kept (`true`) or not (`false`). In the latter case, it is either
1868 skipped completely or replaced by an empty discarded object.
1869
1870 @sa @ref parse(std::istream&, parser_callback_t) or
1871 @ref parse(const CharT, const parser_callback_t) for examples
1872
1873 @since version 1.0.0
1874 */
1875 using parser_callback_t = std::function<bool(int depth,
1876 parse_event_t event,
1877 basic_json& parsed)>;
1878
1879
1880 //////////////////
1881 // constructors //
1882 //////////////////
1883
1884 /// @name constructors and destructors
1885 /// Constructors of class @ref basic_json, copy/move constructor, copy
1886 /// assignment, static functions creating objects, and the destructor.
1887 /// @{
1888
1889 /*!
1890 @brief create an empty value with a given type
1891
1892 Create an empty JSON value with a given type. The value will be default
1893 initialized with an empty value which depends on the type:
1894
1895 Value type | initial value
1896 ----------- | -------------
1897 null | `null`
1898 boolean | `false`
1899 string | `""`
1900 number | `0`
1901 object | `{}`
1902 array | `[]`
1903
1904 @param[in] value_type the type of the value to create
1905
1906 @complexity Constant.
1907
1908 @throw std::bad_alloc if allocation for object, array, or string value
1909 fails
1910
1911 @liveexample{The following code shows the constructor for different @ref
1912 value_t values,basic_json__value_t}
1913
1914 @since version 1.0.0
1915 */
1916 basic_json(const value_t value_type_)
1917 : m_type(value_type_), m_value(value_type_)
1918 {
1920 }
1921
1922 /*!
1923 @brief create a null object
1924
1925 Create a `null` JSON value. It either takes a null pointer as parameter
1926 (explicitly creating `null`) or no parameter (implicitly creating `null`).
1927 The passed null pointer itself is not read -- it is only used to choose
1928 the right constructor.
1929
1930 @complexity Constant.
1931
1932 @exceptionsafety No-throw guarantee: this constructor never throws
1933 exceptions.
1934
1935 @liveexample{The following code shows the constructor with and without a
1936 null pointer parameter.,basic_json__nullptr_t}
1937
1938 @since version 1.0.0
1939 */
1940 basic_json(std::nullptr_t = nullptr) noexcept
1941 : basic_json(value_t::null)
1942 {
1944 }
1945
1946 /*!
1947 @brief create a JSON value
1948
1949 This is a "catch all" constructor for all compatible JSON types; that is,
1950 types for which a `to_json()` method exsits. The constructor forwards the
1951 parameter @a val to that method (to `json_serializer<U>::to_json` method
1952 with `U = uncvref_t<CompatibleType>`, to be exact).
1953
1954 Template type @a CompatibleType includes, but is not limited to, the
1955 following types:
1956 - **arrays**: @ref array_t and all kinds of compatible containers such as
1957 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
1958 `std::array`, `std::set`, `std::unordered_set`, `std::multiset`, and
1959 `unordered_multiset` with a `value_type` from which a @ref basic_json
1960 value can be constructed.
1961 - **objects**: @ref object_t and all kinds of compatible associative
1962 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
1963 and `std::unordered_multimap` with a `key_type` compatible to
1964 @ref string_t and a `value_type` from which a @ref basic_json value can
1965 be constructed.
1966 - **strings**: @ref string_t, string literals, and all compatible string
1967 containers can be used.
1968 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
1969 @ref number_float_t, and all convertible number types such as `int`,
1970 `size_t`, `int64_t`, `float` or `double` can be used.
1971 - **boolean**: @ref boolean_t / `bool` can be used.
1972
1973 See the examples below.
1974
1975 @tparam CompatibleType a type such that:
1976 - @a CompatibleType is not derived from `std::istream`,
1977 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
1978 constructors),
1979 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
1980 @ref json_pointer, @ref iterator, etc ...)
1981 - @ref @ref json_serializer<U> has a
1982 `to_json(basic_json_t&, CompatibleType&&)` method
1983
1984 @tparam U = `uncvref_t<CompatibleType>`
1985
1986 @param[in] val the value to be forwarded
1987
1988 @complexity Usually linear in the size of the passed @a val, also
1989 depending on the implementation of the called `to_json()`
1990 method.
1991
1992 @throw what `json_serializer<U>::to_json()` throws
1993
1994 @liveexample{The following code shows the constructor with several
1995 compatible types.,basic_json__CompatibleType}
1996
1997 @since version 2.1.0
1998 */
1999 template<typename CompatibleType, typename U = detail::uncvref_t<CompatibleType>,
2000 detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
2001 not std::is_same<U, basic_json_t>::value and
2002 not detail::is_basic_json_nested_type<
2003 basic_json_t, U>::value and
2004 detail::has_to_json<basic_json, U>::value,
2005 int> = 0>
2006 basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
2007 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
2008 {
2009 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
2011 }
2012
2013 /*!
2014 @brief create a container (array or object) from an initializer list
2015
2016 Creates a JSON value of type array or object from the passed initializer
2017 list @a init. In case @a type_deduction is `true` (default), the type of
2018 the JSON value to be created is deducted from the initializer list @a init
2019 according to the following rules:
2020
2021 1. If the list is empty, an empty JSON object value `{}` is created.
2022 2. If the list consists of pairs whose first element is a string, a JSON
2023 object value is created where the first elements of the pairs are
2024 treated as keys and the second elements are as values.
2025 3. In all other cases, an array is created.
2026
2027 The rules aim to create the best fit between a C++ initializer list and
2028 JSON values. The rationale is as follows:
2029
2030 1. The empty initializer list is written as `{}` which is exactly an empty
2031 JSON object.
2032 2. C++ has now way of describing mapped types other than to list a list of
2033 pairs. As JSON requires that keys must be of type string, rule 2 is the
2034 weakest constraint one can pose on initializer lists to interpret them
2035 as an object.
2036 3. In all other cases, the initializer list could not be interpreted as
2037 JSON object type, so interpreting it as JSON array type is safe.
2038
2039 With the rules described above, the following JSON values cannot be
2040 expressed by an initializer list:
2041
2042 - the empty array (`[]`): use @ref array(std::initializer_list<basic_json>)
2043 with an empty initializer list in this case
2044 - arrays whose elements satisfy rule 2: use @ref
2045 array(std::initializer_list<basic_json>) with the same initializer list
2046 in this case
2047
2048 @note When used without parentheses around an empty initializer list, @ref
2049 basic_json() is called instead of this function, yielding the JSON null
2050 value.
2051
2052 @param[in] init initializer list with JSON values
2053
2054 @param[in] type_deduction internal parameter; when set to `true`, the type
2055 of the JSON value is deducted from the initializer list @a init; when set
2056 to `false`, the type provided via @a manual_type is forced. This mode is
2057 used by the functions @ref array(std::initializer_list<basic_json>) and
2058 @ref object(std::initializer_list<basic_json>).
2059
2060 @param[in] manual_type internal parameter; when @a type_deduction is set
2061 to `false`, the created JSON value will use the provided type (only @ref
2062 value_t::array and @ref value_t::object are valid); when @a type_deduction
2063 is set to `true`, this parameter has no effect
2064
2065 @throw std::domain_error if @a type_deduction is `false`, @a manual_type
2066 is `value_t::object`, but @a init contains an element which is not a pair
2067 whose first element is a string; example: `"cannot create object from
2068 initializer list"`
2069
2070 @complexity Linear in the size of the initializer list @a init.
2071
2072 @liveexample{The example below shows how JSON values are created from
2073 initializer lists.,basic_json__list_init_t}
2074
2075 @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
2076 value from an initializer list
2077 @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
2078 value from an initializer list
2079
2080 @since version 1.0.0
2081 */
2082 basic_json(std::initializer_list<basic_json> init,
2083 bool type_deduction = true,
2084 value_t manual_type = value_t::array)
2085 {
2086 // check if each element is an array with two elements whose first
2087 // element is a string
2088 bool is_an_object = std::all_of(init.begin(), init.end(),
2089 [](const basic_json & element)
2090 {
2091 return element.is_array() and element.size() == 2 and element[0].is_string();
2092 });
2093
2094 // adjust type if type deduction is not wanted
2095 if (not type_deduction)
2096 {
2097 // if array is wanted, do not create an object though possible
2098 if (manual_type == value_t::array)
2099 {
2100 is_an_object = false;
2101 }
2102
2103 // if object is wanted but impossible, throw an exception
2104 if (manual_type == value_t::object and not is_an_object)
2105 {
2106 JSON_THROW(std::domain_error("cannot create object from initializer list"));
2107 }
2108 }
2109
2110 if (is_an_object)
2111 {
2112 // the initializer list is a list of pairs -> create object
2115
2116 std::for_each(init.begin(), init.end(), [this](const basic_json & element)
2117 {
2118 m_value.object->emplace(*(element[0].m_value.string), element[1]);
2119 });
2120 }
2121 else
2122 {
2123 // the initializer list describes an array -> create array
2125 m_value.array = create<array_t>(init);
2126 }
2127
2129 }
2130
2131 /*!
2132 @brief explicitly create an array from an initializer list
2133
2134 Creates a JSON array value from a given initializer list. That is, given a
2135 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
2136 initializer list is empty, the empty array `[]` is created.
2137
2138 @note This function is only needed to express two edge cases that cannot
2139 be realized with the initializer list constructor (@ref
2140 basic_json(std::initializer_list<basic_json>, bool, value_t)). These cases
2141 are:
2142 1. creating an array whose elements are all pairs whose first element is a
2143 string -- in this case, the initializer list constructor would create an
2144 object, taking the first elements as keys
2145 2. creating an empty array -- passing the empty initializer list to the
2146 initializer list constructor yields an empty object
2147
2148 @param[in] init initializer list with JSON values to create an array from
2149 (optional)
2150
2151 @return JSON array value
2152
2153 @complexity Linear in the size of @a init.
2154
2155 @liveexample{The following code shows an example for the `array`
2156 function.,array}
2157
2158 @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
2159 create a JSON value from an initializer list
2160 @sa @ref object(std::initializer_list<basic_json>) -- create a JSON object
2161 value from an initializer list
2162
2163 @since version 1.0.0
2164 */
2165 static basic_json array(std::initializer_list<basic_json> init =
2166 std::initializer_list<basic_json>())
2167 {
2168 return basic_json(init, false, value_t::array);
2169 }
2170
2171 /*!
2172 @brief explicitly create an object from an initializer list
2173
2174 Creates a JSON object value from a given initializer list. The initializer
2175 lists elements must be pairs, and their first elements must be strings. If
2176 the initializer list is empty, the empty object `{}` is created.
2177
2178 @note This function is only added for symmetry reasons. In contrast to the
2179 related function @ref array(std::initializer_list<basic_json>), there are
2180 no cases which can only be expressed by this function. That is, any
2181 initializer list @a init can also be passed to the initializer list
2182 constructor @ref basic_json(std::initializer_list<basic_json>, bool,
2183 value_t).
2184
2185 @param[in] init initializer list to create an object from (optional)
2186
2187 @return JSON object value
2188
2189 @throw std::domain_error if @a init is not a pair whose first elements are
2190 strings; thrown by
2191 @ref basic_json(std::initializer_list<basic_json>, bool, value_t)
2192
2193 @complexity Linear in the size of @a init.
2194
2195 @liveexample{The following code shows an example for the `object`
2196 function.,object}
2197
2198 @sa @ref basic_json(std::initializer_list<basic_json>, bool, value_t) --
2199 create a JSON value from an initializer list
2200 @sa @ref array(std::initializer_list<basic_json>) -- create a JSON array
2201 value from an initializer list
2202
2203 @since version 1.0.0
2204 */
2205 static basic_json object(std::initializer_list<basic_json> init =
2206 std::initializer_list<basic_json>())
2207 {
2208 return basic_json(init, false, value_t::object);
2209 }
2210
2211 /*!
2212 @brief construct an array with count copies of given value
2213
2214 Constructs a JSON array value by creating @a cnt copies of a passed value.
2215 In case @a cnt is `0`, an empty array is created. As postcondition,
2216 `std::distance(begin(),end()) == cnt` holds.
2217
2218 @param[in] cnt the number of JSON copies of @a val to create
2219 @param[in] val the JSON value to copy
2220
2221 @complexity Linear in @a cnt.
2222
2223 @liveexample{The following code shows examples for the @ref
2224 basic_json(size_type\, const basic_json&)
2225 constructor.,basic_json__size_type_basic_json}
2226
2227 @since version 1.0.0
2228 */
2230 : m_type(value_t::array)
2231 {
2232 m_value.array = create<array_t>(cnt, val);
2234 }
2235
2236 /*!
2237 @brief construct a JSON container given an iterator range
2238
2239 Constructs the JSON value with the contents of the range `[first, last)`.
2240 The semantics depends on the different types a JSON value can have:
2241 - In case of primitive types (number, boolean, or string), @a first must
2242 be `begin()` and @a last must be `end()`. In this case, the value is
2243 copied. Otherwise, std::out_of_range is thrown.
2244 - In case of structured types (array, object), the constructor behaves as
2245 similar versions for `std::vector`.
2246 - In case of a null type, std::domain_error is thrown.
2247
2248 @tparam InputIT an input iterator type (@ref iterator or @ref
2249 const_iterator)
2250
2251 @param[in] first begin of the range to copy from (included)
2252 @param[in] last end of the range to copy from (excluded)
2253
2254 @pre Iterators @a first and @a last must be initialized. **This
2255 precondition is enforced with an assertion.**
2256
2257 @throw std::domain_error if iterators are not compatible; that is, do not
2258 belong to the same JSON value; example: `"iterators are not compatible"`
2259 @throw std::out_of_range if iterators are for a primitive type (number,
2260 boolean, or string) where an out of range error can be detected easily;
2261 example: `"iterators out of range"`
2262 @throw std::bad_alloc if allocation for object, array, or string fails
2263 @throw std::domain_error if called with a null value; example: `"cannot
2264 use construct with iterators from null"`
2265
2266 @complexity Linear in distance between @a first and @a last.
2267
2268 @liveexample{The example below shows several ways to create JSON values by
2269 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
2270
2271 @since version 1.0.0
2272 */
2273 template<class InputIT, typename std::enable_if<
2274 std::is_same<InputIT, typename basic_json_t::iterator>::value or
2275 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
2276 basic_json(InputIT first, InputIT last)
2277 {
2278 assert(first.m_object != nullptr);
2279 assert(last.m_object != nullptr);
2280
2281 // make sure iterator fits the current value
2282 if (first.m_object != last.m_object)
2283 {
2284 JSON_THROW(std::domain_error("iterators are not compatible"));
2285 }
2286
2287 // copy type from first iterator
2288 m_type = first.m_object->m_type;
2289
2290 // check if iterator range is complete for primitive values
2291 switch (m_type)
2292 {
2293 case value_t::boolean:
2297 case value_t::string:
2298 {
2299 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
2300 {
2301 JSON_THROW(std::out_of_range("iterators out of range"));
2302 }
2303 break;
2304 }
2305
2306 default:
2307 {
2308 break;
2309 }
2310 }
2311
2312 switch (m_type)
2313 {
2315 {
2316 m_value.number_integer = first.m_object->m_value.number_integer;
2317 break;
2318 }
2319
2321 {
2322 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
2323 break;
2324 }
2325
2327 {
2328 m_value.number_float = first.m_object->m_value.number_float;
2329 break;
2330 }
2331
2332 case value_t::boolean:
2333 {
2334 m_value.boolean = first.m_object->m_value.boolean;
2335 break;
2336 }
2337
2338 case value_t::string:
2339 {
2340 m_value = *first.m_object->m_value.string;
2341 break;
2342 }
2343
2344 case value_t::object:
2345 {
2346 m_value.object = create<object_t>(first.m_it.object_iterator,
2347 last.m_it.object_iterator);
2348 break;
2349 }
2350
2351 case value_t::array:
2352 {
2353 m_value.array = create<array_t>(first.m_it.array_iterator,
2354 last.m_it.array_iterator);
2355 break;
2356 }
2357
2358 default:
2359 {
2360 JSON_THROW(std::domain_error("cannot use construct with iterators from " + first.m_object->type_name()));
2361 }
2362 }
2363
2365 }
2366
2367 /*!
2368 @brief construct a JSON value given an input stream
2369
2370 @param[in,out] i stream to read a serialized JSON value from
2371 @param[in] cb a parser callback function of type @ref parser_callback_t
2372 which is used to control the deserialization by filtering unwanted values
2373 (optional)
2374
2375 @complexity Linear in the length of the input. The parser is a predictive
2376 LL(1) parser. The complexity can be higher if the parser callback function
2377 @a cb has a super-linear complexity.
2378
2379 @note A UTF-8 byte order mark is silently ignored.
2380
2381 @deprecated This constructor is deprecated and will be removed in version
2382 3.0.0 to unify the interface of the library. Deserialization will be
2383 done by stream operators or by calling one of the `parse` functions,
2384 e.g. @ref parse(std::istream&, const parser_callback_t). That is, calls
2385 like `json j(i);` for an input stream @a i need to be replaced by
2386 `json j = json::parse(i);`. See the example below.
2387
2388 @liveexample{The example below demonstrates constructing a JSON value from
2389 a `std::stringstream` with and without callback
2390 function.,basic_json__istream}
2391
2392 @since version 2.0.0, deprecated in version 2.0.3, to be removed in
2393 version 3.0.0
2394 */
2396 explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr)
2397 {
2398 *this = parser(i, cb).parse();
2400 }
2401
2402 ///////////////////////////////////////
2403 // other constructors and destructor //
2404 ///////////////////////////////////////
2405
2406 /*!
2407 @brief copy constructor
2408
2409 Creates a copy of a given JSON value.
2410
2411 @param[in] other the JSON value to copy
2412
2413 @complexity Linear in the size of @a other.
2414
2415 @requirement This function helps `basic_json` satisfying the
2416 [Container](http://en.cppreference.com/w/cpp/concept/Container)
2417 requirements:
2418 - The complexity is linear.
2419 - As postcondition, it holds: `other == basic_json(other)`.
2420
2421 @throw std::bad_alloc if allocation for object, array, or string fails.
2422
2423 @liveexample{The following code shows an example for the copy
2424 constructor.,basic_json__basic_json}
2425
2426 @since version 1.0.0
2427 */
2429 : m_type(other.m_type)
2430 {
2431 // check of passed value is valid
2432 other.assert_invariant();
2433
2434 switch (m_type)
2435 {
2436 case value_t::object:
2437 {
2438 m_value = *other.m_value.object;
2439 break;
2440 }
2441
2442 case value_t::array:
2443 {
2444 m_value = *other.m_value.array;
2445 break;
2446 }
2447
2448 case value_t::string:
2449 {
2450 m_value = *other.m_value.string;
2451 break;
2452 }
2453
2454 case value_t::boolean:
2455 {
2456 m_value = other.m_value.boolean;
2457 break;
2458 }
2459
2461 {
2463 break;
2464 }
2465
2467 {
2469 break;
2470 }
2471
2473 {
2475 break;
2476 }
2477
2478 default:
2479 {
2480 break;
2481 }
2482 }
2483
2485 }
2486
2487 /*!
2488 @brief move constructor
2489
2490 Move constructor. Constructs a JSON value with the contents of the given
2491 value @a other using move semantics. It "steals" the resources from @a
2492 other and leaves it as JSON null value.
2493
2494 @param[in,out] other value to move to this object
2495
2496 @post @a other is a JSON null value
2497
2498 @complexity Constant.
2499
2500 @liveexample{The code below shows the move constructor explicitly called
2501 via std::move.,basic_json__moveconstructor}
2502
2503 @since version 1.0.0
2504 */
2505 basic_json(basic_json&& other) noexcept
2506 : m_type(std::move(other.m_type)),
2507 m_value(std::move(other.m_value))
2508 {
2509 // check that passed value is valid
2510 other.assert_invariant();
2511
2512 // invalidate payload
2513 other.m_type = value_t::null;
2514 other.m_value = {};
2515
2517 }
2518
2519 /*!
2520 @brief copy assignment
2521
2522 Copy assignment operator. Copies a JSON value via the "copy and swap"
2523 strategy: It is expressed in terms of the copy constructor, destructor,
2524 and the swap() member function.
2525
2526 @param[in] other value to copy from
2527
2528 @complexity Linear.
2529
2530 @requirement This function helps `basic_json` satisfying the
2531 [Container](http://en.cppreference.com/w/cpp/concept/Container)
2532 requirements:
2533 - The complexity is linear.
2534
2535 @liveexample{The code below shows and example for the copy assignment. It
2536 creates a copy of value `a` which is then swapped with `b`. Finally\, the
2537 copy of `a` (which is the null value after the swap) is
2538 destroyed.,basic_json__copyassignment}
2539
2540 @since version 1.0.0
2541 */
2542 reference& operator=(basic_json other) noexcept (
2543 std::is_nothrow_move_constructible<value_t>::value and
2544 std::is_nothrow_move_assignable<value_t>::value and
2545 std::is_nothrow_move_constructible<json_value>::value and
2546 std::is_nothrow_move_assignable<json_value>::value
2547 )
2548 {
2549 // check that passed value is valid
2550 other.assert_invariant();
2551
2552 using std::swap;
2553 swap(m_type, other.m_type);
2554 swap(m_value, other.m_value);
2555
2557 return *this;
2558 }
2559
2560 /*!
2561 @brief destructor
2562
2563 Destroys the JSON value and frees all allocated memory.
2564
2565 @complexity Linear.
2566
2567 @requirement This function helps `basic_json` satisfying the
2568 [Container](http://en.cppreference.com/w/cpp/concept/Container)
2569 requirements:
2570 - The complexity is linear.
2571 - All stored elements are destroyed and all memory is freed.
2572
2573 @since version 1.0.0
2574 */
2576 {
2578
2579 switch (m_type)
2580 {
2581 case value_t::object:
2582 {
2583 AllocatorType<object_t> alloc;
2584 alloc.destroy(m_value.object);
2585 alloc.deallocate(m_value.object, 1);
2586 break;
2587 }
2588
2589 case value_t::array:
2590 {
2591 AllocatorType<array_t> alloc;
2592 alloc.destroy(m_value.array);
2593 alloc.deallocate(m_value.array, 1);
2594 break;
2595 }
2596
2597 case value_t::string:
2598 {
2599 AllocatorType<string_t> alloc;
2600 alloc.destroy(m_value.string);
2601 alloc.deallocate(m_value.string, 1);
2602 break;
2603 }
2604
2605 default:
2606 {
2607 // all other types need no specific destructor
2608 break;
2609 }
2610 }
2611 }
2612
2613 /// @}
2614
2615 public:
2616 ///////////////////////
2617 // object inspection //
2618 ///////////////////////
2619
2620 /// @name object inspection
2621 /// Functions to inspect the type of a JSON value.
2622 /// @{
2623
2624 /*!
2625 @brief serialization
2626
2627 Serialization function for JSON values. The function tries to mimic
2628 Python's `json.dumps()` function, and currently supports its @a indent
2629 parameter.
2630
2631 @param[in] indent If indent is nonnegative, then array elements and object
2632 members will be pretty-printed with that indent level. An indent level of
2633 `0` will only insert newlines. `-1` (the default) selects the most compact
2634 representation.
2635
2636 @return string containing the serialization of the JSON value
2637
2638 @complexity Linear.
2639
2640 @liveexample{The following example shows the effect of different @a indent
2641 parameters to the result of the serialization.,dump}
2642
2643 @see https://docs.python.org/2/library/json.html#json.dump
2644
2645 @since version 1.0.0
2646 */
2647 string_t dump(const int indent = -1) const
2648 {
2649 std::stringstream ss;
2650
2651 if (indent >= 0)
2652 {
2653 dump(ss, true, static_cast<unsigned int>(indent));
2654 }
2655 else
2656 {
2657 dump(ss, false, 0);
2658 }
2659
2660 return ss.str();
2661 }
2662
2663 /*!
2664 @brief return the type of the JSON value (explicit)
2665
2666 Return the type of the JSON value as a value from the @ref value_t
2667 enumeration.
2668
2669 @return the type of the JSON value
2670
2671 @complexity Constant.
2672
2673 @exceptionsafety No-throw guarantee: this member function never throws
2674 exceptions.
2675
2676 @liveexample{The following code exemplifies `type()` for all JSON
2677 types.,type}
2678
2679 @since version 1.0.0
2680 */
2681 constexpr value_t type() const noexcept
2682 {
2683 return m_type;
2684 }
2685
2686 /*!
2687 @brief return whether type is primitive
2688
2689 This function returns true iff the JSON type is primitive (string, number,
2690 boolean, or null).
2691
2692 @return `true` if type is primitive (string, number, boolean, or null),
2693 `false` otherwise.
2694
2695 @complexity Constant.
2696
2697 @exceptionsafety No-throw guarantee: this member function never throws
2698 exceptions.
2699
2700 @liveexample{The following code exemplifies `is_primitive()` for all JSON
2701 types.,is_primitive}
2702
2703 @sa @ref is_structured() -- returns whether JSON value is structured
2704 @sa @ref is_null() -- returns whether JSON value is `null`
2705 @sa @ref is_string() -- returns whether JSON value is a string
2706 @sa @ref is_boolean() -- returns whether JSON value is a boolean
2707 @sa @ref is_number() -- returns whether JSON value is a number
2708
2709 @since version 1.0.0
2710 */
2711 constexpr bool is_primitive() const noexcept
2712 {
2713 return is_null() or is_string() or is_boolean() or is_number();
2714 }
2715
2716 /*!
2717 @brief return whether type is structured
2718
2719 This function returns true iff the JSON type is structured (array or
2720 object).
2721
2722 @return `true` if type is structured (array or object), `false` otherwise.
2723
2724 @complexity Constant.
2725
2726 @exceptionsafety No-throw guarantee: this member function never throws
2727 exceptions.
2728
2729 @liveexample{The following code exemplifies `is_structured()` for all JSON
2730 types.,is_structured}
2731
2732 @sa @ref is_primitive() -- returns whether value is primitive
2733 @sa @ref is_array() -- returns whether value is an array
2734 @sa @ref is_object() -- returns whether value is an object
2735
2736 @since version 1.0.0
2737 */
2738 constexpr bool is_structured() const noexcept
2739 {
2740 return is_array() or is_object();
2741 }
2742
2743 /*!
2744 @brief return whether value is null
2745
2746 This function returns true iff the JSON value is null.
2747
2748 @return `true` if type is null, `false` otherwise.
2749
2750 @complexity Constant.
2751
2752 @exceptionsafety No-throw guarantee: this member function never throws
2753 exceptions.
2754
2755 @liveexample{The following code exemplifies `is_null()` for all JSON
2756 types.,is_null}
2757
2758 @since version 1.0.0
2759 */
2760 constexpr bool is_null() const noexcept
2761 {
2762 return m_type == value_t::null;
2763 }
2764
2765 /*!
2766 @brief return whether value is a boolean
2767
2768 This function returns true iff the JSON value is a boolean.
2769
2770 @return `true` if type is boolean, `false` otherwise.
2771
2772 @complexity Constant.
2773
2774 @exceptionsafety No-throw guarantee: this member function never throws
2775 exceptions.
2776
2777 @liveexample{The following code exemplifies `is_boolean()` for all JSON
2778 types.,is_boolean}
2779
2780 @since version 1.0.0
2781 */
2782 constexpr bool is_boolean() const noexcept
2783 {
2784 return m_type == value_t::boolean;
2785 }
2786
2787 /*!
2788 @brief return whether value is a number
2789
2790 This function returns true iff the JSON value is a number. This includes
2791 both integer and floating-point values.
2792
2793 @return `true` if type is number (regardless whether integer, unsigned
2794 integer or floating-type), `false` otherwise.
2795
2796 @complexity Constant.
2797
2798 @exceptionsafety No-throw guarantee: this member function never throws
2799 exceptions.
2800
2801 @liveexample{The following code exemplifies `is_number()` for all JSON
2802 types.,is_number}
2803
2804 @sa @ref is_number_integer() -- check if value is an integer or unsigned
2805 integer number
2806 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2807 number
2808 @sa @ref is_number_float() -- check if value is a floating-point number
2809
2810 @since version 1.0.0
2811 */
2812 constexpr bool is_number() const noexcept
2813 {
2814 return is_number_integer() or is_number_float();
2815 }
2816
2817 /*!
2818 @brief return whether value is an integer number
2819
2820 This function returns true iff the JSON value is an integer or unsigned
2821 integer number. This excludes floating-point values.
2822
2823 @return `true` if type is an integer or unsigned integer number, `false`
2824 otherwise.
2825
2826 @complexity Constant.
2827
2828 @exceptionsafety No-throw guarantee: this member function never throws
2829 exceptions.
2830
2831 @liveexample{The following code exemplifies `is_number_integer()` for all
2832 JSON types.,is_number_integer}
2833
2834 @sa @ref is_number() -- check if value is a number
2835 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2836 number
2837 @sa @ref is_number_float() -- check if value is a floating-point number
2838
2839 @since version 1.0.0
2840 */
2841 constexpr bool is_number_integer() const noexcept
2842 {
2844 }
2845
2846 /*!
2847 @brief return whether value is an unsigned integer number
2848
2849 This function returns true iff the JSON value is an unsigned integer
2850 number. This excludes floating-point and (signed) integer values.
2851
2852 @return `true` if type is an unsigned integer number, `false` otherwise.
2853
2854 @complexity Constant.
2855
2856 @exceptionsafety No-throw guarantee: this member function never throws
2857 exceptions.
2858
2859 @liveexample{The following code exemplifies `is_number_unsigned()` for all
2860 JSON types.,is_number_unsigned}
2861
2862 @sa @ref is_number() -- check if value is a number
2863 @sa @ref is_number_integer() -- check if value is an integer or unsigned
2864 integer number
2865 @sa @ref is_number_float() -- check if value is a floating-point number
2866
2867 @since version 2.0.0
2868 */
2869 constexpr bool is_number_unsigned() const noexcept
2870 {
2872 }
2873
2874 /*!
2875 @brief return whether value is a floating-point number
2876
2877 This function returns true iff the JSON value is a floating-point number.
2878 This excludes integer and unsigned integer values.
2879
2880 @return `true` if type is a floating-point number, `false` otherwise.
2881
2882 @complexity Constant.
2883
2884 @exceptionsafety No-throw guarantee: this member function never throws
2885 exceptions.
2886
2887 @liveexample{The following code exemplifies `is_number_float()` for all
2888 JSON types.,is_number_float}
2889
2890 @sa @ref is_number() -- check if value is number
2891 @sa @ref is_number_integer() -- check if value is an integer number
2892 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
2893 number
2894
2895 @since version 1.0.0
2896 */
2897 constexpr bool is_number_float() const noexcept
2898 {
2899 return m_type == value_t::number_float;
2900 }
2901
2902 /*!
2903 @brief return whether value is an object
2904
2905 This function returns true iff the JSON value is an object.
2906
2907 @return `true` if type is object, `false` otherwise.
2908
2909 @complexity Constant.
2910
2911 @exceptionsafety No-throw guarantee: this member function never throws
2912 exceptions.
2913
2914 @liveexample{The following code exemplifies `is_object()` for all JSON
2915 types.,is_object}
2916
2917 @since version 1.0.0
2918 */
2919 constexpr bool is_object() const noexcept
2920 {
2921 return m_type == value_t::object;
2922 }
2923
2924 /*!
2925 @brief return whether value is an array
2926
2927 This function returns true iff the JSON value is an array.
2928
2929 @return `true` if type is array, `false` otherwise.
2930
2931 @complexity Constant.
2932
2933 @exceptionsafety No-throw guarantee: this member function never throws
2934 exceptions.
2935
2936 @liveexample{The following code exemplifies `is_array()` for all JSON
2937 types.,is_array}
2938
2939 @since version 1.0.0
2940 */
2941 constexpr bool is_array() const noexcept
2942 {
2943 return m_type == value_t::array;
2944 }
2945
2946 /*!
2947 @brief return whether value is a string
2948
2949 This function returns true iff the JSON value is a string.
2950
2951 @return `true` if type is string, `false` otherwise.
2952
2953 @complexity Constant.
2954
2955 @exceptionsafety No-throw guarantee: this member function never throws
2956 exceptions.
2957
2958 @liveexample{The following code exemplifies `is_string()` for all JSON
2959 types.,is_string}
2960
2961 @since version 1.0.0
2962 */
2963 constexpr bool is_string() const noexcept
2964 {
2965 return m_type == value_t::string;
2966 }
2967
2968 /*!
2969 @brief return whether value is discarded
2970
2971 This function returns true iff the JSON value was discarded during parsing
2972 with a callback function (see @ref parser_callback_t).
2973
2974 @note This function will always be `false` for JSON values after parsing.
2975 That is, discarded values can only occur during parsing, but will be
2976 removed when inside a structured value or replaced by null in other cases.
2977
2978 @return `true` if type is discarded, `false` otherwise.
2979
2980 @complexity Constant.
2981
2982 @exceptionsafety No-throw guarantee: this member function never throws
2983 exceptions.
2984
2985 @liveexample{The following code exemplifies `is_discarded()` for all JSON
2986 types.,is_discarded}
2987
2988 @since version 1.0.0
2989 */
2990 constexpr bool is_discarded() const noexcept
2991 {
2992 return m_type == value_t::discarded;
2993 }
2994
2995 /*!
2996 @brief return the type of the JSON value (implicit)
2997
2998 Implicitly return the type of the JSON value as a value from the @ref
2999 value_t enumeration.
3000
3001 @return the type of the JSON value
3002
3003 @complexity Constant.
3004
3005 @exceptionsafety No-throw guarantee: this member function never throws
3006 exceptions.
3007
3008 @liveexample{The following code exemplifies the @ref value_t operator for
3009 all JSON types.,operator__value_t}
3010
3011 @since version 1.0.0
3012 */
3013 constexpr operator value_t() const noexcept
3014 {
3015 return m_type;
3016 }
3017
3018 /// @}
3019
3020 private:
3021 //////////////////
3022 // value access //
3023 //////////////////
3024
3025 /// get a boolean (explicit)
3026 boolean_t get_impl(boolean_t* /*unused*/) const
3027 {
3028 if (is_boolean())
3029 {
3030 return m_value.boolean;
3031 }
3032
3033 JSON_THROW(std::domain_error("type must be boolean, but is " + type_name()));
3034 }
3035
3036 /// get a pointer to the value (object)
3037 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
3038 {
3039 return is_object() ? m_value.object : nullptr;
3040 }
3041
3042 /// get a pointer to the value (object)
3043 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
3044 {
3045 return is_object() ? m_value.object : nullptr;
3046 }
3047
3048 /// get a pointer to the value (array)
3049 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
3050 {
3051 return is_array() ? m_value.array : nullptr;
3052 }
3053
3054 /// get a pointer to the value (array)
3055 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
3056 {
3057 return is_array() ? m_value.array : nullptr;
3058 }
3059
3060 /// get a pointer to the value (string)
3061 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
3062 {
3063 return is_string() ? m_value.string : nullptr;
3064 }
3065
3066 /// get a pointer to the value (string)
3067 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
3068 {
3069 return is_string() ? m_value.string : nullptr;
3070 }
3071
3072 /// get a pointer to the value (boolean)
3073 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
3074 {
3075 return is_boolean() ? &m_value.boolean : nullptr;
3076 }
3077
3078 /// get a pointer to the value (boolean)
3079 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
3080 {
3081 return is_boolean() ? &m_value.boolean : nullptr;
3082 }
3083
3084 /// get a pointer to the value (integer number)
3086 {
3087 return is_number_integer() ? &m_value.number_integer : nullptr;
3088 }
3089
3090 /// get a pointer to the value (integer number)
3091 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
3092 {
3093 return is_number_integer() ? &m_value.number_integer : nullptr;
3094 }
3095
3096 /// get a pointer to the value (unsigned number)
3098 {
3099 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
3100 }
3101
3102 /// get a pointer to the value (unsigned number)
3103 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
3104 {
3105 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
3106 }
3107
3108 /// get a pointer to the value (floating-point number)
3110 {
3111 return is_number_float() ? &m_value.number_float : nullptr;
3112 }
3113
3114 /// get a pointer to the value (floating-point number)
3115 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
3116 {
3117 return is_number_float() ? &m_value.number_float : nullptr;
3118 }
3119
3120 /*!
3121 @brief helper function to implement get_ref()
3122
3123 This funcion helps to implement get_ref() without code duplication for
3124 const and non-const overloads
3125
3126 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
3127
3128 @throw std::domain_error if ReferenceType does not match underlying value
3129 type of the current JSON
3130 */
3131 template<typename ReferenceType, typename ThisType>
3132 static ReferenceType get_ref_impl(ThisType& obj)
3133 {
3134 // helper type
3135 using PointerType = typename std::add_pointer<ReferenceType>::type;
3136
3137 // delegate the call to get_ptr<>()
3138 auto ptr = obj.template get_ptr<PointerType>();
3139
3140 if (ptr != nullptr)
3141 {
3142 return *ptr;
3143 }
3144
3145 JSON_THROW(std::domain_error("incompatible ReferenceType for get_ref, actual type is " +
3146 obj.type_name()));
3147 }
3148
3149 public:
3150 /// @name value access
3151 /// Direct access to the stored value of a JSON value.
3152 /// @{
3153
3154 /*!
3155 @brief get special-case overload
3156
3157 This overloads avoids a lot of template boilerplate, it can be seen as the
3158 identity method
3159
3160 @tparam BasicJsonType == @ref basic_json
3161
3162 @return a copy of *this
3163
3164 @complexity Constant.
3165
3166 @since version 2.1.0
3167 */
3168 template <
3169 typename BasicJsonType,
3172 int> = 0 >
3174 {
3175 return *this;
3176 }
3177
3178 /*!
3179 @brief get a value (explicit)
3180
3181 Explicit type conversion between the JSON value and a compatible value
3182 which is [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
3183 and [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
3184 The value is converted by calling the @ref json_serializer<ValueType>
3185 `from_json()` method.
3186
3187 The function is equivalent to executing
3188 @code {.cpp}
3189 ValueType ret;
3190 JSONSerializer<ValueType>::from_json(*this, ret);
3191 return ret;
3192 @endcode
3193
3194 This overloads is chosen if:
3195 - @a ValueType is not @ref basic_json,
3196 - @ref json_serializer<ValueType> has a `from_json()` method of the form
3197 `void from_json(const @ref basic_json&, ValueType&)`, and
3198 - @ref json_serializer<ValueType> does not have a `from_json()` method of
3199 the form `ValueType from_json(const @ref basic_json&)`
3200
3201 @tparam ValueTypeCV the provided value type
3202 @tparam ValueType the returned value type
3203
3204 @return copy of the JSON value, converted to @a ValueType
3205
3206 @throw what @ref json_serializer<ValueType> `from_json()` method throws
3207
3208 @liveexample{The example below shows several conversions from JSON values
3209 to other types. There a few things to note: (1) Floating-point numbers can
3210 be converted to integers\, (2) A JSON array can be converted to a standard
3211 `std::vector<short>`\, (3) A JSON object can be converted to C++
3212 associative containers such as `std::unordered_map<std::string\,
3213 json>`.,get__ValueType_const}
3214
3215 @since version 2.1.0
3216 */
3217 template <
3218 typename ValueTypeCV,
3219 typename ValueType = detail::uncvref_t<ValueTypeCV>,
3221 not std::is_same<basic_json_t, ValueType>::value and
3224 int > = 0 >
3225 ValueType get() const noexcept(noexcept(
3226 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
3227 {
3228 // we cannot static_assert on ValueTypeCV being non-const, because
3229 // there is support for get<const basic_json_t>(), which is why we
3230 // still need the uncvref
3231 static_assert(not std::is_reference<ValueTypeCV>::value,
3232 "get() cannot be used with reference types, you might want to use get_ref()");
3233 static_assert(std::is_default_constructible<ValueType>::value,
3234 "types must be DefaultConstructible when used with get()");
3235
3236 ValueType ret;
3238 return ret;
3239 }
3240
3241 /*!
3242 @brief get a value (explicit); special case
3243
3244 Explicit type conversion between the JSON value and a compatible value
3245 which is **not** [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
3246 and **not** [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
3247 The value is converted by calling the @ref json_serializer<ValueType>
3248 `from_json()` method.
3249
3250 The function is equivalent to executing
3251 @code {.cpp}
3252 return JSONSerializer<ValueTypeCV>::from_json(*this);
3253 @endcode
3254
3255 This overloads is chosen if:
3256 - @a ValueType is not @ref basic_json and
3257 - @ref json_serializer<ValueType> has a `from_json()` method of the form
3258 `ValueType from_json(const @ref basic_json&)`
3259
3260 @note If @ref json_serializer<ValueType> has both overloads of
3261 `from_json()`, this one is chosen.
3262
3263 @tparam ValueTypeCV the provided value type
3264 @tparam ValueType the returned value type
3265
3266 @return copy of the JSON value, converted to @a ValueType
3267
3268 @throw what @ref json_serializer<ValueType> `from_json()` method throws
3269
3270 @since version 2.1.0
3271 */
3272 template <
3273 typename ValueTypeCV,
3274 typename ValueType = detail::uncvref_t<ValueTypeCV>,
3277 ValueType>::value, int> = 0 >
3278 ValueType get() const noexcept(noexcept(
3279 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
3280 {
3281 static_assert(not std::is_reference<ValueTypeCV>::value,
3282 "get() cannot be used with reference types, you might want to use get_ref()");
3284 }
3285
3286 /*!
3287 @brief get a pointer value (explicit)
3288
3289 Explicit pointer access to the internally stored JSON value. No copies are
3290 made.
3291
3292 @warning The pointer becomes invalid if the underlying JSON object
3293 changes.
3294
3295 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
3296 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
3297 @ref number_unsigned_t, or @ref number_float_t.
3298
3299 @return pointer to the internally stored JSON value if the requested
3300 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
3301
3302 @complexity Constant.
3303
3304 @liveexample{The example below shows how pointers to internal values of a
3305 JSON value can be requested. Note that no type conversions are made and a
3306 `nullptr` is returned if the value and the requested pointer type does not
3307 match.,get__PointerType}
3308
3309 @sa @ref get_ptr() for explicit pointer-member access
3310
3311 @since version 1.0.0
3312 */
3313 template<typename PointerType, typename std::enable_if<
3314 std::is_pointer<PointerType>::value, int>::type = 0>
3315 PointerType get() noexcept
3316 {
3317 // delegate the call to get_ptr
3318 return get_ptr<PointerType>();
3319 }
3320
3321 /*!
3322 @brief get a pointer value (explicit)
3323 @copydoc get()
3324 */
3325 template<typename PointerType, typename std::enable_if<
3326 std::is_pointer<PointerType>::value, int>::type = 0>
3327 constexpr const PointerType get() const noexcept
3328 {
3329 // delegate the call to get_ptr
3330 return get_ptr<PointerType>();
3331 }
3332
3333 /*!
3334 @brief get a pointer value (implicit)
3335
3336 Implicit pointer access to the internally stored JSON value. No copies are
3337 made.
3338
3339 @warning Writing data to the pointee of the result yields an undefined
3340 state.
3341
3342 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
3343 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
3344 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
3345 assertion.
3346
3347 @return pointer to the internally stored JSON value if the requested
3348 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
3349
3350 @complexity Constant.
3351
3352 @liveexample{The example below shows how pointers to internal values of a
3353 JSON value can be requested. Note that no type conversions are made and a
3354 `nullptr` is returned if the value and the requested pointer type does not
3355 match.,get_ptr}
3356
3357 @since version 1.0.0
3358 */
3359 template<typename PointerType, typename std::enable_if<
3360 std::is_pointer<PointerType>::value, int>::type = 0>
3361 PointerType get_ptr() noexcept
3362 {
3363 // get the type of the PointerType (remove pointer and const)
3364 using pointee_t = typename std::remove_const<typename
3365 std::remove_pointer<typename
3367 // make sure the type matches the allowed types
3368 static_assert(
3369 std::is_same<object_t, pointee_t>::value
3370 or std::is_same<array_t, pointee_t>::value
3371 or std::is_same<string_t, pointee_t>::value
3372 or std::is_same<boolean_t, pointee_t>::value
3373 or std::is_same<number_integer_t, pointee_t>::value
3374 or std::is_same<number_unsigned_t, pointee_t>::value
3375 or std::is_same<number_float_t, pointee_t>::value
3376 , "incompatible pointer type");
3377
3378 // delegate the call to get_impl_ptr<>()
3379 return get_impl_ptr(static_cast<PointerType>(nullptr));
3380 }
3381
3382 /*!
3383 @brief get a pointer value (implicit)
3384 @copydoc get_ptr()
3385 */
3386 template<typename PointerType, typename std::enable_if<
3387 std::is_pointer<PointerType>::value and
3389 constexpr const PointerType get_ptr() const noexcept
3390 {
3391 // get the type of the PointerType (remove pointer and const)
3392 using pointee_t = typename std::remove_const<typename
3393 std::remove_pointer<typename
3395 // make sure the type matches the allowed types
3396 static_assert(
3397 std::is_same<object_t, pointee_t>::value
3398 or std::is_same<array_t, pointee_t>::value
3399 or std::is_same<string_t, pointee_t>::value
3400 or std::is_same<boolean_t, pointee_t>::value
3401 or std::is_same<number_integer_t, pointee_t>::value
3402 or std::is_same<number_unsigned_t, pointee_t>::value
3403 or std::is_same<number_float_t, pointee_t>::value
3404 , "incompatible pointer type");
3405
3406 // delegate the call to get_impl_ptr<>() const
3407 return get_impl_ptr(static_cast<const PointerType>(nullptr));
3408 }
3409
3410 /*!
3411 @brief get a reference value (implicit)
3412
3413 Implicit reference access to the internally stored JSON value. No copies
3414 are made.
3415
3416 @warning Writing data to the referee of the result yields an undefined
3417 state.
3418
3419 @tparam ReferenceType reference type; must be a reference to @ref array_t,
3420 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
3421 @ref number_float_t. Enforced by static assertion.
3422
3423 @return reference to the internally stored JSON value if the requested
3424 reference type @a ReferenceType fits to the JSON value; throws
3425 std::domain_error otherwise
3426
3427 @throw std::domain_error in case passed type @a ReferenceType is
3428 incompatible with the stored JSON value
3429
3430 @complexity Constant.
3431
3432 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
3433
3434 @since version 1.1.0
3435 */
3436 template<typename ReferenceType, typename std::enable_if<
3437 std::is_reference<ReferenceType>::value, int>::type = 0>
3438 ReferenceType get_ref()
3439 {
3440 // delegate call to get_ref_impl
3441 return get_ref_impl<ReferenceType>(*this);
3442 }
3443
3444 /*!
3445 @brief get a reference value (implicit)
3446 @copydoc get_ref()
3447 */
3448 template<typename ReferenceType, typename std::enable_if<
3449 std::is_reference<ReferenceType>::value and
3451 ReferenceType get_ref() const
3452 {
3453 // delegate call to get_ref_impl
3454 return get_ref_impl<ReferenceType>(*this);
3455 }
3456
3457 /*!
3458 @brief get a value (implicit)
3459
3460 Implicit type conversion between the JSON value and a compatible value.
3461 The call is realized by calling @ref get() const.
3462
3463 @tparam ValueType non-pointer type compatible to the JSON value, for
3464 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
3465 `std::vector` types for JSON arrays. The character type of @ref string_t
3466 as well as an initializer list of this type is excluded to avoid
3467 ambiguities as these types implicitly convert to `std::string`.
3468
3469 @return copy of the JSON value, converted to type @a ValueType
3470
3471 @throw std::domain_error in case passed type @a ValueType is incompatible
3472 to JSON, thrown by @ref get() const
3473
3474 @complexity Linear in the size of the JSON value.
3475
3476 @liveexample{The example below shows several conversions from JSON values
3477 to other types. There a few things to note: (1) Floating-point numbers can
3478 be converted to integers\, (2) A JSON array can be converted to a standard
3479 `std::vector<short>`\, (3) A JSON object can be converted to C++
3480 associative containers such as `std::unordered_map<std::string\,
3481 json>`.,operator__ValueType}
3482
3483 @since version 1.0.0
3484 */
3485 template < typename ValueType, typename std::enable_if <
3486 not std::is_pointer<ValueType>::value and
3487 not std::is_same<ValueType, typename string_t::value_type>::value
3488#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
3489 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
3490#endif
3491 , int >::type = 0 >
3492 operator ValueType() const
3493 {
3494 // delegate the call to get<>() const
3495 return get<ValueType>();
3496 }
3497
3498 /// @}
3499
3500
3501 ////////////////////
3502 // element access //
3503 ////////////////////
3504
3505 /// @name element access
3506 /// Access to the JSON value.
3507 /// @{
3508
3509 /*!
3510 @brief access specified array element with bounds checking
3511
3512 Returns a reference to the element at specified location @a idx, with
3513 bounds checking.
3514
3515 @param[in] idx index of the element to access
3516
3517 @return reference to the element at index @a idx
3518
3519 @throw std::domain_error if the JSON value is not an array; example:
3520 `"cannot use at() with string"`
3521 @throw std::out_of_range if the index @a idx is out of range of the array;
3522 that is, `idx >= size()`; example: `"array index 7 is out of range"`
3523
3524 @complexity Constant.
3525
3526 @liveexample{The example below shows how array elements can be read and
3527 written using `at()`.,at__size_type}
3528
3529 @since version 1.0.0
3530 */
3532 {
3533 // at only works for arrays
3534 if (is_array())
3535 {
3536 JSON_TRY
3537 {
3538 return m_value.array->at(idx);
3539 }
3540 JSON_CATCH (std::out_of_range&)
3541 {
3542 // create better exception explanation
3543 JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
3544 }
3545 }
3546 else
3547 {
3548 JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
3549 }
3550 }
3551
3552 /*!
3553 @brief access specified array element with bounds checking
3554
3555 Returns a const reference to the element at specified location @a idx,
3556 with bounds checking.
3557
3558 @param[in] idx index of the element to access
3559
3560 @return const reference to the element at index @a idx
3561
3562 @throw std::domain_error if the JSON value is not an array; example:
3563 `"cannot use at() with string"`
3564 @throw std::out_of_range if the index @a idx is out of range of the array;
3565 that is, `idx >= size()`; example: `"array index 7 is out of range"`
3566
3567 @complexity Constant.
3568
3569 @liveexample{The example below shows how array elements can be read using
3570 `at()`.,at__size_type_const}
3571
3572 @since version 1.0.0
3573 */
3575 {
3576 // at only works for arrays
3577 if (is_array())
3578 {
3579 JSON_TRY
3580 {
3581 return m_value.array->at(idx);
3582 }
3583 JSON_CATCH (std::out_of_range&)
3584 {
3585 // create better exception explanation
3586 JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
3587 }
3588 }
3589 else
3590 {
3591 JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
3592 }
3593 }
3594
3595 /*!
3596 @brief access specified object element with bounds checking
3597
3598 Returns a reference to the element at with specified key @a key, with
3599 bounds checking.
3600
3601 @param[in] key key of the element to access
3602
3603 @return reference to the element at key @a key
3604
3605 @throw std::domain_error if the JSON value is not an object; example:
3606 `"cannot use at() with boolean"`
3607 @throw std::out_of_range if the key @a key is is not stored in the object;
3608 that is, `find(key) == end()`; example: `"key "the fast" not found"`
3609
3610 @complexity Logarithmic in the size of the container.
3611
3612 @liveexample{The example below shows how object elements can be read and
3613 written using `at()`.,at__object_t_key_type}
3614
3615 @sa @ref operator[](const typename object_t::key_type&) for unchecked
3616 access by reference
3617 @sa @ref value() for access by value with a default value
3618
3619 @since version 1.0.0
3620 */
3621 reference at(const typename object_t::key_type& key)
3622 {
3623 // at only works for objects
3624 if (is_object())
3625 {
3626 JSON_TRY
3627 {
3628 return m_value.object->at(key);
3629 }
3630 JSON_CATCH (std::out_of_range&)
3631 {
3632 // create better exception explanation
3633 JSON_THROW(std::out_of_range("key '" + key + "' not found"));
3634 }
3635 }
3636 else
3637 {
3638 JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
3639 }
3640 }
3641
3642 /*!
3643 @brief access specified object element with bounds checking
3644
3645 Returns a const reference to the element at with specified key @a key,
3646 with bounds checking.
3647
3648 @param[in] key key of the element to access
3649
3650 @return const reference to the element at key @a key
3651
3652 @throw std::domain_error if the JSON value is not an object; example:
3653 `"cannot use at() with boolean"`
3654 @throw std::out_of_range if the key @a key is is not stored in the object;
3655 that is, `find(key) == end()`; example: `"key "the fast" not found"`
3656
3657 @complexity Logarithmic in the size of the container.
3658
3659 @liveexample{The example below shows how object elements can be read using
3660 `at()`.,at__object_t_key_type_const}
3661
3662 @sa @ref operator[](const typename object_t::key_type&) for unchecked
3663 access by reference
3664 @sa @ref value() for access by value with a default value
3665
3666 @since version 1.0.0
3667 */
3668 const_reference at(const typename object_t::key_type& key) const
3669 {
3670 // at only works for objects
3671 if (is_object())
3672 {
3673 JSON_TRY
3674 {
3675 return m_value.object->at(key);
3676 }
3677 JSON_CATCH (std::out_of_range&)
3678 {
3679 // create better exception explanation
3680 JSON_THROW(std::out_of_range("key '" + key + "' not found"));
3681 }
3682 }
3683 else
3684 {
3685 JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
3686 }
3687 }
3688
3689 /*!
3690 @brief access specified array element
3691
3692 Returns a reference to the element at specified location @a idx.
3693
3694 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
3695 then the array is silently filled up with `null` values to make `idx` a
3696 valid reference to the last stored element.
3697
3698 @param[in] idx index of the element to access
3699
3700 @return reference to the element at index @a idx
3701
3702 @throw std::domain_error if JSON is not an array or null; example:
3703 `"cannot use operator[] with string"`
3704
3705 @complexity Constant if @a idx is in the range of the array. Otherwise
3706 linear in `idx - size()`.
3707
3708 @liveexample{The example below shows how array elements can be read and
3709 written using `[]` operator. Note the addition of `null`
3710 values.,operatorarray__size_type}
3711
3712 @since version 1.0.0
3713 */
3715 {
3716 // implicitly convert null value to an empty array
3717 if (is_null())
3718 {
3720 m_value.array = create<array_t>();
3722 }
3723
3724 // operator[] only works for arrays
3725 if (is_array())
3726 {
3727 // fill up array with null values if given idx is outside range
3728 if (idx >= m_value.array->size())
3729 {
3730 m_value.array->insert(m_value.array->end(),
3731 idx - m_value.array->size() + 1,
3732 basic_json());
3733 }
3734
3735 return m_value.array->operator[](idx);
3736 }
3737
3738 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3739 }
3740
3741 /*!
3742 @brief access specified array element
3743
3744 Returns a const reference to the element at specified location @a idx.
3745
3746 @param[in] idx index of the element to access
3747
3748 @return const reference to the element at index @a idx
3749
3750 @throw std::domain_error if JSON is not an array; example: `"cannot use
3751 operator[] with null"`
3752
3753 @complexity Constant.
3754
3755 @liveexample{The example below shows how array elements can be read using
3756 the `[]` operator.,operatorarray__size_type_const}
3757
3758 @since version 1.0.0
3759 */
3761 {
3762 // const operator[] only works for arrays
3763 if (is_array())
3764 {
3765 return m_value.array->operator[](idx);
3766 }
3767
3768 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3769 }
3770
3771 /*!
3772 @brief access specified object element
3773
3774 Returns a reference to the element at with specified key @a key.
3775
3776 @note If @a key is not found in the object, then it is silently added to
3777 the object and filled with a `null` value to make `key` a valid reference.
3778 In case the value was `null` before, it is converted to an object.
3779
3780 @param[in] key key of the element to access
3781
3782 @return reference to the element at key @a key
3783
3784 @throw std::domain_error if JSON is not an object or null; example:
3785 `"cannot use operator[] with string"`
3786
3787 @complexity Logarithmic in the size of the container.
3788
3789 @liveexample{The example below shows how object elements can be read and
3790 written using the `[]` operator.,operatorarray__key_type}
3791
3792 @sa @ref at(const typename object_t::key_type&) for access by reference
3793 with range checking
3794 @sa @ref value() for access by value with a default value
3795
3796 @since version 1.0.0
3797 */
3798 reference operator[](const typename object_t::key_type& key)
3799 {
3800 // implicitly convert null value to an empty object
3801 if (is_null())
3802 {
3804 m_value.object = create<object_t>();
3806 }
3807
3808 // operator[] only works for objects
3809 if (is_object())
3810 {
3811 return m_value.object->operator[](key);
3812 }
3813
3814 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3815 }
3816
3817 /*!
3818 @brief read-only access specified object element
3819
3820 Returns a const reference to the element at with specified key @a key. No
3821 bounds checking is performed.
3822
3823 @warning If the element with key @a key does not exist, the behavior is
3824 undefined.
3825
3826 @param[in] key key of the element to access
3827
3828 @return const reference to the element at key @a key
3829
3830 @pre The element with key @a key must exist. **This precondition is
3831 enforced with an assertion.**
3832
3833 @throw std::domain_error if JSON is not an object; example: `"cannot use
3834 operator[] with null"`
3835
3836 @complexity Logarithmic in the size of the container.
3837
3838 @liveexample{The example below shows how object elements can be read using
3839 the `[]` operator.,operatorarray__key_type_const}
3840
3841 @sa @ref at(const typename object_t::key_type&) for access by reference
3842 with range checking
3843 @sa @ref value() for access by value with a default value
3844
3845 @since version 1.0.0
3846 */
3847 const_reference operator[](const typename object_t::key_type& key) const
3848 {
3849 // const operator[] only works for objects
3850 if (is_object())
3851 {
3852 assert(m_value.object->find(key) != m_value.object->end());
3853 return m_value.object->find(key)->second;
3854 }
3855
3856 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3857 }
3858
3859 /*!
3860 @brief access specified object element
3861
3862 Returns a reference to the element at with specified key @a key.
3863
3864 @note If @a key is not found in the object, then it is silently added to
3865 the object and filled with a `null` value to make `key` a valid reference.
3866 In case the value was `null` before, it is converted to an object.
3867
3868 @param[in] key key of the element to access
3869
3870 @return reference to the element at key @a key
3871
3872 @throw std::domain_error if JSON is not an object or null; example:
3873 `"cannot use operator[] with string"`
3874
3875 @complexity Logarithmic in the size of the container.
3876
3877 @liveexample{The example below shows how object elements can be read and
3878 written using the `[]` operator.,operatorarray__key_type}
3879
3880 @sa @ref at(const typename object_t::key_type&) for access by reference
3881 with range checking
3882 @sa @ref value() for access by value with a default value
3883
3884 @since version 1.0.0
3885 */
3886 template<typename T, std::size_t n>
3888 {
3889 return operator[](static_cast<const T>(key));
3890 }
3891
3892 /*!
3893 @brief read-only access specified object element
3894
3895 Returns a const reference to the element at with specified key @a key. No
3896 bounds checking is performed.
3897
3898 @warning If the element with key @a key does not exist, the behavior is
3899 undefined.
3900
3901 @note This function is required for compatibility reasons with Clang.
3902
3903 @param[in] key key of the element to access
3904
3905 @return const reference to the element at key @a key
3906
3907 @throw std::domain_error if JSON is not an object; example: `"cannot use
3908 operator[] with null"`
3909
3910 @complexity Logarithmic in the size of the container.
3911
3912 @liveexample{The example below shows how object elements can be read using
3913 the `[]` operator.,operatorarray__key_type_const}
3914
3915 @sa @ref at(const typename object_t::key_type&) for access by reference
3916 with range checking
3917 @sa @ref value() for access by value with a default value
3918
3919 @since version 1.0.0
3920 */
3921 template<typename T, std::size_t n>
3923 {
3924 return operator[](static_cast<const T>(key));
3925 }
3926
3927 /*!
3928 @brief access specified object element
3929
3930 Returns a reference to the element at with specified key @a key.
3931
3932 @note If @a key is not found in the object, then it is silently added to
3933 the object and filled with a `null` value to make `key` a valid reference.
3934 In case the value was `null` before, it is converted to an object.
3935
3936 @param[in] key key of the element to access
3937
3938 @return reference to the element at key @a key
3939
3940 @throw std::domain_error if JSON is not an object or null; example:
3941 `"cannot use operator[] with string"`
3942
3943 @complexity Logarithmic in the size of the container.
3944
3945 @liveexample{The example below shows how object elements can be read and
3946 written using the `[]` operator.,operatorarray__key_type}
3947
3948 @sa @ref at(const typename object_t::key_type&) for access by reference
3949 with range checking
3950 @sa @ref value() for access by value with a default value
3951
3952 @since version 1.1.0
3953 */
3954 template<typename T>
3956 {
3957 // implicitly convert null to object
3958 if (is_null())
3959 {
3963 }
3964
3965 // at only works for objects
3966 if (is_object())
3967 {
3968 return m_value.object->operator[](key);
3969 }
3970
3971 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
3972 }
3973
3974 /*!
3975 @brief read-only access specified object element
3976
3977 Returns a const reference to the element at with specified key @a key. No
3978 bounds checking is performed.
3979
3980 @warning If the element with key @a key does not exist, the behavior is
3981 undefined.
3982
3983 @param[in] key key of the element to access
3984
3985 @return const reference to the element at key @a key
3986
3987 @pre The element with key @a key must exist. **This precondition is
3988 enforced with an assertion.**
3989
3990 @throw std::domain_error if JSON is not an object; example: `"cannot use
3991 operator[] with null"`
3992
3993 @complexity Logarithmic in the size of the container.
3994
3995 @liveexample{The example below shows how object elements can be read using
3996 the `[]` operator.,operatorarray__key_type_const}
3997
3998 @sa @ref at(const typename object_t::key_type&) for access by reference
3999 with range checking
4000 @sa @ref value() for access by value with a default value
4001
4002 @since version 1.1.0
4003 */
4004 template<typename T>
4006 {
4007 // at only works for objects
4008 if (is_object())
4009 {
4010 assert(m_value.object->find(key) != m_value.object->end());
4011 return m_value.object->find(key)->second;
4012 }
4013
4014 JSON_THROW(std::domain_error("cannot use operator[] with " + type_name()));
4015 }
4016
4017 /*!
4018 @brief access specified object element with default value
4019
4020 Returns either a copy of an object's element at the specified key @a key
4021 or a given default value if no element with key @a key exists.
4022
4023 The function is basically equivalent to executing
4024 @code {.cpp}
4025 try {
4026 return at(key);
4027 } catch(std::out_of_range) {
4028 return default_value;
4029 }
4030 @endcode
4031
4032 @note Unlike @ref at(const typename object_t::key_type&), this function
4033 does not throw if the given key @a key was not found.
4034
4035 @note Unlike @ref operator[](const typename object_t::key_type& key), this
4036 function does not implicitly add an element to the position defined by @a
4037 key. This function is furthermore also applicable to const objects.
4038
4039 @param[in] key key of the element to access
4040 @param[in] default_value the value to return if @a key is not found
4041
4042 @tparam ValueType type compatible to JSON values, for instance `int` for
4043 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
4044 JSON arrays. Note the type of the expected value at @a key and the default
4045 value @a default_value must be compatible.
4046
4047 @return copy of the element at key @a key or @a default_value if @a key
4048 is not found
4049
4050 @throw std::domain_error if JSON is not an object; example: `"cannot use
4051 value() with null"`
4052
4053 @complexity Logarithmic in the size of the container.
4054
4055 @liveexample{The example below shows how object elements can be queried
4056 with a default value.,basic_json__value}
4057
4058 @sa @ref at(const typename object_t::key_type&) for access by reference
4059 with range checking
4060 @sa @ref operator[](const typename object_t::key_type&) for unchecked
4061 access by reference
4062
4063 @since version 1.0.0
4064 */
4065 template<class ValueType, typename std::enable_if<
4066 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
4067 ValueType value(const typename object_t::key_type& key, ValueType default_value) const
4068 {
4069 // at only works for objects
4070 if (is_object())
4071 {
4072 // if key is found, return value and given default value otherwise
4073 const auto it = find(key);
4074 if (it != end())
4075 {
4076 return *it;
4077 }
4078
4079 return default_value;
4080 }
4081 else
4082 {
4083 JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
4084 }
4085 }
4086
4087 /*!
4088 @brief overload for a default value of type const char*
4089 @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
4090 */
4091 string_t value(const typename object_t::key_type& key, const char* default_value) const
4092 {
4093 return value(key, string_t(default_value));
4094 }
4095
4096 /*!
4097 @brief access specified object element via JSON Pointer with default value
4098
4099 Returns either a copy of an object's element at the specified key @a key
4100 or a given default value if no element with key @a key exists.
4101
4102 The function is basically equivalent to executing
4103 @code {.cpp}
4104 try {
4105 return at(ptr);
4106 } catch(std::out_of_range) {
4107 return default_value;
4108 }
4109 @endcode
4110
4111 @note Unlike @ref at(const json_pointer&), this function does not throw
4112 if the given key @a key was not found.
4113
4114 @param[in] ptr a JSON pointer to the element to access
4115 @param[in] default_value the value to return if @a ptr found no value
4116
4117 @tparam ValueType type compatible to JSON values, for instance `int` for
4118 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
4119 JSON arrays. Note the type of the expected value at @a key and the default
4120 value @a default_value must be compatible.
4121
4122 @return copy of the element at key @a key or @a default_value if @a key
4123 is not found
4124
4125 @throw std::domain_error if JSON is not an object; example: `"cannot use
4126 value() with null"`
4127
4128 @complexity Logarithmic in the size of the container.
4129
4130 @liveexample{The example below shows how object elements can be queried
4131 with a default value.,basic_json__value_ptr}
4132
4133 @sa @ref operator[](const json_pointer&) for unchecked access by reference
4134
4135 @since version 2.0.2
4136 */
4137 template<class ValueType, typename std::enable_if<
4138 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
4139 ValueType value(const json_pointer& ptr, ValueType default_value) const
4140 {
4141 // at only works for objects
4142 if (is_object())
4143 {
4144 // if pointer resolves a value, return it or use default value
4145 JSON_TRY
4146 {
4147 return ptr.get_checked(this);
4148 }
4149 JSON_CATCH (std::out_of_range&)
4150 {
4151 return default_value;
4152 }
4153 }
4154
4155 JSON_THROW(std::domain_error("cannot use value() with " + type_name()));
4156 }
4157
4158 /*!
4159 @brief overload for a default value of type const char*
4160 @copydoc basic_json::value(const json_pointer&, ValueType) const
4161 */
4162 string_t value(const json_pointer& ptr, const char* default_value) const
4163 {
4164 return value(ptr, string_t(default_value));
4165 }
4166
4167 /*!
4168 @brief access the first element
4169
4170 Returns a reference to the first element in the container. For a JSON
4171 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
4172
4173 @return In case of a structured type (array or object), a reference to the
4174 first element is returned. In case of number, string, or boolean values, a
4175 reference to the value is returned.
4176
4177 @complexity Constant.
4178
4179 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
4180 or an empty array or object (undefined behavior, **guarded by
4181 assertions**).
4182 @post The JSON value remains unchanged.
4183
4184 @throw std::out_of_range when called on `null` value
4185
4186 @liveexample{The following code shows an example for `front()`.,front}
4187
4188 @sa @ref back() -- access the last element
4189
4190 @since version 1.0.0
4191 */
4193 {
4194 return *begin();
4195 }
4196
4197 /*!
4198 @copydoc basic_json::front()
4199 */
4201 {
4202 return *cbegin();
4203 }
4204
4205 /*!
4206 @brief access the last element
4207
4208 Returns a reference to the last element in the container. For a JSON
4209 container `c`, the expression `c.back()` is equivalent to
4210 @code {.cpp}
4211 auto tmp = c.end();
4212 --tmp;
4213 return *tmp;
4214 @endcode
4215
4216 @return In case of a structured type (array or object), a reference to the
4217 last element is returned. In case of number, string, or boolean values, a
4218 reference to the value is returned.
4219
4220 @complexity Constant.
4221
4222 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
4223 or an empty array or object (undefined behavior, **guarded by
4224 assertions**).
4225 @post The JSON value remains unchanged.
4226
4227 @throw std::out_of_range when called on `null` value.
4228
4229 @liveexample{The following code shows an example for `back()`.,back}
4230
4231 @sa @ref front() -- access the first element
4232
4233 @since version 1.0.0
4234 */
4236 {
4237 auto tmp = end();
4238 --tmp;
4239 return *tmp;
4240 }
4241
4242 /*!
4243 @copydoc basic_json::back()
4244 */
4246 {
4247 auto tmp = cend();
4248 --tmp;
4249 return *tmp;
4250 }
4251
4252 /*!
4253 @brief remove element given an iterator
4254
4255 Removes the element specified by iterator @a pos. The iterator @a pos must
4256 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
4257 but is not dereferenceable) cannot be used as a value for @a pos.
4258
4259 If called on a primitive type other than `null`, the resulting JSON value
4260 will be `null`.
4261
4262 @param[in] pos iterator to the element to remove
4263 @return Iterator following the last removed element. If the iterator @a
4264 pos refers to the last element, the `end()` iterator is returned.
4265
4266 @tparam IteratorType an @ref iterator or @ref const_iterator
4267
4268 @post Invalidates iterators and references at or after the point of the
4269 erase, including the `end()` iterator.
4270
4271 @throw std::domain_error if called on a `null` value; example: `"cannot
4272 use erase() with null"`
4273 @throw std::domain_error if called on an iterator which does not belong to
4274 the current JSON value; example: `"iterator does not fit current value"`
4275 @throw std::out_of_range if called on a primitive type with invalid
4276 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
4277 out of range"`
4278
4279 @complexity The complexity depends on the type:
4280 - objects: amortized constant
4281 - arrays: linear in distance between @a pos and the end of the container
4282 - strings: linear in the length of the string
4283 - other types: constant
4284
4285 @liveexample{The example shows the result of `erase()` for different JSON
4286 types.,erase__IteratorType}
4287
4288 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
4289 the given range
4290 @sa @ref erase(const typename object_t::key_type&) -- removes the element
4291 from an object at the given key
4292 @sa @ref erase(const size_type) -- removes the element from an array at
4293 the given index
4294
4295 @since version 1.0.0
4296 */
4297 template<class IteratorType, typename std::enable_if<
4298 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4299 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4300 = 0>
4301 IteratorType erase(IteratorType pos)
4302 {
4303 // make sure iterator fits the current value
4304 if (this != pos.m_object)
4305 {
4306 JSON_THROW(std::domain_error("iterator does not fit current value"));
4307 }
4308
4309 IteratorType result = end();
4310
4311 switch (m_type)
4312 {
4313 case value_t::boolean:
4317 case value_t::string:
4318 {
4319 if (not pos.m_it.primitive_iterator.is_begin())
4320 {
4321 JSON_THROW(std::out_of_range("iterator out of range"));
4322 }
4323
4324 if (is_string())
4325 {
4326 AllocatorType<string_t> alloc;
4327 alloc.destroy(m_value.string);
4328 alloc.deallocate(m_value.string, 1);
4329 m_value.string = nullptr;
4330 }
4331
4334 break;
4335 }
4336
4337 case value_t::object:
4338 {
4339 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
4340 break;
4341 }
4342
4343 case value_t::array:
4344 {
4345 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
4346 break;
4347 }
4348
4349 default:
4350 {
4351 JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
4352 }
4353 }
4354
4355 return result;
4356 }
4357
4358 /*!
4359 @brief remove elements given an iterator range
4360
4361 Removes the element specified by the range `[first; last)`. The iterator
4362 @a first does not need to be dereferenceable if `first == last`: erasing
4363 an empty range is a no-op.
4364
4365 If called on a primitive type other than `null`, the resulting JSON value
4366 will be `null`.
4367
4368 @param[in] first iterator to the beginning of the range to remove
4369 @param[in] last iterator past the end of the range to remove
4370 @return Iterator following the last removed element. If the iterator @a
4371 second refers to the last element, the `end()` iterator is returned.
4372
4373 @tparam IteratorType an @ref iterator or @ref const_iterator
4374
4375 @post Invalidates iterators and references at or after the point of the
4376 erase, including the `end()` iterator.
4377
4378 @throw std::domain_error if called on a `null` value; example: `"cannot
4379 use erase() with null"`
4380 @throw std::domain_error if called on iterators which does not belong to
4381 the current JSON value; example: `"iterators do not fit current value"`
4382 @throw std::out_of_range if called on a primitive type with invalid
4383 iterators (i.e., if `first != begin()` and `last != end()`); example:
4384 `"iterators out of range"`
4385
4386 @complexity The complexity depends on the type:
4387 - objects: `log(size()) + std::distance(first, last)`
4388 - arrays: linear in the distance between @a first and @a last, plus linear
4389 in the distance between @a last and end of the container
4390 - strings: linear in the length of the string
4391 - other types: constant
4392
4393 @liveexample{The example shows the result of `erase()` for different JSON
4394 types.,erase__IteratorType_IteratorType}
4395
4396 @sa @ref erase(IteratorType) -- removes the element at a given position
4397 @sa @ref erase(const typename object_t::key_type&) -- removes the element
4398 from an object at the given key
4399 @sa @ref erase(const size_type) -- removes the element from an array at
4400 the given index
4401
4402 @since version 1.0.0
4403 */
4404 template<class IteratorType, typename std::enable_if<
4405 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
4406 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
4407 = 0>
4408 IteratorType erase(IteratorType first, IteratorType last)
4409 {
4410 // make sure iterator fits the current value
4411 if (this != first.m_object or this != last.m_object)
4412 {
4413 JSON_THROW(std::domain_error("iterators do not fit current value"));
4414 }
4415
4416 IteratorType result = end();
4417
4418 switch (m_type)
4419 {
4420 case value_t::boolean:
4424 case value_t::string:
4425 {
4426 if (not first.m_it.primitive_iterator.is_begin() or not last.m_it.primitive_iterator.is_end())
4427 {
4428 JSON_THROW(std::out_of_range("iterators out of range"));
4429 }
4430
4431 if (is_string())
4432 {
4433 AllocatorType<string_t> alloc;
4434 alloc.destroy(m_value.string);
4435 alloc.deallocate(m_value.string, 1);
4436 m_value.string = nullptr;
4437 }
4438
4441 break;
4442 }
4443
4444 case value_t::object:
4445 {
4446 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
4447 last.m_it.object_iterator);
4448 break;
4449 }
4450
4451 case value_t::array:
4452 {
4453 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
4454 last.m_it.array_iterator);
4455 break;
4456 }
4457
4458 default:
4459 {
4460 JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
4461 }
4462 }
4463
4464 return result;
4465 }
4466
4467 /*!
4468 @brief remove element from a JSON object given a key
4469
4470 Removes elements from a JSON object with the key value @a key.
4471
4472 @param[in] key value of the elements to remove
4473
4474 @return Number of elements removed. If @a ObjectType is the default
4475 `std::map` type, the return value will always be `0` (@a key was not
4476 found) or `1` (@a key was found).
4477
4478 @post References and iterators to the erased elements are invalidated.
4479 Other references and iterators are not affected.
4480
4481 @throw std::domain_error when called on a type other than JSON object;
4482 example: `"cannot use erase() with null"`
4483
4484 @complexity `log(size()) + count(key)`
4485
4486 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
4487
4488 @sa @ref erase(IteratorType) -- removes the element at a given position
4489 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
4490 the given range
4491 @sa @ref erase(const size_type) -- removes the element from an array at
4492 the given index
4493
4494 @since version 1.0.0
4495 */
4496 size_type erase(const typename object_t::key_type& key)
4497 {
4498 // this erase only works for objects
4499 if (is_object())
4500 {
4501 return m_value.object->erase(key);
4502 }
4503
4504 JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
4505 }
4506
4507 /*!
4508 @brief remove element from a JSON array given an index
4509
4510 Removes element from a JSON array at the index @a idx.
4511
4512 @param[in] idx index of the element to remove
4513
4514 @throw std::domain_error when called on a type other than JSON array;
4515 example: `"cannot use erase() with null"`
4516 @throw std::out_of_range when `idx >= size()`; example: `"array index 17
4517 is out of range"`
4518
4519 @complexity Linear in distance between @a idx and the end of the container.
4520
4521 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
4522
4523 @sa @ref erase(IteratorType) -- removes the element at a given position
4524 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
4525 the given range
4526 @sa @ref erase(const typename object_t::key_type&) -- removes the element
4527 from an object at the given key
4528
4529 @since version 1.0.0
4530 */
4531 void erase(const size_type idx)
4532 {
4533 // this erase only works for arrays
4534 if (is_array())
4535 {
4536 if (idx >= size())
4537 {
4538 JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
4539 }
4540
4541 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
4542 }
4543 else
4544 {
4545 JSON_THROW(std::domain_error("cannot use erase() with " + type_name()));
4546 }
4547 }
4548
4549 /// @}
4550
4551
4552 ////////////
4553 // lookup //
4554 ////////////
4555
4556 /// @name lookup
4557 /// @{
4558
4559 /*!
4560 @brief find an element in a JSON object
4561
4562 Finds an element in a JSON object with key equivalent to @a key. If the
4563 element is not found or the JSON value is not an object, end() is
4564 returned.
4565
4566 @note This method always returns @ref end() when executed on a JSON type
4567 that is not an object.
4568
4569 @param[in] key key value of the element to search for
4570
4571 @return Iterator to an element with key equivalent to @a key. If no such
4572 element is found or the JSON value is not an object, past-the-end (see
4573 @ref end()) iterator is returned.
4574
4575 @complexity Logarithmic in the size of the JSON object.
4576
4577 @liveexample{The example shows how `find()` is used.,find__key_type}
4578
4579 @since version 1.0.0
4580 */
4581 iterator find(typename object_t::key_type key)
4582 {
4583 auto result = end();
4584
4585 if (is_object())
4586 {
4587 result.m_it.object_iterator = m_value.object->find(key);
4588 }
4589
4590 return result;
4591 }
4592
4593 /*!
4594 @brief find an element in a JSON object
4595 @copydoc find(typename object_t::key_type)
4596 */
4597 const_iterator find(typename object_t::key_type key) const
4598 {
4599 auto result = cend();
4600
4601 if (is_object())
4602 {
4603 result.m_it.object_iterator = m_value.object->find(key);
4604 }
4605
4606 return result;
4607 }
4608
4609 /*!
4610 @brief returns the number of occurrences of a key in a JSON object
4611
4612 Returns the number of elements with key @a key. If ObjectType is the
4613 default `std::map` type, the return value will always be `0` (@a key was
4614 not found) or `1` (@a key was found).
4615
4616 @note This method always returns `0` when executed on a JSON type that is
4617 not an object.
4618
4619 @param[in] key key value of the element to count
4620
4621 @return Number of elements with key @a key. If the JSON value is not an
4622 object, the return value will be `0`.
4623
4624 @complexity Logarithmic in the size of the JSON object.
4625
4626 @liveexample{The example shows how `count()` is used.,count}
4627
4628 @since version 1.0.0
4629 */
4630 size_type count(typename object_t::key_type key) const
4631 {
4632 // return 0 for all nonobject types
4633 return is_object() ? m_value.object->count(key) : 0;
4634 }
4635
4636 /// @}
4637
4638
4639 ///////////////
4640 // iterators //
4641 ///////////////
4642
4643 /// @name iterators
4644 /// @{
4645
4646 /*!
4647 @brief returns an iterator to the first element
4648
4649 Returns an iterator to the first element.
4650
4651 @image html range-begin-end.svg "Illustration from cppreference.com"
4652
4653 @return iterator to the first element
4654
4655 @complexity Constant.
4656
4657 @requirement This function helps `basic_json` satisfying the
4658 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4659 requirements:
4660 - The complexity is constant.
4661
4662 @liveexample{The following code shows an example for `begin()`.,begin}
4663
4664 @sa @ref cbegin() -- returns a const iterator to the beginning
4665 @sa @ref end() -- returns an iterator to the end
4666 @sa @ref cend() -- returns a const iterator to the end
4667
4668 @since version 1.0.0
4669 */
4670 iterator begin() noexcept
4671 {
4672 iterator result(this);
4673 result.set_begin();
4674 return result;
4675 }
4676
4677 /*!
4678 @copydoc basic_json::cbegin()
4679 */
4680 const_iterator begin() const noexcept
4681 {
4682 return cbegin();
4683 }
4684
4685 /*!
4686 @brief returns a const iterator to the first element
4687
4688 Returns a const iterator to the first element.
4689
4690 @image html range-begin-end.svg "Illustration from cppreference.com"
4691
4692 @return const iterator to the first element
4693
4694 @complexity Constant.
4695
4696 @requirement This function helps `basic_json` satisfying the
4697 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4698 requirements:
4699 - The complexity is constant.
4700 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
4701
4702 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
4703
4704 @sa @ref begin() -- returns an iterator to the beginning
4705 @sa @ref end() -- returns an iterator to the end
4706 @sa @ref cend() -- returns a const iterator to the end
4707
4708 @since version 1.0.0
4709 */
4710 const_iterator cbegin() const noexcept
4711 {
4712 const_iterator result(this);
4713 result.set_begin();
4714 return result;
4715 }
4716
4717 /*!
4718 @brief returns an iterator to one past the last element
4719
4720 Returns an iterator to one past the last element.
4721
4722 @image html range-begin-end.svg "Illustration from cppreference.com"
4723
4724 @return iterator one past the last element
4725
4726 @complexity Constant.
4727
4728 @requirement This function helps `basic_json` satisfying the
4729 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4730 requirements:
4731 - The complexity is constant.
4732
4733 @liveexample{The following code shows an example for `end()`.,end}
4734
4735 @sa @ref cend() -- returns a const iterator to the end
4736 @sa @ref begin() -- returns an iterator to the beginning
4737 @sa @ref cbegin() -- returns a const iterator to the beginning
4738
4739 @since version 1.0.0
4740 */
4741 iterator end() noexcept
4742 {
4743 iterator result(this);
4744 result.set_end();
4745 return result;
4746 }
4747
4748 /*!
4749 @copydoc basic_json::cend()
4750 */
4751 const_iterator end() const noexcept
4752 {
4753 return cend();
4754 }
4755
4756 /*!
4757 @brief returns a const iterator to one past the last element
4758
4759 Returns a const iterator to one past the last element.
4760
4761 @image html range-begin-end.svg "Illustration from cppreference.com"
4762
4763 @return const iterator one past the last element
4764
4765 @complexity Constant.
4766
4767 @requirement This function helps `basic_json` satisfying the
4768 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4769 requirements:
4770 - The complexity is constant.
4771 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
4772
4773 @liveexample{The following code shows an example for `cend()`.,cend}
4774
4775 @sa @ref end() -- returns an iterator to the end
4776 @sa @ref begin() -- returns an iterator to the beginning
4777 @sa @ref cbegin() -- returns a const iterator to the beginning
4778
4779 @since version 1.0.0
4780 */
4781 const_iterator cend() const noexcept
4782 {
4783 const_iterator result(this);
4784 result.set_end();
4785 return result;
4786 }
4787
4788 /*!
4789 @brief returns an iterator to the reverse-beginning
4790
4791 Returns an iterator to the reverse-beginning; that is, the last element.
4792
4793 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4794
4795 @complexity Constant.
4796
4797 @requirement This function helps `basic_json` satisfying the
4798 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
4799 requirements:
4800 - The complexity is constant.
4801 - Has the semantics of `reverse_iterator(end())`.
4802
4803 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
4804
4805 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
4806 @sa @ref rend() -- returns a reverse iterator to the end
4807 @sa @ref crend() -- returns a const reverse iterator to the end
4808
4809 @since version 1.0.0
4810 */
4812 {
4813 return reverse_iterator(end());
4814 }
4815
4816 /*!
4817 @copydoc basic_json::crbegin()
4818 */
4820 {
4821 return crbegin();
4822 }
4823
4824 /*!
4825 @brief returns an iterator to the reverse-end
4826
4827 Returns an iterator to the reverse-end; that is, one before the first
4828 element.
4829
4830 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4831
4832 @complexity Constant.
4833
4834 @requirement This function helps `basic_json` satisfying the
4835 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
4836 requirements:
4837 - The complexity is constant.
4838 - Has the semantics of `reverse_iterator(begin())`.
4839
4840 @liveexample{The following code shows an example for `rend()`.,rend}
4841
4842 @sa @ref crend() -- returns a const reverse iterator to the end
4843 @sa @ref rbegin() -- returns a reverse iterator to the beginning
4844 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
4845
4846 @since version 1.0.0
4847 */
4849 {
4850 return reverse_iterator(begin());
4851 }
4852
4853 /*!
4854 @copydoc basic_json::crend()
4855 */
4857 {
4858 return crend();
4859 }
4860
4861 /*!
4862 @brief returns a const reverse iterator to the last element
4863
4864 Returns a const iterator to the reverse-beginning; that is, the last
4865 element.
4866
4867 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4868
4869 @complexity Constant.
4870
4871 @requirement This function helps `basic_json` satisfying the
4872 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
4873 requirements:
4874 - The complexity is constant.
4875 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
4876
4877 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
4878
4879 @sa @ref rbegin() -- returns a reverse iterator to the beginning
4880 @sa @ref rend() -- returns a reverse iterator to the end
4881 @sa @ref crend() -- returns a const reverse iterator to the end
4882
4883 @since version 1.0.0
4884 */
4886 {
4887 return const_reverse_iterator(cend());
4888 }
4889
4890 /*!
4891 @brief returns a const reverse iterator to one before the first
4892
4893 Returns a const reverse iterator to the reverse-end; that is, one before
4894 the first element.
4895
4896 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
4897
4898 @complexity Constant.
4899
4900 @requirement This function helps `basic_json` satisfying the
4901 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
4902 requirements:
4903 - The complexity is constant.
4904 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
4905
4906 @liveexample{The following code shows an example for `crend()`.,crend}
4907
4908 @sa @ref rend() -- returns a reverse iterator to the end
4909 @sa @ref rbegin() -- returns a reverse iterator to the beginning
4910 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
4911
4912 @since version 1.0.0
4913 */
4915 {
4917 }
4918
4919 private:
4920 // forward declaration
4921 template<typename IteratorType> class iteration_proxy;
4922
4923 public:
4924 /*!
4925 @brief wrapper to access iterator member functions in range-based for
4926
4927 This function allows to access @ref iterator::key() and @ref
4928 iterator::value() during range-based for loops. In these loops, a
4929 reference to the JSON values is returned, so there is no access to the
4930 underlying iterator.
4931
4932 @note The name of this function is not yet final and may change in the
4933 future.
4934 */
4936 {
4937 return iteration_proxy<iterator>(cont);
4938 }
4939
4940 /*!
4941 @copydoc iterator_wrapper(reference)
4942 */
4944 {
4946 }
4947
4948 /// @}
4949
4950
4951 //////////////
4952 // capacity //
4953 //////////////
4954
4955 /// @name capacity
4956 /// @{
4957
4958 /*!
4959 @brief checks whether the container is empty
4960
4961 Checks if a JSON value has no elements.
4962
4963 @return The return value depends on the different types and is
4964 defined as follows:
4965 Value type | return value
4966 ----------- | -------------
4967 null | `true`
4968 boolean | `false`
4969 string | `false`
4970 number | `false`
4971 object | result of function `object_t::empty()`
4972 array | result of function `array_t::empty()`
4973
4974 @note This function does not return whether a string stored as JSON value
4975 is empty - it returns whether the JSON container itself is empty which is
4976 false in the case of a string.
4977
4978 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
4979 the Container concept; that is, their `empty()` functions have constant
4980 complexity.
4981
4982 @requirement This function helps `basic_json` satisfying the
4983 [Container](http://en.cppreference.com/w/cpp/concept/Container)
4984 requirements:
4985 - The complexity is constant.
4986 - Has the semantics of `begin() == end()`.
4987
4988 @liveexample{The following code uses `empty()` to check if a JSON
4989 object contains any elements.,empty}
4990
4991 @sa @ref size() -- returns the number of elements
4992
4993 @since version 1.0.0
4994 */
4995 bool empty() const noexcept
4996 {
4997 switch (m_type)
4998 {
4999 case value_t::null:
5000 {
5001 // null values are empty
5002 return true;
5003 }
5004
5005 case value_t::array:
5006 {
5007 // delegate call to array_t::empty()
5008 return m_value.array->empty();
5009 }
5010
5011 case value_t::object:
5012 {
5013 // delegate call to object_t::empty()
5014 return m_value.object->empty();
5015 }
5016
5017 default:
5018 {
5019 // all other types are nonempty
5020 return false;
5021 }
5022 }
5023 }
5024
5025 /*!
5026 @brief returns the number of elements
5027
5028 Returns the number of elements in a JSON value.
5029
5030 @return The return value depends on the different types and is
5031 defined as follows:
5032 Value type | return value
5033 ----------- | -------------
5034 null | `0`
5035 boolean | `1`
5036 string | `1`
5037 number | `1`
5038 object | result of function object_t::size()
5039 array | result of function array_t::size()
5040
5041 @note This function does not return the length of a string stored as JSON
5042 value - it returns the number of elements in the JSON value which is 1 in
5043 the case of a string.
5044
5045 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
5046 the Container concept; that is, their size() functions have constant
5047 complexity.
5048
5049 @requirement This function helps `basic_json` satisfying the
5050 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5051 requirements:
5052 - The complexity is constant.
5053 - Has the semantics of `std::distance(begin(), end())`.
5054
5055 @liveexample{The following code calls `size()` on the different value
5056 types.,size}
5057
5058 @sa @ref empty() -- checks whether the container is empty
5059 @sa @ref max_size() -- returns the maximal number of elements
5060
5061 @since version 1.0.0
5062 */
5063 size_type size() const noexcept
5064 {
5065 switch (m_type)
5066 {
5067 case value_t::null:
5068 {
5069 // null values are empty
5070 return 0;
5071 }
5072
5073 case value_t::array:
5074 {
5075 // delegate call to array_t::size()
5076 return m_value.array->size();
5077 }
5078
5079 case value_t::object:
5080 {
5081 // delegate call to object_t::size()
5082 return m_value.object->size();
5083 }
5084
5085 default:
5086 {
5087 // all other types have size 1
5088 return 1;
5089 }
5090 }
5091 }
5092
5093 /*!
5094 @brief returns the maximum possible number of elements
5095
5096 Returns the maximum number of elements a JSON value is able to hold due to
5097 system or library implementation limitations, i.e. `std::distance(begin(),
5098 end())` for the JSON value.
5099
5100 @return The return value depends on the different types and is
5101 defined as follows:
5102 Value type | return value
5103 ----------- | -------------
5104 null | `0` (same as `size()`)
5105 boolean | `1` (same as `size()`)
5106 string | `1` (same as `size()`)
5107 number | `1` (same as `size()`)
5108 object | result of function `object_t::max_size()`
5109 array | result of function `array_t::max_size()`
5110
5111 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
5112 the Container concept; that is, their `max_size()` functions have constant
5113 complexity.
5114
5115 @requirement This function helps `basic_json` satisfying the
5116 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5117 requirements:
5118 - The complexity is constant.
5119 - Has the semantics of returning `b.size()` where `b` is the largest
5120 possible JSON value.
5121
5122 @liveexample{The following code calls `max_size()` on the different value
5123 types. Note the output is implementation specific.,max_size}
5124
5125 @sa @ref size() -- returns the number of elements
5126
5127 @since version 1.0.0
5128 */
5129 size_type max_size() const noexcept
5130 {
5131 switch (m_type)
5132 {
5133 case value_t::array:
5134 {
5135 // delegate call to array_t::max_size()
5136 return m_value.array->max_size();
5137 }
5138
5139 case value_t::object:
5140 {
5141 // delegate call to object_t::max_size()
5142 return m_value.object->max_size();
5143 }
5144
5145 default:
5146 {
5147 // all other types have max_size() == size()
5148 return size();
5149 }
5150 }
5151 }
5152
5153 /// @}
5154
5155
5156 ///////////////
5157 // modifiers //
5158 ///////////////
5159
5160 /// @name modifiers
5161 /// @{
5162
5163 /*!
5164 @brief clears the contents
5165
5166 Clears the content of a JSON value and resets it to the default value as
5167 if @ref basic_json(value_t) would have been called:
5168
5169 Value type | initial value
5170 ----------- | -------------
5171 null | `null`
5172 boolean | `false`
5173 string | `""`
5174 number | `0`
5175 object | `{}`
5176 array | `[]`
5177
5178 @complexity Linear in the size of the JSON value.
5179
5180 @liveexample{The example below shows the effect of `clear()` to different
5181 JSON types.,clear}
5182
5183 @since version 1.0.0
5184 */
5185 void clear() noexcept
5186 {
5187 switch (m_type)
5188 {
5190 {
5192 break;
5193 }
5194
5196 {
5198 break;
5199 }
5200
5202 {
5203 m_value.number_float = 0.0;
5204 break;
5205 }
5206
5207 case value_t::boolean:
5208 {
5209 m_value.boolean = false;
5210 break;
5211 }
5212
5213 case value_t::string:
5214 {
5215 m_value.string->clear();
5216 break;
5217 }
5218
5219 case value_t::array:
5220 {
5221 m_value.array->clear();
5222 break;
5223 }
5224
5225 case value_t::object:
5226 {
5227 m_value.object->clear();
5228 break;
5229 }
5230
5231 default:
5232 {
5233 break;
5234 }
5235 }
5236 }
5237
5238 /*!
5239 @brief add an object to an array
5240
5241 Appends the given element @a val to the end of the JSON value. If the
5242 function is called on a JSON null value, an empty array is created before
5243 appending @a val.
5244
5245 @param[in] val the value to add to the JSON array
5246
5247 @throw std::domain_error when called on a type other than JSON array or
5248 null; example: `"cannot use push_back() with number"`
5249
5250 @complexity Amortized constant.
5251
5252 @liveexample{The example shows how `push_back()` and `+=` can be used to
5253 add elements to a JSON array. Note how the `null` value was silently
5254 converted to a JSON array.,push_back}
5255
5256 @since version 1.0.0
5257 */
5259 {
5260 // push_back only works for null objects or arrays
5261 if (not(is_null() or is_array()))
5262 {
5263 JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
5264 }
5265
5266 // transform null object into an array
5267 if (is_null())
5268 {
5272 }
5273
5274 // add element to array (move semantics)
5275 m_value.array->push_back(std::move(val));
5276 // invalidate object
5277 val.m_type = value_t::null;
5278 }
5279
5280 /*!
5281 @brief add an object to an array
5282 @copydoc push_back(basic_json&&)
5283 */
5285 {
5286 push_back(std::move(val));
5287 return *this;
5288 }
5289
5290 /*!
5291 @brief add an object to an array
5292 @copydoc push_back(basic_json&&)
5293 */
5294 void push_back(const basic_json& val)
5295 {
5296 // push_back only works for null objects or arrays
5297 if (not(is_null() or is_array()))
5298 {
5299 JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
5300 }
5301
5302 // transform null object into an array
5303 if (is_null())
5304 {
5308 }
5309
5310 // add element to array
5311 m_value.array->push_back(val);
5312 }
5313
5314 /*!
5315 @brief add an object to an array
5316 @copydoc push_back(basic_json&&)
5317 */
5319 {
5320 push_back(val);
5321 return *this;
5322 }
5323
5324 /*!
5325 @brief add an object to an object
5326
5327 Inserts the given element @a val to the JSON object. If the function is
5328 called on a JSON null value, an empty object is created before inserting
5329 @a val.
5330
5331 @param[in] val the value to add to the JSON object
5332
5333 @throw std::domain_error when called on a type other than JSON object or
5334 null; example: `"cannot use push_back() with number"`
5335
5336 @complexity Logarithmic in the size of the container, O(log(`size()`)).
5337
5338 @liveexample{The example shows how `push_back()` and `+=` can be used to
5339 add elements to a JSON object. Note how the `null` value was silently
5340 converted to a JSON object.,push_back__object_t__value}
5341
5342 @since version 1.0.0
5343 */
5344 void push_back(const typename object_t::value_type& val)
5345 {
5346 // push_back only works for null objects or objects
5347 if (not(is_null() or is_object()))
5348 {
5349 JSON_THROW(std::domain_error("cannot use push_back() with " + type_name()));
5350 }
5351
5352 // transform null object into an object
5353 if (is_null())
5354 {
5358 }
5359
5360 // add element to array
5361 m_value.object->insert(val);
5362 }
5363
5364 /*!
5365 @brief add an object to an object
5366 @copydoc push_back(const typename object_t::value_type&)
5367 */
5368 reference operator+=(const typename object_t::value_type& val)
5369 {
5370 push_back(val);
5371 return *this;
5372 }
5373
5374 /*!
5375 @brief add an object to an object
5376
5377 This function allows to use `push_back` with an initializer list. In case
5378
5379 1. the current value is an object,
5380 2. the initializer list @a init contains only two elements, and
5381 3. the first element of @a init is a string,
5382
5383 @a init is converted into an object element and added using
5384 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
5385 is converted to a JSON value and added using @ref push_back(basic_json&&).
5386
5387 @param init an initializer list
5388
5389 @complexity Linear in the size of the initializer list @a init.
5390
5391 @note This function is required to resolve an ambiguous overload error,
5392 because pairs like `{"key", "value"}` can be both interpreted as
5393 `object_t::value_type` or `std::initializer_list<basic_json>`, see
5394 https://github.com/nlohmann/json/issues/235 for more information.
5395
5396 @liveexample{The example shows how initializer lists are treated as
5397 objects when possible.,push_back__initializer_list}
5398 */
5399 void push_back(std::initializer_list<basic_json> init)
5400 {
5401 if (is_object() and init.size() == 2 and init.begin()->is_string())
5402 {
5403 const string_t key = *init.begin();
5404 push_back(typename object_t::value_type(key, *(init.begin() + 1)));
5405 }
5406 else
5407 {
5409 }
5410 }
5411
5412 /*!
5413 @brief add an object to an object
5414 @copydoc push_back(std::initializer_list<basic_json>)
5415 */
5416 reference operator+=(std::initializer_list<basic_json> init)
5417 {
5418 push_back(init);
5419 return *this;
5420 }
5421
5422 /*!
5423 @brief add an object to an array
5424
5425 Creates a JSON value from the passed parameters @a args to the end of the
5426 JSON value. If the function is called on a JSON null value, an empty array
5427 is created before appending the value created from @a args.
5428
5429 @param[in] args arguments to forward to a constructor of @ref basic_json
5430 @tparam Args compatible types to create a @ref basic_json object
5431
5432 @throw std::domain_error when called on a type other than JSON array or
5433 null; example: `"cannot use emplace_back() with number"`
5434
5435 @complexity Amortized constant.
5436
5437 @liveexample{The example shows how `push_back()` can be used to add
5438 elements to a JSON array. Note how the `null` value was silently converted
5439 to a JSON array.,emplace_back}
5440
5441 @since version 2.0.8
5442 */
5443 template<class... Args>
5444 void emplace_back(Args&& ... args)
5445 {
5446 // emplace_back only works for null objects or arrays
5447 if (not(is_null() or is_array()))
5448 {
5449 JSON_THROW(std::domain_error("cannot use emplace_back() with " + type_name()));
5450 }
5451
5452 // transform null object into an array
5453 if (is_null())
5454 {
5458 }
5459
5460 // add element to array (perfect forwarding)
5461 m_value.array->emplace_back(std::forward<Args>(args)...);
5462 }
5463
5464 /*!
5465 @brief add an object to an object if key does not exist
5466
5467 Inserts a new element into a JSON object constructed in-place with the
5468 given @a args if there is no element with the key in the container. If the
5469 function is called on a JSON null value, an empty object is created before
5470 appending the value created from @a args.
5471
5472 @param[in] args arguments to forward to a constructor of @ref basic_json
5473 @tparam Args compatible types to create a @ref basic_json object
5474
5475 @return a pair consisting of an iterator to the inserted element, or the
5476 already-existing element if no insertion happened, and a bool
5477 denoting whether the insertion took place.
5478
5479 @throw std::domain_error when called on a type other than JSON object or
5480 null; example: `"cannot use emplace() with number"`
5481
5482 @complexity Logarithmic in the size of the container, O(log(`size()`)).
5483
5484 @liveexample{The example shows how `emplace()` can be used to add elements
5485 to a JSON object. Note how the `null` value was silently converted to a
5486 JSON object. Further note how no value is added if there was already one
5487 value stored with the same key.,emplace}
5488
5489 @since version 2.0.8
5490 */
5491 template<class... Args>
5492 std::pair<iterator, bool> emplace(Args&& ... args)
5493 {
5494 // emplace only works for null objects or arrays
5495 if (not(is_null() or is_object()))
5496 {
5497 JSON_THROW(std::domain_error("cannot use emplace() with " + type_name()));
5498 }
5499
5500 // transform null object into an object
5501 if (is_null())
5502 {
5506 }
5507
5508 // add element to array (perfect forwarding)
5509 auto res = m_value.object->emplace(std::forward<Args>(args)...);
5510 // create result iterator and set iterator to the result of emplace
5511 auto it = begin();
5512 it.m_it.object_iterator = res.first;
5513
5514 // return pair of iterator and boolean
5515 return {it, res.second};
5516 }
5517
5518 /*!
5519 @brief inserts element
5520
5521 Inserts element @a val before iterator @a pos.
5522
5523 @param[in] pos iterator before which the content will be inserted; may be
5524 the end() iterator
5525 @param[in] val element to insert
5526 @return iterator pointing to the inserted @a val.
5527
5528 @throw std::domain_error if called on JSON values other than arrays;
5529 example: `"cannot use insert() with string"`
5530 @throw std::domain_error if @a pos is not an iterator of *this; example:
5531 `"iterator does not fit current value"`
5532
5533 @complexity Constant plus linear in the distance between @a pos and end of
5534 the container.
5535
5536 @liveexample{The example shows how `insert()` is used.,insert}
5537
5538 @since version 1.0.0
5539 */
5541 {
5542 // insert only works for arrays
5543 if (is_array())
5544 {
5545 // check if iterator pos fits to this JSON value
5546 if (pos.m_object != this)
5547 {
5548 JSON_THROW(std::domain_error("iterator does not fit current value"));
5549 }
5550
5551 // insert to array and return iterator
5552 iterator result(this);
5553 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
5554 return result;
5555 }
5556
5557 JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
5558 }
5559
5560 /*!
5561 @brief inserts element
5562 @copydoc insert(const_iterator, const basic_json&)
5563 */
5565 {
5566 return insert(pos, val);
5567 }
5568
5569 /*!
5570 @brief inserts elements
5571
5572 Inserts @a cnt copies of @a val before iterator @a pos.
5573
5574 @param[in] pos iterator before which the content will be inserted; may be
5575 the end() iterator
5576 @param[in] cnt number of copies of @a val to insert
5577 @param[in] val element to insert
5578 @return iterator pointing to the first element inserted, or @a pos if
5579 `cnt==0`
5580
5581 @throw std::domain_error if called on JSON values other than arrays;
5582 example: `"cannot use insert() with string"`
5583 @throw std::domain_error if @a pos is not an iterator of *this; example:
5584 `"iterator does not fit current value"`
5585
5586 @complexity Linear in @a cnt plus linear in the distance between @a pos
5587 and end of the container.
5588
5589 @liveexample{The example shows how `insert()` is used.,insert__count}
5590
5591 @since version 1.0.0
5592 */
5594 {
5595 // insert only works for arrays
5596 if (is_array())
5597 {
5598 // check if iterator pos fits to this JSON value
5599 if (pos.m_object != this)
5600 {
5601 JSON_THROW(std::domain_error("iterator does not fit current value"));
5602 }
5603
5604 // insert to array and return iterator
5605 iterator result(this);
5606 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
5607 return result;
5608 }
5609
5610 JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
5611 }
5612
5613 /*!
5614 @brief inserts elements
5615
5616 Inserts elements from range `[first, last)` before iterator @a pos.
5617
5618 @param[in] pos iterator before which the content will be inserted; may be
5619 the end() iterator
5620 @param[in] first begin of the range of elements to insert
5621 @param[in] last end of the range of elements to insert
5622
5623 @throw std::domain_error if called on JSON values other than arrays;
5624 example: `"cannot use insert() with string"`
5625 @throw std::domain_error if @a pos is not an iterator of *this; example:
5626 `"iterator does not fit current value"`
5627 @throw std::domain_error if @a first and @a last do not belong to the same
5628 JSON value; example: `"iterators do not fit"`
5629 @throw std::domain_error if @a first or @a last are iterators into
5630 container for which insert is called; example: `"passed iterators may not
5631 belong to container"`
5632
5633 @return iterator pointing to the first element inserted, or @a pos if
5634 `first==last`
5635
5636 @complexity Linear in `std::distance(first, last)` plus linear in the
5637 distance between @a pos and end of the container.
5638
5639 @liveexample{The example shows how `insert()` is used.,insert__range}
5640
5641 @since version 1.0.0
5642 */
5644 {
5645 // insert only works for arrays
5646 if (not is_array())
5647 {
5648 JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
5649 }
5650
5651 // check if iterator pos fits to this JSON value
5652 if (pos.m_object != this)
5653 {
5654 JSON_THROW(std::domain_error("iterator does not fit current value"));
5655 }
5656
5657 // check if range iterators belong to the same JSON object
5658 if (first.m_object != last.m_object)
5659 {
5660 JSON_THROW(std::domain_error("iterators do not fit"));
5661 }
5662
5663 if (first.m_object == this or last.m_object == this)
5664 {
5665 JSON_THROW(std::domain_error("passed iterators may not belong to container"));
5666 }
5667
5668 // insert to array and return iterator
5669 iterator result(this);
5670 result.m_it.array_iterator = m_value.array->insert(
5671 pos.m_it.array_iterator,
5672 first.m_it.array_iterator,
5673 last.m_it.array_iterator);
5674 return result;
5675 }
5676
5677 /*!
5678 @brief inserts elements
5679
5680 Inserts elements from initializer list @a ilist before iterator @a pos.
5681
5682 @param[in] pos iterator before which the content will be inserted; may be
5683 the end() iterator
5684 @param[in] ilist initializer list to insert the values from
5685
5686 @throw std::domain_error if called on JSON values other than arrays;
5687 example: `"cannot use insert() with string"`
5688 @throw std::domain_error if @a pos is not an iterator of *this; example:
5689 `"iterator does not fit current value"`
5690
5691 @return iterator pointing to the first element inserted, or @a pos if
5692 `ilist` is empty
5693
5694 @complexity Linear in `ilist.size()` plus linear in the distance between
5695 @a pos and end of the container.
5696
5697 @liveexample{The example shows how `insert()` is used.,insert__ilist}
5698
5699 @since version 1.0.0
5700 */
5701 iterator insert(const_iterator pos, std::initializer_list<basic_json> ilist)
5702 {
5703 // insert only works for arrays
5704 if (not is_array())
5705 {
5706 JSON_THROW(std::domain_error("cannot use insert() with " + type_name()));
5707 }
5708
5709 // check if iterator pos fits to this JSON value
5710 if (pos.m_object != this)
5711 {
5712 JSON_THROW(std::domain_error("iterator does not fit current value"));
5713 }
5714
5715 // insert to array and return iterator
5716 iterator result(this);
5717 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist);
5718 return result;
5719 }
5720
5721 /*!
5722 @brief exchanges the values
5723
5724 Exchanges the contents of the JSON value with those of @a other. Does not
5725 invoke any move, copy, or swap operations on individual elements. All
5726 iterators and references remain valid. The past-the-end iterator is
5727 invalidated.
5728
5729 @param[in,out] other JSON value to exchange the contents with
5730
5731 @complexity Constant.
5732
5733 @liveexample{The example below shows how JSON values can be swapped with
5734 `swap()`.,swap__reference}
5735
5736 @since version 1.0.0
5737 */
5738 void swap(reference other) noexcept (
5739 std::is_nothrow_move_constructible<value_t>::value and
5740 std::is_nothrow_move_assignable<value_t>::value and
5741 std::is_nothrow_move_constructible<json_value>::value and
5742 std::is_nothrow_move_assignable<json_value>::value
5743 )
5744 {
5745 std::swap(m_type, other.m_type);
5746 std::swap(m_value, other.m_value);
5748 }
5749
5750 /*!
5751 @brief exchanges the values
5752
5753 Exchanges the contents of a JSON array with those of @a other. Does not
5754 invoke any move, copy, or swap operations on individual elements. All
5755 iterators and references remain valid. The past-the-end iterator is
5756 invalidated.
5757
5758 @param[in,out] other array to exchange the contents with
5759
5760 @throw std::domain_error when JSON value is not an array; example:
5761 `"cannot use swap() with string"`
5762
5763 @complexity Constant.
5764
5765 @liveexample{The example below shows how arrays can be swapped with
5766 `swap()`.,swap__array_t}
5767
5768 @since version 1.0.0
5769 */
5770 void swap(array_t& other)
5771 {
5772 // swap only works for arrays
5773 if (is_array())
5774 {
5775 std::swap(*(m_value.array), other);
5776 }
5777 else
5778 {
5779 JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
5780 }
5781 }
5782
5783 /*!
5784 @brief exchanges the values
5785
5786 Exchanges the contents of a JSON object with those of @a other. Does not
5787 invoke any move, copy, or swap operations on individual elements. All
5788 iterators and references remain valid. The past-the-end iterator is
5789 invalidated.
5790
5791 @param[in,out] other object to exchange the contents with
5792
5793 @throw std::domain_error when JSON value is not an object; example:
5794 `"cannot use swap() with string"`
5795
5796 @complexity Constant.
5797
5798 @liveexample{The example below shows how objects can be swapped with
5799 `swap()`.,swap__object_t}
5800
5801 @since version 1.0.0
5802 */
5803 void swap(object_t& other)
5804 {
5805 // swap only works for objects
5806 if (is_object())
5807 {
5808 std::swap(*(m_value.object), other);
5809 }
5810 else
5811 {
5812 JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
5813 }
5814 }
5815
5816 /*!
5817 @brief exchanges the values
5818
5819 Exchanges the contents of a JSON string with those of @a other. Does not
5820 invoke any move, copy, or swap operations on individual elements. All
5821 iterators and references remain valid. The past-the-end iterator is
5822 invalidated.
5823
5824 @param[in,out] other string to exchange the contents with
5825
5826 @throw std::domain_error when JSON value is not a string; example: `"cannot
5827 use swap() with boolean"`
5828
5829 @complexity Constant.
5830
5831 @liveexample{The example below shows how strings can be swapped with
5832 `swap()`.,swap__string_t}
5833
5834 @since version 1.0.0
5835 */
5836 void swap(string_t& other)
5837 {
5838 // swap only works for strings
5839 if (is_string())
5840 {
5841 std::swap(*(m_value.string), other);
5842 }
5843 else
5844 {
5845 JSON_THROW(std::domain_error("cannot use swap() with " + type_name()));
5846 }
5847 }
5848
5849 /// @}
5850
5851 public:
5852 //////////////////////////////////////////
5853 // lexicographical comparison operators //
5854 //////////////////////////////////////////
5855
5856 /// @name lexicographical comparison operators
5857 /// @{
5858
5859 /*!
5860 @brief comparison: equal
5861
5862 Compares two JSON values for equality according to the following rules:
5863 - Two JSON values are equal if (1) they are from the same type and (2)
5864 their stored values are the same.
5865 - Integer and floating-point numbers are automatically converted before
5866 comparison. Floating-point numbers are compared indirectly: two
5867 floating-point numbers `f1` and `f2` are considered equal if neither
5868 `f1 > f2` nor `f2 > f1` holds.
5869 - Two JSON null values are equal.
5870
5871 @param[in] lhs first JSON value to consider
5872 @param[in] rhs second JSON value to consider
5873 @return whether the values @a lhs and @a rhs are equal
5874
5875 @complexity Linear.
5876
5877 @liveexample{The example demonstrates comparing several JSON
5878 types.,operator__equal}
5879
5880 @since version 1.0.0
5881 */
5882 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
5883 {
5884 const auto lhs_type = lhs.type();
5885 const auto rhs_type = rhs.type();
5886
5887 if (lhs_type == rhs_type)
5888 {
5889 switch (lhs_type)
5890 {
5891 case value_t::array:
5892 {
5893 return *lhs.m_value.array == *rhs.m_value.array;
5894 }
5895 case value_t::object:
5896 {
5897 return *lhs.m_value.object == *rhs.m_value.object;
5898 }
5899 case value_t::null:
5900 {
5901 return true;
5902 }
5903 case value_t::string:
5904 {
5905 return *lhs.m_value.string == *rhs.m_value.string;
5906 }
5907 case value_t::boolean:
5908 {
5909 return lhs.m_value.boolean == rhs.m_value.boolean;
5910 }
5912 {
5913 return lhs.m_value.number_integer == rhs.m_value.number_integer;
5914 }
5916 {
5917 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
5918 }
5920 {
5921 return lhs.m_value.number_float == rhs.m_value.number_float;
5922 }
5923 default:
5924 {
5925 return false;
5926 }
5927 }
5928 }
5929 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
5930 {
5931 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
5932 }
5933 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
5934 {
5935 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
5936 }
5937 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
5938 {
5939 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
5940 }
5941 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
5942 {
5943 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
5944 }
5945 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
5946 {
5947 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
5948 }
5949 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
5950 {
5951 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
5952 }
5953
5954 return false;
5955 }
5956
5957 /*!
5958 @brief comparison: equal
5959 @copydoc operator==(const_reference, const_reference)
5960 */
5961 template<typename ScalarType, typename std::enable_if<
5962 std::is_scalar<ScalarType>::value, int>::type = 0>
5963 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
5964 {
5965 return (lhs == basic_json(rhs));
5966 }
5967
5968 /*!
5969 @brief comparison: equal
5970 @copydoc operator==(const_reference, const_reference)
5971 */
5972 template<typename ScalarType, typename std::enable_if<
5973 std::is_scalar<ScalarType>::value, int>::type = 0>
5974 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
5975 {
5976 return (basic_json(lhs) == rhs);
5977 }
5978
5979 /*!
5980 @brief comparison: not equal
5981
5982 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
5983
5984 @param[in] lhs first JSON value to consider
5985 @param[in] rhs second JSON value to consider
5986 @return whether the values @a lhs and @a rhs are not equal
5987
5988 @complexity Linear.
5989
5990 @liveexample{The example demonstrates comparing several JSON
5991 types.,operator__notequal}
5992
5993 @since version 1.0.0
5994 */
5995 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
5996 {
5997 return not (lhs == rhs);
5998 }
5999
6000 /*!
6001 @brief comparison: not equal
6002 @copydoc operator!=(const_reference, const_reference)
6003 */
6004 template<typename ScalarType, typename std::enable_if<
6005 std::is_scalar<ScalarType>::value, int>::type = 0>
6006 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
6007 {
6008 return (lhs != basic_json(rhs));
6009 }
6010
6011 /*!
6012 @brief comparison: not equal
6013 @copydoc operator!=(const_reference, const_reference)
6014 */
6015 template<typename ScalarType, typename std::enable_if<
6016 std::is_scalar<ScalarType>::value, int>::type = 0>
6017 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
6018 {
6019 return (basic_json(lhs) != rhs);
6020 }
6021
6022 /*!
6023 @brief comparison: less than
6024
6025 Compares whether one JSON value @a lhs is less than another JSON value @a
6026 rhs according to the following rules:
6027 - If @a lhs and @a rhs have the same type, the values are compared using
6028 the default `<` operator.
6029 - Integer and floating-point numbers are automatically converted before
6030 comparison
6031 - In case @a lhs and @a rhs have different types, the values are ignored
6032 and the order of the types is considered, see
6033 @ref operator<(const value_t, const value_t).
6034
6035 @param[in] lhs first JSON value to consider
6036 @param[in] rhs second JSON value to consider
6037 @return whether @a lhs is less than @a rhs
6038
6039 @complexity Linear.
6040
6041 @liveexample{The example demonstrates comparing several JSON
6042 types.,operator__less}
6043
6044 @since version 1.0.0
6045 */
6046 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
6047 {
6048 const auto lhs_type = lhs.type();
6049 const auto rhs_type = rhs.type();
6050
6051 if (lhs_type == rhs_type)
6052 {
6053 switch (lhs_type)
6054 {
6055 case value_t::array:
6056 {
6057 return *(lhs.m_value.array) < *(rhs.m_value.array);
6058 }
6059 case value_t::object:
6060 {
6061 return *lhs.m_value.object < *rhs.m_value.object;
6062 }
6063 case value_t::null:
6064 {
6065 return false;
6066 }
6067 case value_t::string:
6068 {
6069 return *lhs.m_value.string < *rhs.m_value.string;
6070 }
6071 case value_t::boolean:
6072 {
6073 return lhs.m_value.boolean < rhs.m_value.boolean;
6074 }
6076 {
6077 return lhs.m_value.number_integer < rhs.m_value.number_integer;
6078 }
6080 {
6081 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
6082 }
6084 {
6085 return lhs.m_value.number_float < rhs.m_value.number_float;
6086 }
6087 default:
6088 {
6089 return false;
6090 }
6091 }
6092 }
6093 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
6094 {
6095 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
6096 }
6097 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
6098 {
6099 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
6100 }
6101 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
6102 {
6103 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
6104 }
6105 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
6106 {
6107 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
6108 }
6109 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
6110 {
6111 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
6112 }
6113 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
6114 {
6115 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
6116 }
6117
6118 // We only reach this line if we cannot compare values. In that case,
6119 // we compare types. Note we have to call the operator explicitly,
6120 // because MSVC has problems otherwise.
6121 return operator<(lhs_type, rhs_type);
6122 }
6123
6124 /*!
6125 @brief comparison: less than or equal
6126
6127 Compares whether one JSON value @a lhs is less than or equal to another
6128 JSON value by calculating `not (rhs < lhs)`.
6129
6130 @param[in] lhs first JSON value to consider
6131 @param[in] rhs second JSON value to consider
6132 @return whether @a lhs is less than or equal to @a rhs
6133
6134 @complexity Linear.
6135
6136 @liveexample{The example demonstrates comparing several JSON
6137 types.,operator__greater}
6138
6139 @since version 1.0.0
6140 */
6141 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
6142 {
6143 return not (rhs < lhs);
6144 }
6145
6146 /*!
6147 @brief comparison: greater than
6148
6149 Compares whether one JSON value @a lhs is greater than another
6150 JSON value by calculating `not (lhs <= rhs)`.
6151
6152 @param[in] lhs first JSON value to consider
6153 @param[in] rhs second JSON value to consider
6154 @return whether @a lhs is greater than to @a rhs
6155
6156 @complexity Linear.
6157
6158 @liveexample{The example demonstrates comparing several JSON
6159 types.,operator__lessequal}
6160
6161 @since version 1.0.0
6162 */
6163 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
6164 {
6165 return not (lhs <= rhs);
6166 }
6167
6168 /*!
6169 @brief comparison: greater than or equal
6170
6171 Compares whether one JSON value @a lhs is greater than or equal to another
6172 JSON value by calculating `not (lhs < rhs)`.
6173
6174 @param[in] lhs first JSON value to consider
6175 @param[in] rhs second JSON value to consider
6176 @return whether @a lhs is greater than or equal to @a rhs
6177
6178 @complexity Linear.
6179
6180 @liveexample{The example demonstrates comparing several JSON
6181 types.,operator__greaterequal}
6182
6183 @since version 1.0.0
6184 */
6185 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
6186 {
6187 return not (lhs < rhs);
6188 }
6189
6190 /// @}
6191
6192
6193 ///////////////////
6194 // serialization //
6195 ///////////////////
6196
6197 /// @name serialization
6198 /// @{
6199
6200 /*!
6201 @brief serialize to stream
6202
6203 Serialize the given JSON value @a j to the output stream @a o. The JSON
6204 value will be serialized using the @ref dump member function. The
6205 indentation of the output can be controlled with the member variable
6206 `width` of the output stream @a o. For instance, using the manipulator
6207 `std::setw(4)` on @a o sets the indentation level to `4` and the
6208 serialization result is the same as calling `dump(4)`.
6209
6210 @param[in,out] o stream to serialize to
6211 @param[in] j JSON value to serialize
6212
6213 @return the stream @a o
6214
6215 @complexity Linear.
6216
6217 @liveexample{The example below shows the serialization with different
6218 parameters to `width` to adjust the indentation level.,operator_serialize}
6219
6220 @since version 1.0.0
6221 */
6222 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
6223 {
6224 // read width member and use it as indentation parameter if nonzero
6225 const bool pretty_print = (o.width() > 0);
6226 const auto indentation = (pretty_print ? o.width() : 0);
6227
6228 // reset width to 0 for subsequent calls to this stream
6229 o.width(0);
6230
6231 // do the actual serialization
6232 j.dump(o, pretty_print, static_cast<unsigned int>(indentation));
6233
6234 return o;
6235 }
6236
6237 /*!
6238 @brief serialize to stream
6239 @copydoc operator<<(std::ostream&, const basic_json&)
6240 */
6241 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
6242 {
6243 return o << j;
6244 }
6245
6246 /// @}
6247
6248
6249 /////////////////////
6250 // deserialization //
6251 /////////////////////
6252
6253 /// @name deserialization
6254 /// @{
6255
6256 /*!
6257 @brief deserialize from an array
6258
6259 This function reads from an array of 1-byte values.
6260
6261 @pre Each element of the container has a size of 1 byte. Violating this
6262 precondition yields undefined behavior. **This precondition is enforced
6263 with a static assertion.**
6264
6265 @param[in] array array to read from
6266 @param[in] cb a parser callback function of type @ref parser_callback_t
6267 which is used to control the deserialization by filtering unwanted values
6268 (optional)
6269
6270 @return result of the deserialization
6271
6272 @complexity Linear in the length of the input. The parser is a predictive
6273 LL(1) parser. The complexity can be higher if the parser callback function
6274 @a cb has a super-linear complexity.
6275
6276 @note A UTF-8 byte order mark is silently ignored.
6277
6278 @liveexample{The example below demonstrates the `parse()` function reading
6279 from an array.,parse__array__parser_callback_t}
6280
6281 @since version 2.0.3
6282 */
6283 template<class T, std::size_t N>
6285 const parser_callback_t cb = nullptr)
6286 {
6287 // delegate the call to the iterator-range parse overload
6288 return parse(std::begin(array), std::end(array), cb);
6289 }
6290
6291 /*!
6292 @brief deserialize from string literal
6293
6294 @tparam CharT character/literal type with size of 1 byte
6295 @param[in] s string literal to read a serialized JSON value from
6296 @param[in] cb a parser callback function of type @ref parser_callback_t
6297 which is used to control the deserialization by filtering unwanted values
6298 (optional)
6299
6300 @return result of the deserialization
6301
6302 @complexity Linear in the length of the input. The parser is a predictive
6303 LL(1) parser. The complexity can be higher if the parser callback function
6304 @a cb has a super-linear complexity.
6305
6306 @note A UTF-8 byte order mark is silently ignored.
6307 @note String containers like `std::string` or @ref string_t can be parsed
6308 with @ref parse(const ContiguousContainer&, const parser_callback_t)
6309
6310 @liveexample{The example below demonstrates the `parse()` function with
6311 and without callback function.,parse__string__parser_callback_t}
6312
6313 @sa @ref parse(std::istream&, const parser_callback_t) for a version that
6314 reads from an input stream
6315
6316 @since version 1.0.0 (originally for @ref string_t)
6317 */
6318 template<typename CharT, typename std::enable_if<
6319 std::is_pointer<CharT>::value and
6321 sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0>
6322 static basic_json parse(const CharT s,
6323 const parser_callback_t cb = nullptr)
6324 {
6325 return parser(reinterpret_cast<const char*>(s), cb).parse();
6326 }
6327
6328 /*!
6329 @brief deserialize from stream
6330
6331 @param[in,out] i stream to read a serialized JSON value from
6332 @param[in] cb a parser callback function of type @ref parser_callback_t
6333 which is used to control the deserialization by filtering unwanted values
6334 (optional)
6335
6336 @return result of the deserialization
6337
6338 @complexity Linear in the length of the input. The parser is a predictive
6339 LL(1) parser. The complexity can be higher if the parser callback function
6340 @a cb has a super-linear complexity.
6341
6342 @note A UTF-8 byte order mark is silently ignored.
6343
6344 @liveexample{The example below demonstrates the `parse()` function with
6345 and without callback function.,parse__istream__parser_callback_t}
6346
6347 @sa @ref parse(const CharT, const parser_callback_t) for a version
6348 that reads from a string
6349
6350 @since version 1.0.0
6351 */
6352 static basic_json parse(std::istream& i,
6353 const parser_callback_t cb = nullptr)
6354 {
6355 return parser(i, cb).parse();
6356 }
6357
6358 /*!
6359 @copydoc parse(std::istream&, const parser_callback_t)
6360 */
6361 static basic_json parse(std::istream&& i,
6362 const parser_callback_t cb = nullptr)
6363 {
6364 return parser(i, cb).parse();
6365 }
6366
6367 /*!
6368 @brief deserialize from an iterator range with contiguous storage
6369
6370 This function reads from an iterator range of a container with contiguous
6371 storage of 1-byte values. Compatible container types include
6372 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
6373 `std::initializer_list`. Furthermore, C-style arrays can be used with
6374 `std::begin()`/`std::end()`. User-defined containers can be used as long
6375 as they implement random-access iterators and a contiguous storage.
6376
6377 @pre The iterator range is contiguous. Violating this precondition yields
6378 undefined behavior. **This precondition is enforced with an assertion.**
6379 @pre Each element in the range has a size of 1 byte. Violating this
6380 precondition yields undefined behavior. **This precondition is enforced
6381 with a static assertion.**
6382
6383 @warning There is no way to enforce all preconditions at compile-time. If
6384 the function is called with noncompliant iterators and with
6385 assertions switched off, the behavior is undefined and will most
6386 likely yield segmentation violation.
6387
6388 @tparam IteratorType iterator of container with contiguous storage
6389 @param[in] first begin of the range to parse (included)
6390 @param[in] last end of the range to parse (excluded)
6391 @param[in] cb a parser callback function of type @ref parser_callback_t
6392 which is used to control the deserialization by filtering unwanted values
6393 (optional)
6394
6395 @return result of the deserialization
6396
6397 @complexity Linear in the length of the input. The parser is a predictive
6398 LL(1) parser. The complexity can be higher if the parser callback function
6399 @a cb has a super-linear complexity.
6400
6401 @note A UTF-8 byte order mark is silently ignored.
6402
6403 @liveexample{The example below demonstrates the `parse()` function reading
6404 from an iterator range.,parse__iteratortype__parser_callback_t}
6405
6406 @since version 2.0.3
6407 */
6408 template<class IteratorType, typename std::enable_if<
6409 std::is_base_of<
6410 std::random_access_iterator_tag,
6411 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
6412 static basic_json parse(IteratorType first, IteratorType last,
6413 const parser_callback_t cb = nullptr)
6414 {
6415 // assertion to check that the iterator range is indeed contiguous,
6416 // see http://stackoverflow.com/a/35008842/266378 for more discussion
6417 assert(std::accumulate(first, last, std::pair<bool, int>(true, 0),
6418 [&first](std::pair<bool, int> res, decltype(*first) val)
6419 {
6420 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
6421 return res;
6422 }).first);
6423
6424 // assertion to check that each element is 1 byte long
6425 static_assert(sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
6426 "each element in the iterator range must have the size of 1 byte");
6427
6428 // if iterator range is empty, create a parser with an empty string
6429 // to generate "unexpected EOF" error message
6430 if (std::distance(first, last) <= 0)
6431 {
6432 return parser("").parse();
6433 }
6434
6435 return parser(first, last, cb).parse();
6436 }
6437
6438 /*!
6439 @brief deserialize from a container with contiguous storage
6440
6441 This function reads from a container with contiguous storage of 1-byte
6442 values. Compatible container types include `std::vector`, `std::string`,
6443 `std::array`, and `std::initializer_list`. User-defined containers can be
6444 used as long as they implement random-access iterators and a contiguous
6445 storage.
6446
6447 @pre The container storage is contiguous. Violating this precondition
6448 yields undefined behavior. **This precondition is enforced with an
6449 assertion.**
6450 @pre Each element of the container has a size of 1 byte. Violating this
6451 precondition yields undefined behavior. **This precondition is enforced
6452 with a static assertion.**
6453
6454 @warning There is no way to enforce all preconditions at compile-time. If
6455 the function is called with a noncompliant container and with
6456 assertions switched off, the behavior is undefined and will most
6457 likely yield segmentation violation.
6458
6459 @tparam ContiguousContainer container type with contiguous storage
6460 @param[in] c container to read from
6461 @param[in] cb a parser callback function of type @ref parser_callback_t
6462 which is used to control the deserialization by filtering unwanted values
6463 (optional)
6464
6465 @return result of the deserialization
6466
6467 @complexity Linear in the length of the input. The parser is a predictive
6468 LL(1) parser. The complexity can be higher if the parser callback function
6469 @a cb has a super-linear complexity.
6470
6471 @note A UTF-8 byte order mark is silently ignored.
6472
6473 @liveexample{The example below demonstrates the `parse()` function reading
6474 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
6475
6476 @since version 2.0.3
6477 */
6478 template<class ContiguousContainer, typename std::enable_if<
6479 not std::is_pointer<ContiguousContainer>::value and
6480 std::is_base_of<
6481 std::random_access_iterator_tag,
6482 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value
6483 , int>::type = 0>
6484 static basic_json parse(const ContiguousContainer& c,
6485 const parser_callback_t cb = nullptr)
6486 {
6487 // delegate the call to the iterator-range parse overload
6488 return parse(std::begin(c), std::end(c), cb);
6489 }
6490
6491 /*!
6492 @brief deserialize from stream
6493
6494 Deserializes an input stream to a JSON value.
6495
6496 @param[in,out] i input stream to read a serialized JSON value from
6497 @param[in,out] j JSON value to write the deserialized input to
6498
6499 @throw std::invalid_argument in case of parse errors
6500
6501 @complexity Linear in the length of the input. The parser is a predictive
6502 LL(1) parser.
6503
6504 @note A UTF-8 byte order mark is silently ignored.
6505
6506 @liveexample{The example below shows how a JSON value is constructed by
6507 reading a serialization from a stream.,operator_deserialize}
6508
6509 @sa parse(std::istream&, const parser_callback_t) for a variant with a
6510 parser callback function to filter values while parsing
6511
6512 @since version 1.0.0
6513 */
6514 friend std::istream& operator<<(basic_json& j, std::istream& i)
6515 {
6516 j = parser(i).parse();
6517 return i;
6518 }
6519
6520 /*!
6521 @brief deserialize from stream
6522 @copydoc operator<<(basic_json&, std::istream&)
6523 */
6524 friend std::istream& operator>>(std::istream& i, basic_json& j)
6525 {
6526 j = parser(i).parse();
6527 return i;
6528 }
6529
6530 /// @}
6531
6532 //////////////////////////////////////////
6533 // binary serialization/deserialization //
6534 //////////////////////////////////////////
6535
6536 /// @name binary serialization/deserialization support
6537 /// @{
6538
6539 private:
6540 /*!
6541 @note Some code in the switch cases has been copied, because otherwise
6542 copilers would complain about implicit fallthrough and there is no
6543 portable attribute to mute such warnings.
6544 */
6545 template<typename T>
6546 static void add_to_vector(std::vector<uint8_t>& vec, size_t bytes, const T number)
6547 {
6548 assert(bytes == 1 or bytes == 2 or bytes == 4 or bytes == 8);
6549
6550 switch (bytes)
6551 {
6552 case 8:
6553 {
6554 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 070) & 0xff));
6555 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 060) & 0xff));
6556 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 050) & 0xff));
6557 vec.push_back(static_cast<uint8_t>((static_cast<uint64_t>(number) >> 040) & 0xff));
6558 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
6559 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
6560 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6561 vec.push_back(static_cast<uint8_t>(number & 0xff));
6562 break;
6563 }
6564
6565 case 4:
6566 {
6567 vec.push_back(static_cast<uint8_t>((number >> 030) & 0xff));
6568 vec.push_back(static_cast<uint8_t>((number >> 020) & 0xff));
6569 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6570 vec.push_back(static_cast<uint8_t>(number & 0xff));
6571 break;
6572 }
6573
6574 case 2:
6575 {
6576 vec.push_back(static_cast<uint8_t>((number >> 010) & 0xff));
6577 vec.push_back(static_cast<uint8_t>(number & 0xff));
6578 break;
6579 }
6580
6581 case 1:
6582 {
6583 vec.push_back(static_cast<uint8_t>(number & 0xff));
6584 break;
6585 }
6586 }
6587 }
6588
6589 /*!
6590 @brief take sufficient bytes from a vector to fill an integer variable
6591
6592 In the context of binary serialization formats, we need to read several
6593 bytes from a byte vector and combine them to multi-byte integral data
6594 types.
6595
6596 @param[in] vec byte vector to read from
6597 @param[in] current_index the position in the vector after which to read
6598
6599 @return the next sizeof(T) bytes from @a vec, in reverse order as T
6600
6601 @tparam T the integral return type
6602
6603 @throw std::out_of_range if there are less than sizeof(T)+1 bytes in the
6604 vector @a vec to read
6605
6606 In the for loop, the bytes from the vector are copied in reverse order into
6607 the return value. In the figures below, let sizeof(T)=4 and `i` be the loop
6608 variable.
6609
6610 Precondition:
6611
6612 vec: | | | a | b | c | d | T: | | | | |
6613 ^ ^ ^ ^
6614 current_index i ptr sizeof(T)
6615
6616 Postcondition:
6617
6618 vec: | | | a | b | c | d | T: | d | c | b | a |
6619 ^ ^ ^
6620 | i ptr
6621 current_index
6622
6623 @sa Code adapted from <http://stackoverflow.com/a/41031865/266378>.
6624 */
6625 template<typename T>
6626 static T get_from_vector(const std::vector<uint8_t>& vec, const size_t current_index)
6627 {
6628 if (current_index + sizeof(T) + 1 > vec.size())
6629 {
6630 JSON_THROW(std::out_of_range("cannot read " + std::to_string(sizeof(T)) + " bytes from vector"));
6631 }
6632
6633 T result;
6634 auto* ptr = reinterpret_cast<uint8_t*>(&result);
6635 for (size_t i = 0; i < sizeof(T); ++i)
6636 {
6637 *ptr++ = vec[current_index + sizeof(T) - i];
6638 }
6639 return result;
6640 }
6641
6642 /*!
6643 @brief create a MessagePack serialization of a given JSON value
6644
6645 This is a straightforward implementation of the MessagePack specification.
6646
6647 @param[in] j JSON value to serialize
6648 @param[in,out] v byte vector to write the serialization to
6649
6650 @sa https://github.com/msgpack/msgpack/blob/master/spec.md
6651 */
6652 static void to_msgpack_internal(const basic_json& j, std::vector<uint8_t>& v)
6653 {
6654 switch (j.type())
6655 {
6656 case value_t::null:
6657 {
6658 // nil
6659 v.push_back(0xc0);
6660 break;
6661 }
6662
6663 case value_t::boolean:
6664 {
6665 // true and false
6666 v.push_back(j.m_value.boolean ? 0xc3 : 0xc2);
6667 break;
6668 }
6669
6671 {
6672 if (j.m_value.number_integer >= 0)
6673 {
6674 // MessagePack does not differentiate between positive
6675 // signed integers and unsigned integers. Therefore, we
6676 // used the code from the value_t::number_unsigned case
6677 // here.
6678 if (j.m_value.number_unsigned < 128)
6679 {
6680 // positive fixnum
6682 }
6683 else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
6684 {
6685 // uint 8
6686 v.push_back(0xcc);
6688 }
6689 else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
6690 {
6691 // uint 16
6692 v.push_back(0xcd);
6694 }
6695 else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
6696 {
6697 // uint 32
6698 v.push_back(0xce);
6700 }
6701 else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
6702 {
6703 // uint 64
6704 v.push_back(0xcf);
6706 }
6707 }
6708 else
6709 {
6710 if (j.m_value.number_integer >= -32)
6711 {
6712 // negative fixnum
6714 }
6715 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())
6716 {
6717 // int 8
6718 v.push_back(0xd0);
6720 }
6721 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())
6722 {
6723 // int 16
6724 v.push_back(0xd1);
6726 }
6727 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())
6728 {
6729 // int 32
6730 v.push_back(0xd2);
6732 }
6733 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())
6734 {
6735 // int 64
6736 v.push_back(0xd3);
6738 }
6739 }
6740 break;
6741 }
6742
6744 {
6745 if (j.m_value.number_unsigned < 128)
6746 {
6747 // positive fixnum
6749 }
6750 else if (j.m_value.number_unsigned <= std::numeric_limits<uint8_t>::max())
6751 {
6752 // uint 8
6753 v.push_back(0xcc);
6755 }
6756 else if (j.m_value.number_unsigned <= std::numeric_limits<uint16_t>::max())
6757 {
6758 // uint 16
6759 v.push_back(0xcd);
6761 }
6762 else if (j.m_value.number_unsigned <= std::numeric_limits<uint32_t>::max())
6763 {
6764 // uint 32
6765 v.push_back(0xce);
6767 }
6768 else if (j.m_value.number_unsigned <= std::numeric_limits<uint64_t>::max())
6769 {
6770 // uint 64
6771 v.push_back(0xcf);
6773 }
6774 break;
6775 }
6776
6778 {
6779 // float 64
6780 v.push_back(0xcb);
6781 const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
6782 for (size_t i = 0; i < 8; ++i)
6783 {
6784 v.push_back(helper[7 - i]);
6785 }
6786 break;
6787 }
6788
6789 case value_t::string:
6790 {
6791 const auto N = j.m_value.string->size();
6792 if (N <= 31)
6793 {
6794 // fixstr
6795 v.push_back(static_cast<uint8_t>(0xa0 | N));
6796 }
6797 else if (N <= 255)
6798 {
6799 // str 8
6800 v.push_back(0xd9);
6801 add_to_vector(v, 1, N);
6802 }
6803 else if (N <= 65535)
6804 {
6805 // str 16
6806 v.push_back(0xda);
6807 add_to_vector(v, 2, N);
6808 }
6809 else if (N <= 4294967295)
6810 {
6811 // str 32
6812 v.push_back(0xdb);
6813 add_to_vector(v, 4, N);
6814 }
6815
6816 // append string
6817 std::copy(j.m_value.string->begin(), j.m_value.string->end(),
6818 std::back_inserter(v));
6819 break;
6820 }
6821
6822 case value_t::array:
6823 {
6824 const auto N = j.m_value.array->size();
6825 if (N <= 15)
6826 {
6827 // fixarray
6828 v.push_back(static_cast<uint8_t>(0x90 | N));
6829 }
6830 else if (N <= 0xffff)
6831 {
6832 // array 16
6833 v.push_back(0xdc);
6834 add_to_vector(v, 2, N);
6835 }
6836 else if (N <= 0xffffffff)
6837 {
6838 // array 32
6839 v.push_back(0xdd);
6840 add_to_vector(v, 4, N);
6841 }
6842
6843 // append each element
6844 for (const auto& el : *j.m_value.array)
6845 {
6847 }
6848 break;
6849 }
6850
6851 case value_t::object:
6852 {
6853 const auto N = j.m_value.object->size();
6854 if (N <= 15)
6855 {
6856 // fixmap
6857 v.push_back(static_cast<uint8_t>(0x80 | (N & 0xf)));
6858 }
6859 else if (N <= 65535)
6860 {
6861 // map 16
6862 v.push_back(0xde);
6863 add_to_vector(v, 2, N);
6864 }
6865 else if (N <= 4294967295)
6866 {
6867 // map 32
6868 v.push_back(0xdf);
6869 add_to_vector(v, 4, N);
6870 }
6871
6872 // append each element
6873 for (const auto& el : *j.m_value.object)
6874 {
6875 to_msgpack_internal(el.first, v);
6876 to_msgpack_internal(el.second, v);
6877 }
6878 break;
6879 }
6880
6881 default:
6882 {
6883 break;
6884 }
6885 }
6886 }
6887
6888 /*!
6889 @brief create a CBOR serialization of a given JSON value
6890
6891 This is a straightforward implementation of the CBOR specification.
6892
6893 @param[in] j JSON value to serialize
6894 @param[in,out] v byte vector to write the serialization to
6895
6896 @sa https://tools.ietf.org/html/rfc7049
6897 */
6898 static void to_cbor_internal(const basic_json& j, std::vector<uint8_t>& v)
6899 {
6900 switch (j.type())
6901 {
6902 case value_t::null:
6903 {
6904 v.push_back(0xf6);
6905 break;
6906 }
6907
6908 case value_t::boolean:
6909 {
6910 v.push_back(j.m_value.boolean ? 0xf5 : 0xf4);
6911 break;
6912 }
6913
6915 {
6916 if (j.m_value.number_integer >= 0)
6917 {
6918 // CBOR does not differentiate between positive signed
6919 // integers and unsigned integers. Therefore, we used the
6920 // code from the value_t::number_unsigned case here.
6921 if (j.m_value.number_integer <= 0x17)
6922 {
6924 }
6925 else if (j.m_value.number_integer <= std::numeric_limits<uint8_t>::max())
6926 {
6927 v.push_back(0x18);
6928 // one-byte uint8_t
6930 }
6931 else if (j.m_value.number_integer <= std::numeric_limits<uint16_t>::max())
6932 {
6933 v.push_back(0x19);
6934 // two-byte uint16_t
6936 }
6937 else if (j.m_value.number_integer <= std::numeric_limits<uint32_t>::max())
6938 {
6939 v.push_back(0x1a);
6940 // four-byte uint32_t
6942 }
6943 else
6944 {
6945 v.push_back(0x1b);
6946 // eight-byte uint64_t
6948 }
6949 }
6950 else
6951 {
6952 // The conversions below encode the sign in the first
6953 // byte, and the value is converted to a positive number.
6954 const auto positive_number = -1 - j.m_value.number_integer;
6955 if (j.m_value.number_integer >= -24)
6956 {
6957 v.push_back(static_cast<uint8_t>(0x20 + positive_number));
6958 }
6959 else if (positive_number <= std::numeric_limits<uint8_t>::max())
6960 {
6961 // int 8
6962 v.push_back(0x38);
6963 add_to_vector(v, 1, positive_number);
6964 }
6965 else if (positive_number <= std::numeric_limits<uint16_t>::max())
6966 {
6967 // int 16
6968 v.push_back(0x39);
6969 add_to_vector(v, 2, positive_number);
6970 }
6971 else if (positive_number <= std::numeric_limits<uint32_t>::max())
6972 {
6973 // int 32
6974 v.push_back(0x3a);
6975 add_to_vector(v, 4, positive_number);
6976 }
6977 else
6978 {
6979 // int 64
6980 v.push_back(0x3b);
6981 add_to_vector(v, 8, positive_number);
6982 }
6983 }
6984 break;
6985 }
6986
6988 {
6989 if (j.m_value.number_unsigned <= 0x17)
6990 {
6991 v.push_back(static_cast<uint8_t>(j.m_value.number_unsigned));
6992 }
6993 else if (j.m_value.number_unsigned <= 0xff)
6994 {
6995 v.push_back(0x18);
6996 // one-byte uint8_t
6998 }
6999 else if (j.m_value.number_unsigned <= 0xffff)
7000 {
7001 v.push_back(0x19);
7002 // two-byte uint16_t
7004 }
7005 else if (j.m_value.number_unsigned <= 0xffffffff)
7006 {
7007 v.push_back(0x1a);
7008 // four-byte uint32_t
7010 }
7011 else if (j.m_value.number_unsigned <= 0xffffffffffffffff)
7012 {
7013 v.push_back(0x1b);
7014 // eight-byte uint64_t
7016 }
7017 break;
7018 }
7019
7021 {
7022 // Double-Precision Float
7023 v.push_back(0xfb);
7024 const auto* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
7025 for (size_t i = 0; i < 8; ++i)
7026 {
7027 v.push_back(helper[7 - i]);
7028 }
7029 break;
7030 }
7031
7032 case value_t::string:
7033 {
7034 const auto N = j.m_value.string->size();
7035 if (N <= 0x17)
7036 {
7037 v.push_back(0x60 + static_cast<uint8_t>(N)); // 1 byte for string + size
7038 }
7039 else if (N <= 0xff)
7040 {
7041 v.push_back(0x78); // one-byte uint8_t for N
7042 add_to_vector(v, 1, N);
7043 }
7044 else if (N <= 0xffff)
7045 {
7046 v.push_back(0x79); // two-byte uint16_t for N
7047 add_to_vector(v, 2, N);
7048 }
7049 else if (N <= 0xffffffff)
7050 {
7051 v.push_back(0x7a); // four-byte uint32_t for N
7052 add_to_vector(v, 4, N);
7053 }
7054 // LCOV_EXCL_START
7055 else if (N <= 0xffffffffffffffff)
7056 {
7057 v.push_back(0x7b); // eight-byte uint64_t for N
7058 add_to_vector(v, 8, N);
7059 }
7060 // LCOV_EXCL_STOP
7061
7062 // append string
7063 std::copy(j.m_value.string->begin(), j.m_value.string->end(),
7064 std::back_inserter(v));
7065 break;
7066 }
7067
7068 case value_t::array:
7069 {
7070 const auto N = j.m_value.array->size();
7071 if (N <= 0x17)
7072 {
7073 v.push_back(0x80 + static_cast<uint8_t>(N)); // 1 byte for array + size
7074 }
7075 else if (N <= 0xff)
7076 {
7077 v.push_back(0x98); // one-byte uint8_t for N
7078 add_to_vector(v, 1, N);
7079 }
7080 else if (N <= 0xffff)
7081 {
7082 v.push_back(0x99); // two-byte uint16_t for N
7083 add_to_vector(v, 2, N);
7084 }
7085 else if (N <= 0xffffffff)
7086 {
7087 v.push_back(0x9a); // four-byte uint32_t for N
7088 add_to_vector(v, 4, N);
7089 }
7090 // LCOV_EXCL_START
7091 else if (N <= 0xffffffffffffffff)
7092 {
7093 v.push_back(0x9b); // eight-byte uint64_t for N
7094 add_to_vector(v, 8, N);
7095 }
7096 // LCOV_EXCL_STOP
7097
7098 // append each element
7099 for (const auto& el : *j.m_value.array)
7100 {
7101 to_cbor_internal(el, v);
7102 }
7103 break;
7104 }
7105
7106 case value_t::object:
7107 {
7108 const auto N = j.m_value.object->size();
7109 if (N <= 0x17)
7110 {
7111 v.push_back(0xa0 + static_cast<uint8_t>(N)); // 1 byte for object + size
7112 }
7113 else if (N <= 0xff)
7114 {
7115 v.push_back(0xb8);
7116 add_to_vector(v, 1, N); // one-byte uint8_t for N
7117 }
7118 else if (N <= 0xffff)
7119 {
7120 v.push_back(0xb9);
7121 add_to_vector(v, 2, N); // two-byte uint16_t for N
7122 }
7123 else if (N <= 0xffffffff)
7124 {
7125 v.push_back(0xba);
7126 add_to_vector(v, 4, N); // four-byte uint32_t for N
7127 }
7128 // LCOV_EXCL_START
7129 else if (N <= 0xffffffffffffffff)
7130 {
7131 v.push_back(0xbb);
7132 add_to_vector(v, 8, N); // eight-byte uint64_t for N
7133 }
7134 // LCOV_EXCL_STOP
7135
7136 // append each element
7137 for (const auto& el : *j.m_value.object)
7138 {
7139 to_cbor_internal(el.first, v);
7140 to_cbor_internal(el.second, v);
7141 }
7142 break;
7143 }
7144
7145 default:
7146 {
7147 break;
7148 }
7149 }
7150 }
7151
7152
7153 /*
7154 @brief checks if given lengths do not exceed the size of a given vector
7155
7156 To secure the access to the byte vector during CBOR/MessagePack
7157 deserialization, bytes are copied from the vector into buffers. This
7158 function checks if the number of bytes to copy (@a len) does not exceed
7159 the size @s size of the vector. Additionally, an @a offset is given from
7160 where to start reading the bytes.
7161
7162 This function checks whether reading the bytes is safe; that is, offset is
7163 a valid index in the vector, offset+len
7164
7165 @param[in] size size of the byte vector
7166 @param[in] len number of bytes to read
7167 @param[in] offset offset where to start reading
7168
7169 vec: x x x x x X X X X X
7170 ^ ^ ^
7171 0 offset len
7172
7173 @throws out_of_range if `len > v.size()`
7174 */
7175 static void check_length(const size_t size, const size_t len, const size_t offset)
7176 {
7177 // simple case: requested length is greater than the vector's length
7178 if (len > size or offset > size)
7179 {
7180 JSON_THROW(std::out_of_range("len out of range"));
7181 }
7182
7183 // second case: adding offset would result in overflow
7184 if ((size > (std::numeric_limits<size_t>::max() - offset)))
7185 {
7186 JSON_THROW(std::out_of_range("len+offset out of range"));
7187 }
7188
7189 // last case: reading past the end of the vector
7190 if (len + offset > size)
7191 {
7192 JSON_THROW(std::out_of_range("len+offset out of range"));
7193 }
7194 }
7195
7196 /*!
7197 @brief create a JSON value from a given MessagePack vector
7198
7199 @param[in] v MessagePack serialization
7200 @param[in] idx byte index to start reading from @a v
7201
7202 @return deserialized JSON value
7203
7204 @throw std::invalid_argument if unsupported features from MessagePack were
7205 used in the given vector @a v or if the input is not valid MessagePack
7206 @throw std::out_of_range if the given vector ends prematurely
7207
7208 @sa https://github.com/msgpack/msgpack/blob/master/spec.md
7209 */
7210 static basic_json from_msgpack_internal(const std::vector<uint8_t>& v, size_t& idx)
7211 {
7212 // make sure reading 1 byte is safe
7213 check_length(v.size(), 1, idx);
7214
7215 // store and increment index
7216 const size_t current_idx = idx++;
7217
7218 if (v[current_idx] <= 0xbf)
7219 {
7220 if (v[current_idx] <= 0x7f) // positive fixint
7221 {
7222 return v[current_idx];
7223 }
7224 if (v[current_idx] <= 0x8f) // fixmap
7225 {
7226 basic_json result = value_t::object;
7227 const size_t len = v[current_idx] & 0x0f;
7228 for (size_t i = 0; i < len; ++i)
7229 {
7230 std::string key = from_msgpack_internal(v, idx);
7231 result[key] = from_msgpack_internal(v, idx);
7232 }
7233 return result;
7234 }
7235 else if (v[current_idx] <= 0x9f) // fixarray
7236 {
7237 basic_json result = value_t::array;
7238 const size_t len = v[current_idx] & 0x0f;
7239 for (size_t i = 0; i < len; ++i)
7240 {
7241 result.push_back(from_msgpack_internal(v, idx));
7242 }
7243 return result;
7244 }
7245 else // fixstr
7246 {
7247 const size_t len = v[current_idx] & 0x1f;
7248 const size_t offset = current_idx + 1;
7249 idx += len; // skip content bytes
7250 check_length(v.size(), len, offset);
7251 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7252 }
7253 }
7254 else if (v[current_idx] >= 0xe0) // negative fixint
7255 {
7256 return static_cast<int8_t>(v[current_idx]);
7257 }
7258 else
7259 {
7260 switch (v[current_idx])
7261 {
7262 case 0xc0: // nil
7263 {
7264 return value_t::null;
7265 }
7266
7267 case 0xc2: // false
7268 {
7269 return false;
7270 }
7271
7272 case 0xc3: // true
7273 {
7274 return true;
7275 }
7276
7277 case 0xca: // float 32
7278 {
7279 // copy bytes in reverse order into the double variable
7280 float res;
7281 for (size_t byte = 0; byte < sizeof(float); ++byte)
7282 {
7283 reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
7284 }
7285 idx += sizeof(float); // skip content bytes
7286 return res;
7287 }
7288
7289 case 0xcb: // float 64
7290 {
7291 // copy bytes in reverse order into the double variable
7292 double res;
7293 for (size_t byte = 0; byte < sizeof(double); ++byte)
7294 {
7295 reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
7296 }
7297 idx += sizeof(double); // skip content bytes
7298 return res;
7299 }
7300
7301 case 0xcc: // uint 8
7302 {
7303 idx += 1; // skip content byte
7304 return get_from_vector<uint8_t>(v, current_idx);
7305 }
7306
7307 case 0xcd: // uint 16
7308 {
7309 idx += 2; // skip 2 content bytes
7310 return get_from_vector<uint16_t>(v, current_idx);
7311 }
7312
7313 case 0xce: // uint 32
7314 {
7315 idx += 4; // skip 4 content bytes
7316 return get_from_vector<uint32_t>(v, current_idx);
7317 }
7318
7319 case 0xcf: // uint 64
7320 {
7321 idx += 8; // skip 8 content bytes
7322 return get_from_vector<uint64_t>(v, current_idx);
7323 }
7324
7325 case 0xd0: // int 8
7326 {
7327 idx += 1; // skip content byte
7328 return get_from_vector<int8_t>(v, current_idx);
7329 }
7330
7331 case 0xd1: // int 16
7332 {
7333 idx += 2; // skip 2 content bytes
7334 return get_from_vector<int16_t>(v, current_idx);
7335 }
7336
7337 case 0xd2: // int 32
7338 {
7339 idx += 4; // skip 4 content bytes
7340 return get_from_vector<int32_t>(v, current_idx);
7341 }
7342
7343 case 0xd3: // int 64
7344 {
7345 idx += 8; // skip 8 content bytes
7346 return get_from_vector<int64_t>(v, current_idx);
7347 }
7348
7349 case 0xd9: // str 8
7350 {
7351 const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
7352 const size_t offset = current_idx + 2;
7353 idx += len + 1; // skip size byte + content bytes
7354 check_length(v.size(), len, offset);
7355 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7356 }
7357
7358 case 0xda: // str 16
7359 {
7360 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7361 const size_t offset = current_idx + 3;
7362 idx += len + 2; // skip 2 size bytes + content bytes
7363 check_length(v.size(), len, offset);
7364 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7365 }
7366
7367 case 0xdb: // str 32
7368 {
7369 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7370 const size_t offset = current_idx + 5;
7371 idx += len + 4; // skip 4 size bytes + content bytes
7372 check_length(v.size(), len, offset);
7373 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7374 }
7375
7376 case 0xdc: // array 16
7377 {
7378 basic_json result = value_t::array;
7379 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7380 idx += 2; // skip 2 size bytes
7381 for (size_t i = 0; i < len; ++i)
7382 {
7383 result.push_back(from_msgpack_internal(v, idx));
7384 }
7385 return result;
7386 }
7387
7388 case 0xdd: // array 32
7389 {
7390 basic_json result = value_t::array;
7391 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7392 idx += 4; // skip 4 size bytes
7393 for (size_t i = 0; i < len; ++i)
7394 {
7395 result.push_back(from_msgpack_internal(v, idx));
7396 }
7397 return result;
7398 }
7399
7400 case 0xde: // map 16
7401 {
7402 basic_json result = value_t::object;
7403 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7404 idx += 2; // skip 2 size bytes
7405 for (size_t i = 0; i < len; ++i)
7406 {
7407 std::string key = from_msgpack_internal(v, idx);
7408 result[key] = from_msgpack_internal(v, idx);
7409 }
7410 return result;
7411 }
7412
7413 case 0xdf: // map 32
7414 {
7415 basic_json result = value_t::object;
7416 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7417 idx += 4; // skip 4 size bytes
7418 for (size_t i = 0; i < len; ++i)
7419 {
7420 std::string key = from_msgpack_internal(v, idx);
7421 result[key] = from_msgpack_internal(v, idx);
7422 }
7423 return result;
7424 }
7425
7426 default:
7427 {
7428 JSON_THROW(std::invalid_argument("error parsing a msgpack @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
7429 }
7430 }
7431 }
7432 }
7433
7434 /*!
7435 @brief create a JSON value from a given CBOR vector
7436
7437 @param[in] v CBOR serialization
7438 @param[in] idx byte index to start reading from @a v
7439
7440 @return deserialized JSON value
7441
7442 @throw std::invalid_argument if unsupported features from CBOR were used in
7443 the given vector @a v or if the input is not valid CBOR
7444 @throw std::out_of_range if the given vector ends prematurely
7445
7446 @sa https://tools.ietf.org/html/rfc7049
7447 */
7448 static basic_json from_cbor_internal(const std::vector<uint8_t>& v, size_t& idx)
7449 {
7450 // store and increment index
7451 const size_t current_idx = idx++;
7452
7453 switch (v.at(current_idx))
7454 {
7455 // Integer 0x00..0x17 (0..23)
7456 case 0x00:
7457 case 0x01:
7458 case 0x02:
7459 case 0x03:
7460 case 0x04:
7461 case 0x05:
7462 case 0x06:
7463 case 0x07:
7464 case 0x08:
7465 case 0x09:
7466 case 0x0a:
7467 case 0x0b:
7468 case 0x0c:
7469 case 0x0d:
7470 case 0x0e:
7471 case 0x0f:
7472 case 0x10:
7473 case 0x11:
7474 case 0x12:
7475 case 0x13:
7476 case 0x14:
7477 case 0x15:
7478 case 0x16:
7479 case 0x17:
7480 {
7481 return v[current_idx];
7482 }
7483
7484 case 0x18: // Unsigned integer (one-byte uint8_t follows)
7485 {
7486 idx += 1; // skip content byte
7487 return get_from_vector<uint8_t>(v, current_idx);
7488 }
7489
7490 case 0x19: // Unsigned integer (two-byte uint16_t follows)
7491 {
7492 idx += 2; // skip 2 content bytes
7493 return get_from_vector<uint16_t>(v, current_idx);
7494 }
7495
7496 case 0x1a: // Unsigned integer (four-byte uint32_t follows)
7497 {
7498 idx += 4; // skip 4 content bytes
7499 return get_from_vector<uint32_t>(v, current_idx);
7500 }
7501
7502 case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
7503 {
7504 idx += 8; // skip 8 content bytes
7505 return get_from_vector<uint64_t>(v, current_idx);
7506 }
7507
7508 // Negative integer -1-0x00..-1-0x17 (-1..-24)
7509 case 0x20:
7510 case 0x21:
7511 case 0x22:
7512 case 0x23:
7513 case 0x24:
7514 case 0x25:
7515 case 0x26:
7516 case 0x27:
7517 case 0x28:
7518 case 0x29:
7519 case 0x2a:
7520 case 0x2b:
7521 case 0x2c:
7522 case 0x2d:
7523 case 0x2e:
7524 case 0x2f:
7525 case 0x30:
7526 case 0x31:
7527 case 0x32:
7528 case 0x33:
7529 case 0x34:
7530 case 0x35:
7531 case 0x36:
7532 case 0x37:
7533 {
7534 return static_cast<int8_t>(0x20 - 1 - v[current_idx]);
7535 }
7536
7537 case 0x38: // Negative integer (one-byte uint8_t follows)
7538 {
7539 idx += 1; // skip content byte
7540 // must be uint8_t !
7541 return static_cast<number_integer_t>(-1) - get_from_vector<uint8_t>(v, current_idx);
7542 }
7543
7544 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
7545 {
7546 idx += 2; // skip 2 content bytes
7547 return static_cast<number_integer_t>(-1) - get_from_vector<uint16_t>(v, current_idx);
7548 }
7549
7550 case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
7551 {
7552 idx += 4; // skip 4 content bytes
7553 return static_cast<number_integer_t>(-1) - get_from_vector<uint32_t>(v, current_idx);
7554 }
7555
7556 case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
7557 {
7558 idx += 8; // skip 8 content bytes
7559 return static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(get_from_vector<uint64_t>(v, current_idx));
7560 }
7561
7562 // UTF-8 string (0x00..0x17 bytes follow)
7563 case 0x60:
7564 case 0x61:
7565 case 0x62:
7566 case 0x63:
7567 case 0x64:
7568 case 0x65:
7569 case 0x66:
7570 case 0x67:
7571 case 0x68:
7572 case 0x69:
7573 case 0x6a:
7574 case 0x6b:
7575 case 0x6c:
7576 case 0x6d:
7577 case 0x6e:
7578 case 0x6f:
7579 case 0x70:
7580 case 0x71:
7581 case 0x72:
7582 case 0x73:
7583 case 0x74:
7584 case 0x75:
7585 case 0x76:
7586 case 0x77:
7587 {
7588 const auto len = static_cast<size_t>(v[current_idx] - 0x60);
7589 const size_t offset = current_idx + 1;
7590 idx += len; // skip content bytes
7591 check_length(v.size(), len, offset);
7592 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7593 }
7594
7595 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
7596 {
7597 const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
7598 const size_t offset = current_idx + 2;
7599 idx += len + 1; // skip size byte + content bytes
7600 check_length(v.size(), len, offset);
7601 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7602 }
7603
7604 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
7605 {
7606 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7607 const size_t offset = current_idx + 3;
7608 idx += len + 2; // skip 2 size bytes + content bytes
7609 check_length(v.size(), len, offset);
7610 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7611 }
7612
7613 case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
7614 {
7615 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7616 const size_t offset = current_idx + 5;
7617 idx += len + 4; // skip 4 size bytes + content bytes
7618 check_length(v.size(), len, offset);
7619 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7620 }
7621
7622 case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
7623 {
7624 const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
7625 const size_t offset = current_idx + 9;
7626 idx += len + 8; // skip 8 size bytes + content bytes
7627 check_length(v.size(), len, offset);
7628 return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
7629 }
7630
7631 case 0x7f: // UTF-8 string (indefinite length)
7632 {
7633 std::string result;
7634 while (v.at(idx) != 0xff)
7635 {
7637 result += s;
7638 }
7639 // skip break byte (0xFF)
7640 idx += 1;
7641 return result;
7642 }
7643
7644 // array (0x00..0x17 data items follow)
7645 case 0x80:
7646 case 0x81:
7647 case 0x82:
7648 case 0x83:
7649 case 0x84:
7650 case 0x85:
7651 case 0x86:
7652 case 0x87:
7653 case 0x88:
7654 case 0x89:
7655 case 0x8a:
7656 case 0x8b:
7657 case 0x8c:
7658 case 0x8d:
7659 case 0x8e:
7660 case 0x8f:
7661 case 0x90:
7662 case 0x91:
7663 case 0x92:
7664 case 0x93:
7665 case 0x94:
7666 case 0x95:
7667 case 0x96:
7668 case 0x97:
7669 {
7670 basic_json result = value_t::array;
7671 const auto len = static_cast<size_t>(v[current_idx] - 0x80);
7672 for (size_t i = 0; i < len; ++i)
7673 {
7674 result.push_back(from_cbor_internal(v, idx));
7675 }
7676 return result;
7677 }
7678
7679 case 0x98: // array (one-byte uint8_t for n follows)
7680 {
7681 basic_json result = value_t::array;
7682 const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
7683 idx += 1; // skip 1 size byte
7684 for (size_t i = 0; i < len; ++i)
7685 {
7686 result.push_back(from_cbor_internal(v, idx));
7687 }
7688 return result;
7689 }
7690
7691 case 0x99: // array (two-byte uint16_t for n follow)
7692 {
7693 basic_json result = value_t::array;
7694 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7695 idx += 2; // skip 4 size bytes
7696 for (size_t i = 0; i < len; ++i)
7697 {
7698 result.push_back(from_cbor_internal(v, idx));
7699 }
7700 return result;
7701 }
7702
7703 case 0x9a: // array (four-byte uint32_t for n follow)
7704 {
7705 basic_json result = value_t::array;
7706 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7707 idx += 4; // skip 4 size bytes
7708 for (size_t i = 0; i < len; ++i)
7709 {
7710 result.push_back(from_cbor_internal(v, idx));
7711 }
7712 return result;
7713 }
7714
7715 case 0x9b: // array (eight-byte uint64_t for n follow)
7716 {
7717 basic_json result = value_t::array;
7718 const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
7719 idx += 8; // skip 8 size bytes
7720 for (size_t i = 0; i < len; ++i)
7721 {
7722 result.push_back(from_cbor_internal(v, idx));
7723 }
7724 return result;
7725 }
7726
7727 case 0x9f: // array (indefinite length)
7728 {
7729 basic_json result = value_t::array;
7730 while (v.at(idx) != 0xff)
7731 {
7732 result.push_back(from_cbor_internal(v, idx));
7733 }
7734 // skip break byte (0xFF)
7735 idx += 1;
7736 return result;
7737 }
7738
7739 // map (0x00..0x17 pairs of data items follow)
7740 case 0xa0:
7741 case 0xa1:
7742 case 0xa2:
7743 case 0xa3:
7744 case 0xa4:
7745 case 0xa5:
7746 case 0xa6:
7747 case 0xa7:
7748 case 0xa8:
7749 case 0xa9:
7750 case 0xaa:
7751 case 0xab:
7752 case 0xac:
7753 case 0xad:
7754 case 0xae:
7755 case 0xaf:
7756 case 0xb0:
7757 case 0xb1:
7758 case 0xb2:
7759 case 0xb3:
7760 case 0xb4:
7761 case 0xb5:
7762 case 0xb6:
7763 case 0xb7:
7764 {
7765 basic_json result = value_t::object;
7766 const auto len = static_cast<size_t>(v[current_idx] - 0xa0);
7767 for (size_t i = 0; i < len; ++i)
7768 {
7769 std::string key = from_cbor_internal(v, idx);
7770 result[key] = from_cbor_internal(v, idx);
7771 }
7772 return result;
7773 }
7774
7775 case 0xb8: // map (one-byte uint8_t for n follows)
7776 {
7777 basic_json result = value_t::object;
7778 const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
7779 idx += 1; // skip 1 size byte
7780 for (size_t i = 0; i < len; ++i)
7781 {
7782 std::string key = from_cbor_internal(v, idx);
7783 result[key] = from_cbor_internal(v, idx);
7784 }
7785 return result;
7786 }
7787
7788 case 0xb9: // map (two-byte uint16_t for n follow)
7789 {
7790 basic_json result = value_t::object;
7791 const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
7792 idx += 2; // skip 2 size bytes
7793 for (size_t i = 0; i < len; ++i)
7794 {
7795 std::string key = from_cbor_internal(v, idx);
7796 result[key] = from_cbor_internal(v, idx);
7797 }
7798 return result;
7799 }
7800
7801 case 0xba: // map (four-byte uint32_t for n follow)
7802 {
7803 basic_json result = value_t::object;
7804 const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
7805 idx += 4; // skip 4 size bytes
7806 for (size_t i = 0; i < len; ++i)
7807 {
7808 std::string key = from_cbor_internal(v, idx);
7809 result[key] = from_cbor_internal(v, idx);
7810 }
7811 return result;
7812 }
7813
7814 case 0xbb: // map (eight-byte uint64_t for n follow)
7815 {
7816 basic_json result = value_t::object;
7817 const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
7818 idx += 8; // skip 8 size bytes
7819 for (size_t i = 0; i < len; ++i)
7820 {
7821 std::string key = from_cbor_internal(v, idx);
7822 result[key] = from_cbor_internal(v, idx);
7823 }
7824 return result;
7825 }
7826
7827 case 0xbf: // map (indefinite length)
7828 {
7829 basic_json result = value_t::object;
7830 while (v.at(idx) != 0xff)
7831 {
7832 std::string key = from_cbor_internal(v, idx);
7833 result[key] = from_cbor_internal(v, idx);
7834 }
7835 // skip break byte (0xFF)
7836 idx += 1;
7837 return result;
7838 }
7839
7840 case 0xf4: // false
7841 {
7842 return false;
7843 }
7844
7845 case 0xf5: // true
7846 {
7847 return true;
7848 }
7849
7850 case 0xf6: // null
7851 {
7852 return value_t::null;
7853 }
7854
7855 case 0xf9: // Half-Precision Float (two-byte IEEE 754)
7856 {
7857 idx += 2; // skip two content bytes
7858
7859 // code from RFC 7049, Appendix D, Figure 3:
7860 // As half-precision floating-point numbers were only added to
7861 // IEEE 754 in 2008, today's programming platforms often still
7862 // only have limited support for them. It is very easy to
7863 // include at least decoding support for them even without such
7864 // support. An example of a small decoder for half-precision
7865 // floating-point numbers in the C language is shown in Fig. 3.
7866 const int half = (v.at(current_idx + 1) << 8) + v.at(current_idx + 2);
7867 const int exp = (half >> 10) & 0x1f;
7868 const int mant = half & 0x3ff;
7869 double val;
7870 if (exp == 0)
7871 {
7872 val = std::ldexp(mant, -24);
7873 }
7874 else if (exp != 31)
7875 {
7876 val = std::ldexp(mant + 1024, exp - 25);
7877 }
7878 else
7879 {
7880 val = mant == 0
7881 ? std::numeric_limits<double>::infinity()
7882 : std::numeric_limits<double>::quiet_NaN();
7883 }
7884 return (half & 0x8000) != 0 ? -val : val;
7885 }
7886
7887 case 0xfa: // Single-Precision Float (four-byte IEEE 754)
7888 {
7889 // copy bytes in reverse order into the float variable
7890 float res;
7891 for (size_t byte = 0; byte < sizeof(float); ++byte)
7892 {
7893 reinterpret_cast<uint8_t*>(&res)[sizeof(float) - byte - 1] = v.at(current_idx + 1 + byte);
7894 }
7895 idx += sizeof(float); // skip content bytes
7896 return res;
7897 }
7898
7899 case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
7900 {
7901 // copy bytes in reverse order into the double variable
7902 double res;
7903 for (size_t byte = 0; byte < sizeof(double); ++byte)
7904 {
7905 reinterpret_cast<uint8_t*>(&res)[sizeof(double) - byte - 1] = v.at(current_idx + 1 + byte);
7906 }
7907 idx += sizeof(double); // skip content bytes
7908 return res;
7909 }
7910
7911 default: // anything else (0xFF is handled inside the other types)
7912 {
7913 JSON_THROW(std::invalid_argument("error parsing a CBOR @ " + std::to_string(current_idx) + ": " + std::to_string(static_cast<int>(v[current_idx]))));
7914 }
7915 }
7916 }
7917
7918 public:
7919 /*!
7920 @brief create a MessagePack serialization of a given JSON value
7921
7922 Serializes a given JSON value @a j to a byte vector using the MessagePack
7923 serialization format. MessagePack is a binary serialization format which
7924 aims to be more compact than JSON itself, yet more efficient to parse.
7925
7926 @param[in] j JSON value to serialize
7927 @return MessagePack serialization as byte vector
7928
7929 @complexity Linear in the size of the JSON value @a j.
7930
7931 @liveexample{The example shows the serialization of a JSON value to a byte
7932 vector in MessagePack format.,to_msgpack}
7933
7934 @sa http://msgpack.org
7935 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
7936 analogous deserialization
7937 @sa @ref to_cbor(const basic_json& for the related CBOR format
7938
7939 @since version 2.0.9
7940 */
7941 static std::vector<uint8_t> to_msgpack(const basic_json& j)
7942 {
7943 std::vector<uint8_t> result;
7944 to_msgpack_internal(j, result);
7945 return result;
7946 }
7947
7948 /*!
7949 @brief create a JSON value from a byte vector in MessagePack format
7950
7951 Deserializes a given byte vector @a v to a JSON value using the MessagePack
7952 serialization format.
7953
7954 @param[in] v a byte vector in MessagePack format
7955 @param[in] start_index the index to start reading from @a v (0 by default)
7956 @return deserialized JSON value
7957
7958 @throw std::invalid_argument if unsupported features from MessagePack were
7959 used in the given vector @a v or if the input is not valid MessagePack
7960 @throw std::out_of_range if the given vector ends prematurely
7961
7962 @complexity Linear in the size of the byte vector @a v.
7963
7964 @liveexample{The example shows the deserialization of a byte vector in
7965 MessagePack format to a JSON value.,from_msgpack}
7966
7967 @sa http://msgpack.org
7968 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
7969 @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
7970 related CBOR format
7971
7972 @since version 2.0.9, parameter @a start_index since 2.1.1
7973 */
7974 static basic_json from_msgpack(const std::vector<uint8_t>& v,
7975 const size_t start_index = 0)
7976 {
7977 size_t i = start_index;
7978 return from_msgpack_internal(v, i);
7979 }
7980
7981 /*!
7982 @brief create a MessagePack serialization of a given JSON value
7983
7984 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
7985 Binary Object Representation) serialization format. CBOR is a binary
7986 serialization format which aims to be more compact than JSON itself, yet
7987 more efficient to parse.
7988
7989 @param[in] j JSON value to serialize
7990 @return MessagePack serialization as byte vector
7991
7992 @complexity Linear in the size of the JSON value @a j.
7993
7994 @liveexample{The example shows the serialization of a JSON value to a byte
7995 vector in CBOR format.,to_cbor}
7996
7997 @sa http://cbor.io
7998 @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
7999 analogous deserialization
8000 @sa @ref to_msgpack(const basic_json& for the related MessagePack format
8001
8002 @since version 2.0.9
8003 */
8004 static std::vector<uint8_t> to_cbor(const basic_json& j)
8005 {
8006 std::vector<uint8_t> result;
8007 to_cbor_internal(j, result);
8008 return result;
8009 }
8010
8011 /*!
8012 @brief create a JSON value from a byte vector in CBOR format
8013
8014 Deserializes a given byte vector @a v to a JSON value using the CBOR
8015 (Concise Binary Object Representation) serialization format.
8016
8017 @param[in] v a byte vector in CBOR format
8018 @param[in] start_index the index to start reading from @a v (0 by default)
8019 @return deserialized JSON value
8020
8021 @throw std::invalid_argument if unsupported features from CBOR were used in
8022 the given vector @a v or if the input is not valid MessagePack
8023 @throw std::out_of_range if the given vector ends prematurely
8024
8025 @complexity Linear in the size of the byte vector @a v.
8026
8027 @liveexample{The example shows the deserialization of a byte vector in CBOR
8028 format to a JSON value.,from_cbor}
8029
8030 @sa http://cbor.io
8031 @sa @ref to_cbor(const basic_json&) for the analogous serialization
8032 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
8033 related MessagePack format
8034
8035 @since version 2.0.9, parameter @a start_index since 2.1.1
8036 */
8037 static basic_json from_cbor(const std::vector<uint8_t>& v,
8038 const size_t start_index = 0)
8039 {
8040 size_t i = start_index;
8041 return from_cbor_internal(v, i);
8042 }
8043
8044 /// @}
8045
8046 ///////////////////////////
8047 // convenience functions //
8048 ///////////////////////////
8049
8050 /*!
8051 @brief return the type as string
8052
8053 Returns the type name as string to be used in error messages - usually to
8054 indicate that a function was called on a wrong JSON type.
8055
8056 @return basically a string representation of a the @a m_type member
8057
8058 @complexity Constant.
8059
8060 @liveexample{The following code exemplifies `type_name()` for all JSON
8061 types.,type_name}
8062
8063 @since version 1.0.0, public since 2.1.0
8064 */
8065 std::string type_name() const
8066 {
8067 {
8068 switch (m_type)
8069 {
8070 case value_t::null:
8071 return "null";
8072 case value_t::object:
8073 return "object";
8074 case value_t::array:
8075 return "array";
8076 case value_t::string:
8077 return "string";
8078 case value_t::boolean:
8079 return "boolean";
8080 case value_t::discarded:
8081 return "discarded";
8082 default:
8083 return "number";
8084 }
8085 }
8086 }
8087
8088 private:
8089 /*!
8090 @brief calculates the extra space to escape a JSON string
8091
8092 @param[in] s the string to escape
8093 @return the number of characters required to escape string @a s
8094
8095 @complexity Linear in the length of string @a s.
8096 */
8097 static std::size_t extra_space(const string_t& s) noexcept
8098 {
8099 return std::accumulate(s.begin(), s.end(), size_t{},
8100 [](size_t res, typename string_t::value_type c)
8101 {
8102 switch (c)
8103 {
8104 case '"':
8105 case '\\':
8106 case '\b':
8107 case '\f':
8108 case '\n':
8109 case '\r':
8110 case '\t':
8111 {
8112 // from c (1 byte) to \x (2 bytes)
8113 return res + 1;
8114 }
8115
8116 default:
8117 {
8118 if (c >= 0x00 and c <= 0x1f)
8119 {
8120 // from c (1 byte) to \uxxxx (6 bytes)
8121 return res + 5;
8122 }
8123
8124 return res;
8125 }
8126 }
8127 });
8128 }
8129
8130 /*!
8131 @brief escape a string
8132
8133 Escape a string by replacing certain special characters by a sequence of
8134 an escape character (backslash) and another character and other control
8135 characters by a sequence of "\u" followed by a four-digit hex
8136 representation.
8137
8138 @param[in] s the string to escape
8139 @return the escaped string
8140
8141 @complexity Linear in the length of string @a s.
8142 */
8144 {
8145 const auto space = extra_space(s);
8146 if (space == 0)
8147 {
8148 return s;
8149 }
8150
8151 // create a result string of necessary size
8152 string_t result(s.size() + space, '\\');
8153 std::size_t pos = 0;
8154
8155 for (const auto& c : s)
8156 {
8157 switch (c)
8158 {
8159 // quotation mark (0x22)
8160 case '"':
8161 {
8162 result[pos + 1] = '"';
8163 pos += 2;
8164 break;
8165 }
8166
8167 // reverse solidus (0x5c)
8168 case '\\':
8169 {
8170 // nothing to change
8171 pos += 2;
8172 break;
8173 }
8174
8175 // backspace (0x08)
8176 case '\b':
8177 {
8178 result[pos + 1] = 'b';
8179 pos += 2;
8180 break;
8181 }
8182
8183 // formfeed (0x0c)
8184 case '\f':
8185 {
8186 result[pos + 1] = 'f';
8187 pos += 2;
8188 break;
8189 }
8190
8191 // newline (0x0a)
8192 case '\n':
8193 {
8194 result[pos + 1] = 'n';
8195 pos += 2;
8196 break;
8197 }
8198
8199 // carriage return (0x0d)
8200 case '\r':
8201 {
8202 result[pos + 1] = 'r';
8203 pos += 2;
8204 break;
8205 }
8206
8207 // horizontal tab (0x09)
8208 case '\t':
8209 {
8210 result[pos + 1] = 't';
8211 pos += 2;
8212 break;
8213 }
8214
8215 default:
8216 {
8217 if (c >= 0x00 and c <= 0x1f)
8218 {
8219 // convert a number 0..15 to its hex representation
8220 // (0..f)
8221 static const char hexify[16] =
8222 {
8223 '0', '1', '2', '3', '4', '5', '6', '7',
8224 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
8225 };
8226
8227 // print character c as \uxxxx
8228 for (const char m :
8229 { 'u', '0', '0', hexify[c >> 4], hexify[c & 0x0f]
8230 })
8231 {
8232 result[++pos] = m;
8233 }
8234
8235 ++pos;
8236 }
8237 else
8238 {
8239 // all other characters are added as-is
8240 result[pos++] = c;
8241 }
8242 break;
8243 }
8244 }
8245 }
8246
8247 return result;
8248 }
8249
8250
8251 /*!
8252 @brief locale-independent serialization for built-in arithmetic types
8253 */
8255 {
8256 public:
8257 template<typename NumberType>
8258 numtostr(NumberType value)
8259 {
8260 x_write(value, std::is_integral<NumberType>());
8261 }
8262
8263 const char* c_str() const
8264 {
8265 return m_buf.data();
8266 }
8267
8268 private:
8269 /// a (hopefully) large enough character buffer
8270 std::array < char, 64 > m_buf{{}};
8271
8272 template<typename NumberType>
8273 void x_write(NumberType x, /*is_integral=*/std::true_type)
8274 {
8275 // special case for "0"
8276 if (x == 0)
8277 {
8278 m_buf[0] = '0';
8279 return;
8280 }
8281
8282 const bool is_negative = x < 0;
8283 size_t i = 0;
8284
8285 // spare 1 byte for '\0'
8286 while (x != 0 and i < m_buf.size() - 1)
8287 {
8288 const auto digit = std::labs(static_cast<long>(x % 10));
8289 m_buf[i++] = static_cast<char>('0' + digit);
8290 x /= 10;
8291 }
8292
8293 // make sure the number has been processed completely
8294 assert(x == 0);
8295
8296 if (is_negative)
8297 {
8298 // make sure there is capacity for the '-'
8299 assert(i < m_buf.size() - 2);
8300 m_buf[i++] = '-';
8301 }
8302
8303 std::reverse(m_buf.begin(), m_buf.begin() + i);
8304 }
8305
8306 template<typename NumberType>
8307 void x_write(NumberType x, /*is_integral=*/std::false_type)
8308 {
8309 // special case for 0.0 and -0.0
8310 if (x == 0)
8311 {
8312 size_t i = 0;
8313 if (std::signbit(x))
8314 {
8315 m_buf[i++] = '-';
8316 }
8317 m_buf[i++] = '0';
8318 m_buf[i++] = '.';
8319 m_buf[i] = '0';
8320 return;
8321 }
8322
8323 // get number of digits for a text -> float -> text round-trip
8324 static constexpr auto d = std::numeric_limits<NumberType>::digits10;
8325
8326 // the actual conversion
8327 const auto written_bytes = snprintf(m_buf.data(), m_buf.size(), "%.*g", d, x);
8328
8329 // negative value indicates an error
8330 assert(written_bytes > 0);
8331 // check if buffer was large enough
8332 assert(static_cast<size_t>(written_bytes) < m_buf.size());
8333
8334 // read information from locale
8335 const auto loc = localeconv();
8336 assert(loc != nullptr);
8337 const char thousands_sep = !loc->thousands_sep ? '\0'
8338 : loc->thousands_sep[0];
8339
8340 const char decimal_point = !loc->decimal_point ? '\0'
8341 : loc->decimal_point[0];
8342
8343 // erase thousands separator
8344 if (thousands_sep != '\0')
8345 {
8346 const auto end = std::remove(m_buf.begin(), m_buf.begin() + written_bytes, thousands_sep);
8347 std::fill(end, m_buf.end(), '\0');
8348 }
8349
8350 // convert decimal point to '.'
8351 if (decimal_point != '\0' and decimal_point != '.')
8352 {
8353 for (auto& c : m_buf)
8354 {
8355 if (c == decimal_point)
8356 {
8357 c = '.';
8358 break;
8359 }
8360 }
8361 }
8362
8363 // determine if need to append ".0"
8364 size_t i = 0;
8365 bool value_is_int_like = true;
8366 for (i = 0; i < m_buf.size(); ++i)
8367 {
8368 // break when end of number is reached
8369 if (m_buf[i] == '\0')
8370 {
8371 break;
8372 }
8373
8374 // check if we find non-int character
8375 value_is_int_like = value_is_int_like and m_buf[i] != '.' and
8376 m_buf[i] != 'e' and m_buf[i] != 'E';
8377 }
8378
8379 if (value_is_int_like)
8380 {
8381 // there must be 2 bytes left for ".0"
8382 assert((i + 2) < m_buf.size());
8383 // we write to the end of the number
8384 assert(m_buf[i] == '\0');
8385 assert(m_buf[i - 1] != '\0');
8386
8387 // add ".0"
8388 m_buf[i] = '.';
8389 m_buf[i + 1] = '0';
8390
8391 // the resulting string is properly terminated
8392 assert(m_buf[i + 2] == '\0');
8393 }
8394 }
8395 };
8396
8397
8398 /*!
8399 @brief internal implementation of the serialization function
8400
8401 This function is called by the public member function dump and organizes
8402 the serialization internally. The indentation level is propagated as
8403 additional parameter. In case of arrays and objects, the function is
8404 called recursively. Note that
8405
8406 - strings and object keys are escaped using `escape_string()`
8407 - integer numbers are converted implicitly via `operator<<`
8408 - floating-point numbers are converted to a string using `"%g"` format
8409
8410 @param[out] o stream to write to
8411 @param[in] pretty_print whether the output shall be pretty-printed
8412 @param[in] indent_step the indent level
8413 @param[in] current_indent the current indent level (only used internally)
8414 */
8415 void dump(std::ostream& o,
8416 const bool pretty_print,
8417 const unsigned int indent_step,
8418 const unsigned int current_indent = 0) const
8419 {
8420 // variable to hold indentation for recursive calls
8421 unsigned int new_indent = current_indent;
8422
8423 switch (m_type)
8424 {
8425 case value_t::object:
8426 {
8427 if (m_value.object->empty())
8428 {
8429 o << "{}";
8430 return;
8431 }
8432
8433 o << "{";
8434
8435 // increase indentation
8436 if (pretty_print)
8437 {
8438 new_indent += indent_step;
8439 o << "\n";
8440 }
8441
8442 for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
8443 {
8444 if (i != m_value.object->cbegin())
8445 {
8446 o << (pretty_print ? ",\n" : ",");
8447 }
8448 o << string_t(new_indent, ' ') << "\""
8449 << escape_string(i->first) << "\":"
8450 << (pretty_print ? " " : "");
8451 i->second.dump(o, pretty_print, indent_step, new_indent);
8452 }
8453
8454 // decrease indentation
8455 if (pretty_print)
8456 {
8457 new_indent -= indent_step;
8458 o << "\n";
8459 }
8460
8461 o << string_t(new_indent, ' ') + "}";
8462 return;
8463 }
8464
8465 case value_t::array:
8466 {
8467 if (m_value.array->empty())
8468 {
8469 o << "[]";
8470 return;
8471 }
8472
8473 o << "[";
8474
8475 // increase indentation
8476 if (pretty_print)
8477 {
8478 new_indent += indent_step;
8479 o << "\n";
8480 }
8481
8482 for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
8483 {
8484 if (i != m_value.array->cbegin())
8485 {
8486 o << (pretty_print ? ",\n" : ",");
8487 }
8488 o << string_t(new_indent, ' ');
8489 i->dump(o, pretty_print, indent_step, new_indent);
8490 }
8491
8492 // decrease indentation
8493 if (pretty_print)
8494 {
8495 new_indent -= indent_step;
8496 o << "\n";
8497 }
8498
8499 o << string_t(new_indent, ' ') << "]";
8500 return;
8501 }
8502
8503 case value_t::string:
8504 {
8505 o << string_t("\"") << escape_string(*m_value.string) << "\"";
8506 return;
8507 }
8508
8509 case value_t::boolean:
8510 {
8511 o << (m_value.boolean ? "true" : "false");
8512 return;
8513 }
8514
8515 case value_t::number_integer:
8516 {
8517 o << numtostr(m_value.number_integer).c_str();
8518 return;
8519 }
8520
8521 case value_t::number_unsigned:
8522 {
8523 o << numtostr(m_value.number_unsigned).c_str();
8524 return;
8525 }
8526
8527 case value_t::number_float:
8528 {
8529 o << numtostr(m_value.number_float).c_str();
8530 return;
8531 }
8532
8533 case value_t::discarded:
8534 {
8535 o << "<discarded>";
8536 return;
8537 }
8538
8539 case value_t::null:
8540 {
8541 o << "null";
8542 return;
8543 }
8544 }
8545 }
8546
8547 private:
8548 //////////////////////
8549 // member variables //
8550 //////////////////////
8551
8552 /// the type of the current element
8554
8555 /// the value of the current element
8556 json_value m_value = {};
8557
8558
8559 private:
8560 ///////////////
8561 // iterators //
8562 ///////////////
8563
8564 /*!
8565 @brief an iterator for primitive JSON types
8566
8567 This class models an iterator for primitive JSON types (boolean, number,
8568 string). It's only purpose is to allow the iterator/const_iterator classes
8569 to "iterate" over primitive values. Internally, the iterator is modeled by
8570 a `difference_type` variable. Value begin_value (`0`) models the begin,
8571 end_value (`1`) models past the end.
8572 */
8574 {
8575 public:
8576
8578 {
8579 return m_it;
8580 }
8581 /// set iterator to a defined beginning
8582 void set_begin() noexcept
8583 {
8584 m_it = begin_value;
8585 }
8586
8587 /// set iterator to a defined past the end
8588 void set_end() noexcept
8589 {
8590 m_it = end_value;
8591 }
8592
8593 /// return whether the iterator can be dereferenced
8594 constexpr bool is_begin() const noexcept
8595 {
8596 return (m_it == begin_value);
8597 }
8598
8599 /// return whether the iterator is at end
8600 constexpr bool is_end() const noexcept
8601 {
8602 return (m_it == end_value);
8603 }
8604
8605 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8606 {
8607 return lhs.m_it == rhs.m_it;
8608 }
8609
8610 friend constexpr bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8611 {
8612 return !(lhs == rhs);
8613 }
8614
8615 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8616 {
8617 return lhs.m_it < rhs.m_it;
8618 }
8619
8620 friend constexpr bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8621 {
8622 return lhs.m_it <= rhs.m_it;
8623 }
8624
8625 friend constexpr bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8626 {
8627 return lhs.m_it > rhs.m_it;
8628 }
8629
8630 friend constexpr bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
8631 {
8632 return lhs.m_it >= rhs.m_it;
8633 }
8634
8636 {
8637 auto result = *this;
8638 result += i;
8639 return result;
8640 }
8641
8643 {
8644 return lhs.m_it - rhs.m_it;
8645 }
8646
8647 friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
8648 {
8649 return os << it.m_it;
8650 }
8651
8653 {
8654 ++m_it;
8655 return *this;
8656 }
8657
8659 {
8660 auto result = *this;
8661 m_it++;
8662 return result;
8663 }
8664
8666 {
8667 --m_it;
8668 return *this;
8669 }
8670
8672 {
8673 auto result = *this;
8674 m_it--;
8675 return result;
8676 }
8677
8679 {
8680 m_it += n;
8681 return *this;
8682 }
8683
8685 {
8686 m_it -= n;
8687 return *this;
8688 }
8689
8690 private:
8691 static constexpr difference_type begin_value = 0;
8692 static constexpr difference_type end_value = begin_value + 1;
8693
8694 /// iterator as signed integer type
8695 difference_type m_it = std::numeric_limits<std::ptrdiff_t>::denorm_min();
8696 };
8697
8698 /*!
8699 @brief an iterator value
8700
8701 @note This structure could easily be a union, but MSVC currently does not
8702 allow unions members with complex constructors, see
8703 https://github.com/nlohmann/json/pull/105.
8704 */
8706 {
8707 /// iterator for JSON objects
8708 typename object_t::iterator object_iterator;
8709 /// iterator for JSON arrays
8710 typename array_t::iterator array_iterator;
8711 /// generic iterator for all other types
8713
8714 /// create an uninitialized internal_iterator
8716 : object_iterator(), array_iterator(), primitive_iterator()
8717 {}
8718 };
8719
8720 /// proxy class for the iterator_wrapper functions
8721 template<typename IteratorType>
8723 {
8724 private:
8725 /// helper class for iteration
8727 {
8728 private:
8729 /// the iterator
8730 IteratorType anchor;
8731 /// an index for arrays (used to create key names)
8732 size_t array_index = 0;
8733
8734 public:
8735 explicit iteration_proxy_internal(IteratorType it) noexcept
8736 : anchor(it)
8737 {}
8738
8739 /// dereference operator (needed for range-based for)
8741 {
8742 return *this;
8743 }
8744
8745 /// increment operator (needed for range-based for)
8747 {
8748 ++anchor;
8749 ++array_index;
8750
8751 return *this;
8752 }
8753
8754 /// inequality operator (needed for range-based for)
8756 {
8757 return anchor != o.anchor;
8758 }
8759
8760 /// return key of the iterator
8761 typename basic_json::string_t key() const
8762 {
8763 assert(anchor.m_object != nullptr);
8764
8765 switch (anchor.m_object->type())
8766 {
8767 // use integer array index as key
8768 case value_t::array:
8769 {
8770 return std::to_string(array_index);
8771 }
8772
8773 // use key from the object
8774 case value_t::object:
8775 {
8776 return anchor.key();
8777 }
8778
8779 // use an empty key for all primitive types
8780 default:
8781 {
8782 return "";
8783 }
8784 }
8785 }
8786
8787 /// return value of the iterator
8788 typename IteratorType::reference value() const
8789 {
8790 return anchor.value();
8791 }
8792 };
8793
8794 /// the container to iterate
8795 typename IteratorType::reference container;
8796
8797 public:
8798 /// construct iteration proxy from a container
8799 explicit iteration_proxy(typename IteratorType::reference cont)
8800 : container(cont)
8801 {}
8802
8803 /// return iterator begin (needed for range-based for)
8805 {
8806 return iteration_proxy_internal(container.begin());
8807 }
8808
8809 /// return iterator end (needed for range-based for)
8811 {
8812 return iteration_proxy_internal(container.end());
8813 }
8814 };
8815
8816 public:
8817 /*!
8818 @brief a template for a random access iterator for the @ref basic_json class
8819
8820 This class implements a both iterators (iterator and const_iterator) for the
8821 @ref basic_json class.
8822
8823 @note An iterator is called *initialized* when a pointer to a JSON value
8824 has been set (e.g., by a constructor or a copy assignment). If the
8825 iterator is default-constructed, it is *uninitialized* and most
8826 methods are undefined. **The library uses assertions to detect calls
8827 on uninitialized iterators.**
8828
8829 @requirement The class satisfies the following concept requirements:
8830 - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
8831 The iterator that can be moved to point (forward and backward) to any
8832 element in constant time.
8833
8834 @since version 1.0.0, simplified in version 2.0.9
8835 */
8836 template<typename U>
8837 class iter_impl : public std::iterator<std::random_access_iterator_tag, U>
8838 {
8839 /// allow basic_json to access private members
8840 friend class basic_json;
8841
8842 // make sure U is basic_json or const basic_json
8843 static_assert(std::is_same<U, basic_json>::value
8844 or std::is_same<U, const basic_json>::value,
8845 "iter_impl only accepts (const) basic_json");
8846
8847 public:
8848 /// the type of the values when the iterator is dereferenced
8850 /// a type to represent differences between iterators
8852 /// defines a pointer to the type iterated over (value_type)
8853 using pointer = typename std::conditional<std::is_const<U>::value,
8855 typename basic_json::pointer>::type;
8856 /// defines a reference to the type iterated over (value_type)
8857 using reference = typename std::conditional<std::is_const<U>::value,
8860 /// the category of the iterator
8861 using iterator_category = std::bidirectional_iterator_tag;
8862
8863 /// default constructor
8864 iter_impl() = default;
8865
8866 /*!
8867 @brief constructor for a given JSON instance
8868 @param[in] object pointer to a JSON object for this iterator
8869 @pre object != nullptr
8870 @post The iterator is initialized; i.e. `m_object != nullptr`.
8871 */
8872 explicit iter_impl(pointer object) noexcept
8873 : m_object(object)
8874 {
8875 assert(m_object != nullptr);
8876
8877 switch (m_object->m_type)
8878 {
8880 {
8881 m_it.object_iterator = typename object_t::iterator();
8882 break;
8883 }
8884
8886 {
8887 m_it.array_iterator = typename array_t::iterator();
8888 break;
8889 }
8890
8891 default:
8892 {
8893 m_it.primitive_iterator = primitive_iterator_t();
8894 break;
8895 }
8896 }
8897 }
8898
8899 /*
8900 Use operator `const_iterator` instead of `const_iterator(const iterator&
8901 other) noexcept` to avoid two class definitions for @ref iterator and
8902 @ref const_iterator.
8903
8904 This function is only called if this class is an @ref iterator. If this
8905 class is a @ref const_iterator this function is not called.
8906 */
8907 operator const_iterator() const
8908 {
8909 const_iterator ret;
8910
8911 if (m_object)
8912 {
8913 ret.m_object = m_object;
8914 ret.m_it = m_it;
8915 }
8916
8917 return ret;
8918 }
8919
8920 /*!
8921 @brief copy constructor
8922 @param[in] other iterator to copy from
8923 @note It is not checked whether @a other is initialized.
8924 */
8925 iter_impl(const iter_impl& other) noexcept
8926 : m_object(other.m_object), m_it(other.m_it)
8927 {}
8928
8929 /*!
8930 @brief copy assignment
8931 @param[in,out] other iterator to copy from
8932 @note It is not checked whether @a other is initialized.
8933 */
8935 std::is_nothrow_move_constructible<pointer>::value and
8936 std::is_nothrow_move_assignable<pointer>::value and
8937 std::is_nothrow_move_constructible<internal_iterator>::value and
8938 std::is_nothrow_move_assignable<internal_iterator>::value
8939 )
8940 {
8941 std::swap(m_object, other.m_object);
8942 std::swap(m_it, other.m_it);
8943 return *this;
8944 }
8945
8946 private:
8947 /*!
8948 @brief set the iterator to the first value
8949 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8950 */
8951 void set_begin() noexcept
8952 {
8953 assert(m_object != nullptr);
8954
8955 switch (m_object->m_type)
8956 {
8958 {
8959 m_it.object_iterator = m_object->m_value.object->begin();
8960 break;
8961 }
8962
8964 {
8965 m_it.array_iterator = m_object->m_value.array->begin();
8966 break;
8967 }
8968
8970 {
8971 // set to end so begin()==end() is true: null is empty
8972 m_it.primitive_iterator.set_end();
8973 break;
8974 }
8975
8976 default:
8977 {
8978 m_it.primitive_iterator.set_begin();
8979 break;
8980 }
8981 }
8982 }
8983
8984 /*!
8985 @brief set the iterator past the last value
8986 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8987 */
8988 void set_end() noexcept
8989 {
8990 assert(m_object != nullptr);
8991
8992 switch (m_object->m_type)
8993 {
8995 {
8996 m_it.object_iterator = m_object->m_value.object->end();
8997 break;
8998 }
8999
9001 {
9002 m_it.array_iterator = m_object->m_value.array->end();
9003 break;
9004 }
9005
9006 default:
9007 {
9008 m_it.primitive_iterator.set_end();
9009 break;
9010 }
9011 }
9012 }
9013
9014 public:
9015 /*!
9016 @brief return a reference to the value pointed to by the iterator
9017 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9018 */
9020 {
9021 assert(m_object != nullptr);
9022
9023 switch (m_object->m_type)
9024 {
9026 {
9027 assert(m_it.object_iterator != m_object->m_value.object->end());
9028 return m_it.object_iterator->second;
9029 }
9030
9032 {
9033 assert(m_it.array_iterator != m_object->m_value.array->end());
9034 return *m_it.array_iterator;
9035 }
9036
9038 {
9039 JSON_THROW(std::out_of_range("cannot get value"));
9040 }
9041
9042 default:
9043 {
9044 if (m_it.primitive_iterator.is_begin())
9045 {
9046 return *m_object;
9047 }
9048
9049 JSON_THROW(std::out_of_range("cannot get value"));
9050 }
9051 }
9052 }
9053
9054 /*!
9055 @brief dereference the iterator
9056 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9057 */
9059 {
9060 assert(m_object != nullptr);
9061
9062 switch (m_object->m_type)
9063 {
9065 {
9066 assert(m_it.object_iterator != m_object->m_value.object->end());
9067 return &(m_it.object_iterator->second);
9068 }
9069
9071 {
9072 assert(m_it.array_iterator != m_object->m_value.array->end());
9073 return &*m_it.array_iterator;
9074 }
9075
9076 default:
9077 {
9078 if (m_it.primitive_iterator.is_begin())
9079 {
9080 return m_object;
9081 }
9082
9083 JSON_THROW(std::out_of_range("cannot get value"));
9084 }
9085 }
9086 }
9087
9088 /*!
9089 @brief post-increment (it++)
9090 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9091 */
9093 {
9094 auto result = *this;
9095 ++(*this);
9096 return result;
9097 }
9098
9099 /*!
9100 @brief pre-increment (++it)
9101 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9102 */
9104 {
9105 assert(m_object != nullptr);
9106
9107 switch (m_object->m_type)
9108 {
9110 {
9111 std::advance(m_it.object_iterator, 1);
9112 break;
9113 }
9114
9116 {
9117 std::advance(m_it.array_iterator, 1);
9118 break;
9119 }
9120
9121 default:
9122 {
9123 ++m_it.primitive_iterator;
9124 break;
9125 }
9126 }
9127
9128 return *this;
9129 }
9130
9131 /*!
9132 @brief post-decrement (it--)
9133 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9134 */
9136 {
9137 auto result = *this;
9138 --(*this);
9139 return result;
9140 }
9141
9142 /*!
9143 @brief pre-decrement (--it)
9144 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9145 */
9147 {
9148 assert(m_object != nullptr);
9149
9150 switch (m_object->m_type)
9151 {
9153 {
9154 std::advance(m_it.object_iterator, -1);
9155 break;
9156 }
9157
9159 {
9160 std::advance(m_it.array_iterator, -1);
9161 break;
9162 }
9163
9164 default:
9165 {
9166 --m_it.primitive_iterator;
9167 break;
9168 }
9169 }
9170
9171 return *this;
9172 }
9173
9174 /*!
9175 @brief comparison: equal
9176 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9177 */
9178 bool operator==(const iter_impl& other) const
9179 {
9180 // if objects are not the same, the comparison is undefined
9181 if (m_object != other.m_object)
9182 {
9183 JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
9184 }
9185
9186 assert(m_object != nullptr);
9187
9188 switch (m_object->m_type)
9189 {
9191 {
9192 return (m_it.object_iterator == other.m_it.object_iterator);
9193 }
9194
9196 {
9197 return (m_it.array_iterator == other.m_it.array_iterator);
9198 }
9199
9200 default:
9201 {
9202 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
9203 }
9204 }
9205 }
9206
9207 /*!
9208 @brief comparison: not equal
9209 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9210 */
9211 bool operator!=(const iter_impl& other) const
9212 {
9213 return not operator==(other);
9214 }
9215
9216 /*!
9217 @brief comparison: smaller
9218 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9219 */
9220 bool operator<(const iter_impl& other) const
9221 {
9222 // if objects are not the same, the comparison is undefined
9223 if (m_object != other.m_object)
9224 {
9225 JSON_THROW(std::domain_error("cannot compare iterators of different containers"));
9226 }
9227
9228 assert(m_object != nullptr);
9229
9230 switch (m_object->m_type)
9231 {
9233 {
9234 JSON_THROW(std::domain_error("cannot compare order of object iterators"));
9235 }
9236
9238 {
9239 return (m_it.array_iterator < other.m_it.array_iterator);
9240 }
9241
9242 default:
9243 {
9244 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
9245 }
9246 }
9247 }
9248
9249 /*!
9250 @brief comparison: less than or equal
9251 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9252 */
9253 bool operator<=(const iter_impl& other) const
9254 {
9255 return not other.operator < (*this);
9256 }
9257
9258 /*!
9259 @brief comparison: greater than
9260 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9261 */
9262 bool operator>(const iter_impl& other) const
9263 {
9264 return not operator<=(other);
9265 }
9266
9267 /*!
9268 @brief comparison: greater than or equal
9269 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9270 */
9271 bool operator>=(const iter_impl& other) const
9272 {
9273 return not operator<(other);
9274 }
9275
9276 /*!
9277 @brief add to iterator
9278 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9279 */
9281 {
9282 assert(m_object != nullptr);
9283
9284 switch (m_object->m_type)
9285 {
9287 {
9288 JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
9289 }
9290
9292 {
9293 std::advance(m_it.array_iterator, i);
9294 break;
9295 }
9296
9297 default:
9298 {
9299 m_it.primitive_iterator += i;
9300 break;
9301 }
9302 }
9303
9304 return *this;
9305 }
9306
9307 /*!
9308 @brief subtract from iterator
9309 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9310 */
9312 {
9313 return operator+=(-i);
9314 }
9315
9316 /*!
9317 @brief add to iterator
9318 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9319 */
9321 {
9322 auto result = *this;
9323 result += i;
9324 return result;
9325 }
9326
9327 /*!
9328 @brief subtract from iterator
9329 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9330 */
9332 {
9333 auto result = *this;
9334 result -= i;
9335 return result;
9336 }
9337
9338 /*!
9339 @brief return difference
9340 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9341 */
9343 {
9344 assert(m_object != nullptr);
9345
9346 switch (m_object->m_type)
9347 {
9349 {
9350 JSON_THROW(std::domain_error("cannot use offsets with object iterators"));
9351 }
9352
9354 {
9355 return m_it.array_iterator - other.m_it.array_iterator;
9356 }
9357
9358 default:
9359 {
9360 return m_it.primitive_iterator - other.m_it.primitive_iterator;
9361 }
9362 }
9363 }
9364
9365 /*!
9366 @brief access to successor
9367 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9368 */
9370 {
9371 assert(m_object != nullptr);
9372
9373 switch (m_object->m_type)
9374 {
9376 {
9377 JSON_THROW(std::domain_error("cannot use operator[] for object iterators"));
9378 }
9379
9381 {
9382 return *std::next(m_it.array_iterator, n);
9383 }
9384
9386 {
9387 JSON_THROW(std::out_of_range("cannot get value"));
9388 }
9389
9390 default:
9391 {
9392 if (m_it.primitive_iterator.get_value() == -n)
9393 {
9394 return *m_object;
9395 }
9396
9397 JSON_THROW(std::out_of_range("cannot get value"));
9398 }
9399 }
9400 }
9401
9402 /*!
9403 @brief return the key of an object iterator
9404 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9405 */
9406 typename object_t::key_type key() const
9407 {
9408 assert(m_object != nullptr);
9409
9410 if (m_object->is_object())
9411 {
9412 return m_it.object_iterator->first;
9413 }
9414
9415 JSON_THROW(std::domain_error("cannot use key() for non-object iterators"));
9416 }
9417
9418 /*!
9419 @brief return the value of an iterator
9420 @pre The iterator is initialized; i.e. `m_object != nullptr`.
9421 */
9423 {
9424 return operator*();
9425 }
9426
9427 private:
9428 /// associated JSON instance
9429 pointer m_object = nullptr;
9430 /// the actual iterator of the associated instance
9432 };
9433
9434 /*!
9435 @brief a template for a reverse iterator class
9436
9437 @tparam Base the base iterator type to reverse. Valid types are @ref
9438 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
9439 create @ref const_reverse_iterator).
9440
9441 @requirement The class satisfies the following concept requirements:
9442 - [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
9443 The iterator that can be moved to point (forward and backward) to any
9444 element in constant time.
9445 - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
9446 It is possible to write to the pointed-to element (only if @a Base is
9447 @ref iterator).
9448
9449 @since version 1.0.0
9450 */
9451 template<typename Base>
9452 class json_reverse_iterator : public std::reverse_iterator<Base>
9453 {
9454 public:
9455 /// shortcut to the reverse iterator adaptor
9456 using base_iterator = std::reverse_iterator<Base>;
9457 /// the reference type for the pointed-to element
9458 using reference = typename Base::reference;
9459
9460 /// create reverse iterator from iterator
9461 json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
9462 : base_iterator(it)
9463 {}
9464
9465 /// create reverse iterator from base class
9467 : base_iterator(it)
9468 {}
9469
9470 /// post-increment (it++)
9472 {
9473 return base_iterator::operator++(1);
9474 }
9475
9476 /// pre-increment (++it)
9478 {
9479 base_iterator::operator++();
9480 return *this;
9481 }
9482
9483 /// post-decrement (it--)
9485 {
9486 return base_iterator::operator--(1);
9487 }
9488
9489 /// pre-decrement (--it)
9491 {
9492 base_iterator::operator--();
9493 return *this;
9494 }
9495
9496 /// add to iterator
9498 {
9500 return *this;
9501 }
9502
9503 /// add to iterator
9505 {
9506 auto result = *this;
9507 result += i;
9508 return result;
9509 }
9510
9511 /// subtract from iterator
9513 {
9514 auto result = *this;
9515 result -= i;
9516 return result;
9517 }
9518
9519 /// return difference
9521 {
9522 return this->base() - other.base();
9523 }
9524
9525 /// access to successor
9527 {
9528 return *(this->operator+(n));
9529 }
9530
9531 /// return the key of an object iterator
9532 typename object_t::key_type key() const
9533 {
9534 auto it = --this->base();
9535 return it.key();
9536 }
9537
9538 /// return the value of an iterator
9540 {
9541 auto it = --this->base();
9542 return it.operator * ();
9543 }
9544 };
9545
9546
9547 private:
9548 //////////////////////
9549 // lexer and parser //
9550 //////////////////////
9551
9552 /*!
9553 @brief lexical analysis
9554
9555 This class organizes the lexical analysis during JSON deserialization. The
9556 core of it is a scanner generated by [re2c](http://re2c.org) that
9557 processes a buffer and recognizes tokens according to RFC 7159.
9558 */
9559 class lexer
9560 {
9561 public:
9562 /// token types for the parser
9563 enum class token_type
9564 {
9565 uninitialized, ///< indicating the scanner is uninitialized
9566 literal_true, ///< the `true` literal
9567 literal_false, ///< the `false` literal
9568 literal_null, ///< the `null` literal
9569 value_string, ///< a string -- use get_string() for actual value
9570 value_unsigned, ///< an unsigned integer -- use get_number() for actual value
9571 value_integer, ///< a signed integer -- use get_number() for actual value
9572 value_float, ///< an floating point number -- use get_number() for actual value
9573 begin_array, ///< the character for array begin `[`
9574 begin_object, ///< the character for object begin `{`
9575 end_array, ///< the character for array end `]`
9576 end_object, ///< the character for object end `}`
9577 name_separator, ///< the name separator `:`
9578 value_separator, ///< the value separator `,`
9579 parse_error, ///< indicating a parse error
9580 end_of_input ///< indicating the end of the input buffer
9581 };
9582
9583 /// the char type to use in the lexer
9584 using lexer_char_t = unsigned char;
9585
9586 /// a lexer from a buffer with given length
9587 lexer(const lexer_char_t* buff, const size_t len) noexcept
9588 : m_content(buff)
9589 {
9590 assert(m_content != nullptr);
9591 m_start = m_cursor = m_content;
9592 m_limit = m_content + len;
9593 }
9594
9595 /// a lexer from an input stream
9596 explicit lexer(std::istream& s)
9597 : m_stream(&s), m_line_buffer()
9598 {
9599 // immediately abort if stream is erroneous
9600 if (s.fail())
9601 {
9602 JSON_THROW(std::invalid_argument("stream error"));
9603 }
9604
9605 // fill buffer
9606 fill_line_buffer();
9607
9608 // skip UTF-8 byte-order mark
9609 if (m_line_buffer.size() >= 3 and m_line_buffer.substr(0, 3) == "\xEF\xBB\xBF")
9610 {
9611 m_line_buffer[0] = ' ';
9612 m_line_buffer[1] = ' ';
9613 m_line_buffer[2] = ' ';
9614 }
9615 }
9616
9617 // switch off unwanted functions (due to pointer members)
9618 lexer() = delete;
9619 lexer(const lexer&) = delete;
9620 lexer operator=(const lexer&) = delete;
9621
9622 /*!
9623 @brief create a string from one or two Unicode code points
9624
9625 There are two cases: (1) @a codepoint1 is in the Basic Multilingual
9626 Plane (U+0000 through U+FFFF) and @a codepoint2 is 0, or (2)
9627 @a codepoint1 and @a codepoint2 are a UTF-16 surrogate pair to
9628 represent a code point above U+FFFF.
9629
9630 @param[in] codepoint1 the code point (can be high surrogate)
9631 @param[in] codepoint2 the code point (can be low surrogate or 0)
9632
9633 @return string representation of the code point; the length of the
9634 result string is between 1 and 4 characters.
9635
9636 @throw std::out_of_range if code point is > 0x10ffff; example: `"code
9637 points above 0x10FFFF are invalid"`
9638 @throw std::invalid_argument if the low surrogate is invalid; example:
9639 `""missing or wrong low surrogate""`
9640
9641 @complexity Constant.
9642
9643 @see <http://en.wikipedia.org/wiki/UTF-8#Sample_code>
9644 */
9645 static string_t to_unicode(const std::size_t codepoint1,
9646 const std::size_t codepoint2 = 0)
9647 {
9648 // calculate the code point from the given code points
9649 std::size_t codepoint = codepoint1;
9650
9651 // check if codepoint1 is a high surrogate
9652 if (codepoint1 >= 0xD800 and codepoint1 <= 0xDBFF)
9653 {
9654 // check if codepoint2 is a low surrogate
9655 if (codepoint2 >= 0xDC00 and codepoint2 <= 0xDFFF)
9656 {
9657 codepoint =
9658 // high surrogate occupies the most significant 22 bits
9659 (codepoint1 << 10)
9660 // low surrogate occupies the least significant 15 bits
9661 + codepoint2
9662 // there is still the 0xD800, 0xDC00 and 0x10000 noise
9663 // in the result so we have to subtract with:
9664 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
9665 - 0x35FDC00;
9666 }
9667 else
9668 {
9669 JSON_THROW(std::invalid_argument("missing or wrong low surrogate"));
9670 }
9671 }
9672
9673 string_t result;
9674
9675 if (codepoint < 0x80)
9676 {
9677 // 1-byte characters: 0xxxxxxx (ASCII)
9678 result.append(1, static_cast<typename string_t::value_type>(codepoint));
9679 }
9680 else if (codepoint <= 0x7ff)
9681 {
9682 // 2-byte characters: 110xxxxx 10xxxxxx
9683 result.append(1, static_cast<typename string_t::value_type>(0xC0 | ((codepoint >> 6) & 0x1F)));
9684 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9685 }
9686 else if (codepoint <= 0xffff)
9687 {
9688 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
9689 result.append(1, static_cast<typename string_t::value_type>(0xE0 | ((codepoint >> 12) & 0x0F)));
9690 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
9691 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9692 }
9693 else if (codepoint <= 0x10ffff)
9694 {
9695 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
9696 result.append(1, static_cast<typename string_t::value_type>(0xF0 | ((codepoint >> 18) & 0x07)));
9697 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 12) & 0x3F)));
9698 result.append(1, static_cast<typename string_t::value_type>(0x80 | ((codepoint >> 6) & 0x3F)));
9699 result.append(1, static_cast<typename string_t::value_type>(0x80 | (codepoint & 0x3F)));
9700 }
9701 else
9702 {
9703 JSON_THROW(std::out_of_range("code points above 0x10FFFF are invalid"));
9704 }
9705
9706 return result;
9707 }
9708
9709 /// return name of values of type token_type (only used for errors)
9710 static std::string token_type_name(const token_type t)
9711 {
9712 switch (t)
9713 {
9714 case token_type::uninitialized:
9715 return "<uninitialized>";
9716 case token_type::literal_true:
9717 return "true literal";
9718 case token_type::literal_false:
9719 return "false literal";
9720 case token_type::literal_null:
9721 return "null literal";
9722 case token_type::value_string:
9723 return "string literal";
9724 case lexer::token_type::value_unsigned:
9725 case lexer::token_type::value_integer:
9726 case lexer::token_type::value_float:
9727 return "number literal";
9728 case token_type::begin_array:
9729 return "'['";
9730 case token_type::begin_object:
9731 return "'{'";
9732 case token_type::end_array:
9733 return "']'";
9734 case token_type::end_object:
9735 return "'}'";
9736 case token_type::name_separator:
9737 return "':'";
9738 case token_type::value_separator:
9739 return "','";
9740 case token_type::parse_error:
9741 return "<parse error>";
9742 case token_type::end_of_input:
9743 return "end of input";
9744 default:
9745 {
9746 // catch non-enum values
9747 return "unknown token"; // LCOV_EXCL_LINE
9748 }
9749 }
9750 }
9751
9752 /*!
9753 This function implements a scanner for JSON. It is specified using
9754 regular expressions that try to follow RFC 7159 as close as possible.
9755 These regular expressions are then translated into a minimized
9756 deterministic finite automaton (DFA) by the tool
9757 [re2c](http://re2c.org). As a result, the translated code for this
9758 function consists of a large block of code with `goto` jumps.
9759
9760 @return the class of the next token read from the buffer
9761
9762 @complexity Linear in the length of the input.\n
9763
9764 Proposition: The loop below will always terminate for finite input.\n
9765
9766 Proof (by contradiction): Assume a finite input. To loop forever, the
9767 loop must never hit code with a `break` statement. The only code
9768 snippets without a `break` statement are the continue statements for
9769 whitespace and byte-order-marks. To loop forever, the input must be an
9770 infinite sequence of whitespace or byte-order-marks. This contradicts
9771 the assumption of finite input, q.e.d.
9772 */
9774 {
9775 while (true)
9776 {
9777 // pointer for backtracking information
9778 m_marker = nullptr;
9779
9780 // remember the begin of the token
9781 m_start = m_cursor;
9782 assert(m_start != nullptr);
9783
9784
9785 {
9786 lexer_char_t yych;
9787 unsigned int yyaccept = 0;
9788 static const unsigned char yybm[] =
9789 {
9790 0, 0, 0, 0, 0, 0, 0, 0,
9791 0, 32, 32, 0, 0, 32, 0, 0,
9792 0, 0, 0, 0, 0, 0, 0, 0,
9793 0, 0, 0, 0, 0, 0, 0, 0,
9794 160, 128, 0, 128, 128, 128, 128, 128,
9795 128, 128, 128, 128, 128, 128, 128, 128,
9796 192, 192, 192, 192, 192, 192, 192, 192,
9797 192, 192, 128, 128, 128, 128, 128, 128,
9798 128, 128, 128, 128, 128, 128, 128, 128,
9799 128, 128, 128, 128, 128, 128, 128, 128,
9800 128, 128, 128, 128, 128, 128, 128, 128,
9801 128, 128, 128, 128, 0, 128, 128, 128,
9802 128, 128, 128, 128, 128, 128, 128, 128,
9803 128, 128, 128, 128, 128, 128, 128, 128,
9804 128, 128, 128, 128, 128, 128, 128, 128,
9805 128, 128, 128, 128, 128, 128, 128, 128,
9806 0, 0, 0, 0, 0, 0, 0, 0,
9807 0, 0, 0, 0, 0, 0, 0, 0,
9808 0, 0, 0, 0, 0, 0, 0, 0,
9809 0, 0, 0, 0, 0, 0, 0, 0,
9810 0, 0, 0, 0, 0, 0, 0, 0,
9811 0, 0, 0, 0, 0, 0, 0, 0,
9812 0, 0, 0, 0, 0, 0, 0, 0,
9813 0, 0, 0, 0, 0, 0, 0, 0,
9814 0, 0, 0, 0, 0, 0, 0, 0,
9815 0, 0, 0, 0, 0, 0, 0, 0,
9816 0, 0, 0, 0, 0, 0, 0, 0,
9817 0, 0, 0, 0, 0, 0, 0, 0,
9818 0, 0, 0, 0, 0, 0, 0, 0,
9819 0, 0, 0, 0, 0, 0, 0, 0,
9820 0, 0, 0, 0, 0, 0, 0, 0,
9821 0, 0, 0, 0, 0, 0, 0, 0,
9822 };
9823 if ((m_limit - m_cursor) < 5)
9824 {
9825 fill_line_buffer(5); // LCOV_EXCL_LINE
9826 }
9827 yych = *m_cursor;
9828 if (yybm[0 + yych] & 32)
9829 {
9830 goto basic_json_parser_6;
9831 }
9832 if (yych <= '[')
9833 {
9834 if (yych <= '-')
9835 {
9836 if (yych <= '"')
9837 {
9838 if (yych <= 0x00)
9839 {
9840 goto basic_json_parser_2;
9841 }
9842 if (yych <= '!')
9843 {
9844 goto basic_json_parser_4;
9845 }
9846 goto basic_json_parser_9;
9847 }
9848 else
9849 {
9850 if (yych <= '+')
9851 {
9852 goto basic_json_parser_4;
9853 }
9854 if (yych <= ',')
9855 {
9856 goto basic_json_parser_10;
9857 }
9858 goto basic_json_parser_12;
9859 }
9860 }
9861 else
9862 {
9863 if (yych <= '9')
9864 {
9865 if (yych <= '/')
9866 {
9867 goto basic_json_parser_4;
9868 }
9869 if (yych <= '0')
9870 {
9871 goto basic_json_parser_13;
9872 }
9873 goto basic_json_parser_15;
9874 }
9875 else
9876 {
9877 if (yych <= ':')
9878 {
9879 goto basic_json_parser_17;
9880 }
9881 if (yych <= 'Z')
9882 {
9883 goto basic_json_parser_4;
9884 }
9885 goto basic_json_parser_19;
9886 }
9887 }
9888 }
9889 else
9890 {
9891 if (yych <= 'n')
9892 {
9893 if (yych <= 'e')
9894 {
9895 if (yych == ']')
9896 {
9897 goto basic_json_parser_21;
9898 }
9899 goto basic_json_parser_4;
9900 }
9901 else
9902 {
9903 if (yych <= 'f')
9904 {
9905 goto basic_json_parser_23;
9906 }
9907 if (yych <= 'm')
9908 {
9909 goto basic_json_parser_4;
9910 }
9911 goto basic_json_parser_24;
9912 }
9913 }
9914 else
9915 {
9916 if (yych <= 'z')
9917 {
9918 if (yych == 't')
9919 {
9920 goto basic_json_parser_25;
9921 }
9922 goto basic_json_parser_4;
9923 }
9924 else
9925 {
9926 if (yych <= '{')
9927 {
9928 goto basic_json_parser_26;
9929 }
9930 if (yych == '}')
9931 {
9932 goto basic_json_parser_28;
9933 }
9934 goto basic_json_parser_4;
9935 }
9936 }
9937 }
9938basic_json_parser_2:
9939 ++m_cursor;
9940 {
9941 last_token_type = token_type::end_of_input;
9942 break;
9943 }
9944basic_json_parser_4:
9945 ++m_cursor;
9946basic_json_parser_5:
9947 {
9948 last_token_type = token_type::parse_error;
9949 break;
9950 }
9951basic_json_parser_6:
9952 ++m_cursor;
9953 if (m_limit <= m_cursor)
9954 {
9955 fill_line_buffer(1); // LCOV_EXCL_LINE
9956 }
9957 yych = *m_cursor;
9958 if (yybm[0 + yych] & 32)
9959 {
9960 goto basic_json_parser_6;
9961 }
9962 {
9963 continue;
9964 }
9965basic_json_parser_9:
9966 yyaccept = 0;
9967 yych = *(m_marker = ++m_cursor);
9968 if (yych <= 0x1F)
9969 {
9970 goto basic_json_parser_5;
9971 }
9972 if (yych <= 0x7F)
9973 {
9974 goto basic_json_parser_31;
9975 }
9976 if (yych <= 0xC1)
9977 {
9978 goto basic_json_parser_5;
9979 }
9980 if (yych <= 0xF4)
9981 {
9982 goto basic_json_parser_31;
9983 }
9984 goto basic_json_parser_5;
9985basic_json_parser_10:
9986 ++m_cursor;
9987 {
9988 last_token_type = token_type::value_separator;
9989 break;
9990 }
9991basic_json_parser_12:
9992 yych = *++m_cursor;
9993 if (yych <= '/')
9994 {
9995 goto basic_json_parser_5;
9996 }
9997 if (yych <= '0')
9998 {
9999 goto basic_json_parser_43;
10000 }
10001 if (yych <= '9')
10002 {
10003 goto basic_json_parser_45;
10004 }
10005 goto basic_json_parser_5;
10006basic_json_parser_13:
10007 yyaccept = 1;
10008 yych = *(m_marker = ++m_cursor);
10009 if (yych <= '9')
10010 {
10011 if (yych == '.')
10012 {
10013 goto basic_json_parser_47;
10014 }
10015 if (yych >= '0')
10016 {
10017 goto basic_json_parser_48;
10018 }
10019 }
10020 else
10021 {
10022 if (yych <= 'E')
10023 {
10024 if (yych >= 'E')
10025 {
10026 goto basic_json_parser_51;
10027 }
10028 }
10029 else
10030 {
10031 if (yych == 'e')
10032 {
10033 goto basic_json_parser_51;
10034 }
10035 }
10036 }
10037basic_json_parser_14:
10038 {
10039 last_token_type = token_type::value_unsigned;
10040 break;
10041 }
10042basic_json_parser_15:
10043 yyaccept = 1;
10044 m_marker = ++m_cursor;
10045 if ((m_limit - m_cursor) < 3)
10046 {
10047 fill_line_buffer(3); // LCOV_EXCL_LINE
10048 }
10049 yych = *m_cursor;
10050 if (yybm[0 + yych] & 64)
10051 {
10052 goto basic_json_parser_15;
10053 }
10054 if (yych <= 'D')
10055 {
10056 if (yych == '.')
10057 {
10058 goto basic_json_parser_47;
10059 }
10060 goto basic_json_parser_14;
10061 }
10062 else
10063 {
10064 if (yych <= 'E')
10065 {
10066 goto basic_json_parser_51;
10067 }
10068 if (yych == 'e')
10069 {
10070 goto basic_json_parser_51;
10071 }
10072 goto basic_json_parser_14;
10073 }
10074basic_json_parser_17:
10075 ++m_cursor;
10076 {
10077 last_token_type = token_type::name_separator;
10078 break;
10079 }
10080basic_json_parser_19:
10081 ++m_cursor;
10082 {
10083 last_token_type = token_type::begin_array;
10084 break;
10085 }
10086basic_json_parser_21:
10087 ++m_cursor;
10088 {
10089 last_token_type = token_type::end_array;
10090 break;
10091 }
10092basic_json_parser_23:
10093 yyaccept = 0;
10094 yych = *(m_marker = ++m_cursor);
10095 if (yych == 'a')
10096 {
10097 goto basic_json_parser_52;
10098 }
10099 goto basic_json_parser_5;
10100basic_json_parser_24:
10101 yyaccept = 0;
10102 yych = *(m_marker = ++m_cursor);
10103 if (yych == 'u')
10104 {
10105 goto basic_json_parser_53;
10106 }
10107 goto basic_json_parser_5;
10108basic_json_parser_25:
10109 yyaccept = 0;
10110 yych = *(m_marker = ++m_cursor);
10111 if (yych == 'r')
10112 {
10113 goto basic_json_parser_54;
10114 }
10115 goto basic_json_parser_5;
10116basic_json_parser_26:
10117 ++m_cursor;
10118 {
10119 last_token_type = token_type::begin_object;
10120 break;
10121 }
10122basic_json_parser_28:
10123 ++m_cursor;
10124 {
10125 last_token_type = token_type::end_object;
10126 break;
10127 }
10128basic_json_parser_30:
10129 ++m_cursor;
10130 if (m_limit <= m_cursor)
10131 {
10132 fill_line_buffer(1); // LCOV_EXCL_LINE
10133 }
10134 yych = *m_cursor;
10135basic_json_parser_31:
10136 if (yybm[0 + yych] & 128)
10137 {
10138 goto basic_json_parser_30;
10139 }
10140 if (yych <= 0xE0)
10141 {
10142 if (yych <= '\\')
10143 {
10144 if (yych <= 0x1F)
10145 {
10146 goto basic_json_parser_32;
10147 }
10148 if (yych <= '"')
10149 {
10150 goto basic_json_parser_33;
10151 }
10152 goto basic_json_parser_35;
10153 }
10154 else
10155 {
10156 if (yych <= 0xC1)
10157 {
10158 goto basic_json_parser_32;
10159 }
10160 if (yych <= 0xDF)
10161 {
10162 goto basic_json_parser_36;
10163 }
10164 goto basic_json_parser_37;
10165 }
10166 }
10167 else
10168 {
10169 if (yych <= 0xEF)
10170 {
10171 if (yych == 0xED)
10172 {
10173 goto basic_json_parser_39;
10174 }
10175 goto basic_json_parser_38;
10176 }
10177 else
10178 {
10179 if (yych <= 0xF0)
10180 {
10181 goto basic_json_parser_40;
10182 }
10183 if (yych <= 0xF3)
10184 {
10185 goto basic_json_parser_41;
10186 }
10187 if (yych <= 0xF4)
10188 {
10189 goto basic_json_parser_42;
10190 }
10191 }
10192 }
10193basic_json_parser_32:
10194 m_cursor = m_marker;
10195 if (yyaccept <= 1)
10196 {
10197 if (yyaccept == 0)
10198 {
10199 goto basic_json_parser_5;
10200 }
10201 else
10202 {
10203 goto basic_json_parser_14;
10204 }
10205 }
10206 else
10207 {
10208 if (yyaccept == 2)
10209 {
10210 goto basic_json_parser_44;
10211 }
10212 else
10213 {
10214 goto basic_json_parser_58;
10215 }
10216 }
10217basic_json_parser_33:
10218 ++m_cursor;
10219 {
10220 last_token_type = token_type::value_string;
10221 break;
10222 }
10223basic_json_parser_35:
10224 ++m_cursor;
10225 if (m_limit <= m_cursor)
10226 {
10227 fill_line_buffer(1); // LCOV_EXCL_LINE
10228 }
10229 yych = *m_cursor;
10230 if (yych <= 'e')
10231 {
10232 if (yych <= '/')
10233 {
10234 if (yych == '"')
10235 {
10236 goto basic_json_parser_30;
10237 }
10238 if (yych <= '.')
10239 {
10240 goto basic_json_parser_32;
10241 }
10242 goto basic_json_parser_30;
10243 }
10244 else
10245 {
10246 if (yych <= '\\')
10247 {
10248 if (yych <= '[')
10249 {
10250 goto basic_json_parser_32;
10251 }
10252 goto basic_json_parser_30;
10253 }
10254 else
10255 {
10256 if (yych == 'b')
10257 {
10258 goto basic_json_parser_30;
10259 }
10260 goto basic_json_parser_32;
10261 }
10262 }
10263 }
10264 else
10265 {
10266 if (yych <= 'q')
10267 {
10268 if (yych <= 'f')
10269 {
10270 goto basic_json_parser_30;
10271 }
10272 if (yych == 'n')
10273 {
10274 goto basic_json_parser_30;
10275 }
10276 goto basic_json_parser_32;
10277 }
10278 else
10279 {
10280 if (yych <= 's')
10281 {
10282 if (yych <= 'r')
10283 {
10284 goto basic_json_parser_30;
10285 }
10286 goto basic_json_parser_32;
10287 }
10288 else
10289 {
10290 if (yych <= 't')
10291 {
10292 goto basic_json_parser_30;
10293 }
10294 if (yych <= 'u')
10295 {
10296 goto basic_json_parser_55;
10297 }
10298 goto basic_json_parser_32;
10299 }
10300 }
10301 }
10302basic_json_parser_36:
10303 ++m_cursor;
10304 if (m_limit <= m_cursor)
10305 {
10306 fill_line_buffer(1); // LCOV_EXCL_LINE
10307 }
10308 yych = *m_cursor;
10309 if (yych <= 0x7F)
10310 {
10311 goto basic_json_parser_32;
10312 }
10313 if (yych <= 0xBF)
10314 {
10315 goto basic_json_parser_30;
10316 }
10317 goto basic_json_parser_32;
10318basic_json_parser_37:
10319 ++m_cursor;
10320 if (m_limit <= m_cursor)
10321 {
10322 fill_line_buffer(1); // LCOV_EXCL_LINE
10323 }
10324 yych = *m_cursor;
10325 if (yych <= 0x9F)
10326 {
10327 goto basic_json_parser_32;
10328 }
10329 if (yych <= 0xBF)
10330 {
10331 goto basic_json_parser_36;
10332 }
10333 goto basic_json_parser_32;
10334basic_json_parser_38:
10335 ++m_cursor;
10336 if (m_limit <= m_cursor)
10337 {
10338 fill_line_buffer(1); // LCOV_EXCL_LINE
10339 }
10340 yych = *m_cursor;
10341 if (yych <= 0x7F)
10342 {
10343 goto basic_json_parser_32;
10344 }
10345 if (yych <= 0xBF)
10346 {
10347 goto basic_json_parser_36;
10348 }
10349 goto basic_json_parser_32;
10350basic_json_parser_39:
10351 ++m_cursor;
10352 if (m_limit <= m_cursor)
10353 {
10354 fill_line_buffer(1); // LCOV_EXCL_LINE
10355 }
10356 yych = *m_cursor;
10357 if (yych <= 0x7F)
10358 {
10359 goto basic_json_parser_32;
10360 }
10361 if (yych <= 0x9F)
10362 {
10363 goto basic_json_parser_36;
10364 }
10365 goto basic_json_parser_32;
10366basic_json_parser_40:
10367 ++m_cursor;
10368 if (m_limit <= m_cursor)
10369 {
10370 fill_line_buffer(1); // LCOV_EXCL_LINE
10371 }
10372 yych = *m_cursor;
10373 if (yych <= 0x8F)
10374 {
10375 goto basic_json_parser_32;
10376 }
10377 if (yych <= 0xBF)
10378 {
10379 goto basic_json_parser_38;
10380 }
10381 goto basic_json_parser_32;
10382basic_json_parser_41:
10383 ++m_cursor;
10384 if (m_limit <= m_cursor)
10385 {
10386 fill_line_buffer(1); // LCOV_EXCL_LINE
10387 }
10388 yych = *m_cursor;
10389 if (yych <= 0x7F)
10390 {
10391 goto basic_json_parser_32;
10392 }
10393 if (yych <= 0xBF)
10394 {
10395 goto basic_json_parser_38;
10396 }
10397 goto basic_json_parser_32;
10398basic_json_parser_42:
10399 ++m_cursor;
10400 if (m_limit <= m_cursor)
10401 {
10402 fill_line_buffer(1); // LCOV_EXCL_LINE
10403 }
10404 yych = *m_cursor;
10405 if (yych <= 0x7F)
10406 {
10407 goto basic_json_parser_32;
10408 }
10409 if (yych <= 0x8F)
10410 {
10411 goto basic_json_parser_38;
10412 }
10413 goto basic_json_parser_32;
10414basic_json_parser_43:
10415 yyaccept = 2;
10416 yych = *(m_marker = ++m_cursor);
10417 if (yych <= '9')
10418 {
10419 if (yych == '.')
10420 {
10421 goto basic_json_parser_47;
10422 }
10423 if (yych >= '0')
10424 {
10425 goto basic_json_parser_48;
10426 }
10427 }
10428 else
10429 {
10430 if (yych <= 'E')
10431 {
10432 if (yych >= 'E')
10433 {
10434 goto basic_json_parser_51;
10435 }
10436 }
10437 else
10438 {
10439 if (yych == 'e')
10440 {
10441 goto basic_json_parser_51;
10442 }
10443 }
10444 }
10445basic_json_parser_44:
10446 {
10447 last_token_type = token_type::value_integer;
10448 break;
10449 }
10450basic_json_parser_45:
10451 yyaccept = 2;
10452 m_marker = ++m_cursor;
10453 if ((m_limit - m_cursor) < 3)
10454 {
10455 fill_line_buffer(3); // LCOV_EXCL_LINE
10456 }
10457 yych = *m_cursor;
10458 if (yych <= '9')
10459 {
10460 if (yych == '.')
10461 {
10462 goto basic_json_parser_47;
10463 }
10464 if (yych <= '/')
10465 {
10466 goto basic_json_parser_44;
10467 }
10468 goto basic_json_parser_45;
10469 }
10470 else
10471 {
10472 if (yych <= 'E')
10473 {
10474 if (yych <= 'D')
10475 {
10476 goto basic_json_parser_44;
10477 }
10478 goto basic_json_parser_51;
10479 }
10480 else
10481 {
10482 if (yych == 'e')
10483 {
10484 goto basic_json_parser_51;
10485 }
10486 goto basic_json_parser_44;
10487 }
10488 }
10489basic_json_parser_47:
10490 yych = *++m_cursor;
10491 if (yych <= '/')
10492 {
10493 goto basic_json_parser_32;
10494 }
10495 if (yych <= '9')
10496 {
10497 goto basic_json_parser_56;
10498 }
10499 goto basic_json_parser_32;
10500basic_json_parser_48:
10501 ++m_cursor;
10502 if (m_limit <= m_cursor)
10503 {
10504 fill_line_buffer(1); // LCOV_EXCL_LINE
10505 }
10506 yych = *m_cursor;
10507 if (yych <= '/')
10508 {
10509 goto basic_json_parser_50;
10510 }
10511 if (yych <= '9')
10512 {
10513 goto basic_json_parser_48;
10514 }
10515basic_json_parser_50:
10516 {
10517 last_token_type = token_type::parse_error;
10518 break;
10519 }
10520basic_json_parser_51:
10521 yych = *++m_cursor;
10522 if (yych <= ',')
10523 {
10524 if (yych == '+')
10525 {
10526 goto basic_json_parser_59;
10527 }
10528 goto basic_json_parser_32;
10529 }
10530 else
10531 {
10532 if (yych <= '-')
10533 {
10534 goto basic_json_parser_59;
10535 }
10536 if (yych <= '/')
10537 {
10538 goto basic_json_parser_32;
10539 }
10540 if (yych <= '9')
10541 {
10542 goto basic_json_parser_60;
10543 }
10544 goto basic_json_parser_32;
10545 }
10546basic_json_parser_52:
10547 yych = *++m_cursor;
10548 if (yych == 'l')
10549 {
10550 goto basic_json_parser_62;
10551 }
10552 goto basic_json_parser_32;
10553basic_json_parser_53:
10554 yych = *++m_cursor;
10555 if (yych == 'l')
10556 {
10557 goto basic_json_parser_63;
10558 }
10559 goto basic_json_parser_32;
10560basic_json_parser_54:
10561 yych = *++m_cursor;
10562 if (yych == 'u')
10563 {
10564 goto basic_json_parser_64;
10565 }
10566 goto basic_json_parser_32;
10567basic_json_parser_55:
10568 ++m_cursor;
10569 if (m_limit <= m_cursor)
10570 {
10571 fill_line_buffer(1); // LCOV_EXCL_LINE
10572 }
10573 yych = *m_cursor;
10574 if (yych <= '@')
10575 {
10576 if (yych <= '/')
10577 {
10578 goto basic_json_parser_32;
10579 }
10580 if (yych <= '9')
10581 {
10582 goto basic_json_parser_65;
10583 }
10584 goto basic_json_parser_32;
10585 }
10586 else
10587 {
10588 if (yych <= 'F')
10589 {
10590 goto basic_json_parser_65;
10591 }
10592 if (yych <= '`')
10593 {
10594 goto basic_json_parser_32;
10595 }
10596 if (yych <= 'f')
10597 {
10598 goto basic_json_parser_65;
10599 }
10600 goto basic_json_parser_32;
10601 }
10602basic_json_parser_56:
10603 yyaccept = 3;
10604 m_marker = ++m_cursor;
10605 if ((m_limit - m_cursor) < 3)
10606 {
10607 fill_line_buffer(3); // LCOV_EXCL_LINE
10608 }
10609 yych = *m_cursor;
10610 if (yych <= 'D')
10611 {
10612 if (yych <= '/')
10613 {
10614 goto basic_json_parser_58;
10615 }
10616 if (yych <= '9')
10617 {
10618 goto basic_json_parser_56;
10619 }
10620 }
10621 else
10622 {
10623 if (yych <= 'E')
10624 {
10625 goto basic_json_parser_51;
10626 }
10627 if (yych == 'e')
10628 {
10629 goto basic_json_parser_51;
10630 }
10631 }
10632basic_json_parser_58:
10633 {
10634 last_token_type = token_type::value_float;
10635 break;
10636 }
10637basic_json_parser_59:
10638 yych = *++m_cursor;
10639 if (yych <= '/')
10640 {
10641 goto basic_json_parser_32;
10642 }
10643 if (yych >= ':')
10644 {
10645 goto basic_json_parser_32;
10646 }
10647basic_json_parser_60:
10648 ++m_cursor;
10649 if (m_limit <= m_cursor)
10650 {
10651 fill_line_buffer(1); // LCOV_EXCL_LINE
10652 }
10653 yych = *m_cursor;
10654 if (yych <= '/')
10655 {
10656 goto basic_json_parser_58;
10657 }
10658 if (yych <= '9')
10659 {
10660 goto basic_json_parser_60;
10661 }
10662 goto basic_json_parser_58;
10663basic_json_parser_62:
10664 yych = *++m_cursor;
10665 if (yych == 's')
10666 {
10667 goto basic_json_parser_66;
10668 }
10669 goto basic_json_parser_32;
10670basic_json_parser_63:
10671 yych = *++m_cursor;
10672 if (yych == 'l')
10673 {
10674 goto basic_json_parser_67;
10675 }
10676 goto basic_json_parser_32;
10677basic_json_parser_64:
10678 yych = *++m_cursor;
10679 if (yych == 'e')
10680 {
10681 goto basic_json_parser_69;
10682 }
10683 goto basic_json_parser_32;
10684basic_json_parser_65:
10685 ++m_cursor;
10686 if (m_limit <= m_cursor)
10687 {
10688 fill_line_buffer(1); // LCOV_EXCL_LINE
10689 }
10690 yych = *m_cursor;
10691 if (yych <= '@')
10692 {
10693 if (yych <= '/')
10694 {
10695 goto basic_json_parser_32;
10696 }
10697 if (yych <= '9')
10698 {
10699 goto basic_json_parser_71;
10700 }
10701 goto basic_json_parser_32;
10702 }
10703 else
10704 {
10705 if (yych <= 'F')
10706 {
10707 goto basic_json_parser_71;
10708 }
10709 if (yych <= '`')
10710 {
10711 goto basic_json_parser_32;
10712 }
10713 if (yych <= 'f')
10714 {
10715 goto basic_json_parser_71;
10716 }
10717 goto basic_json_parser_32;
10718 }
10719basic_json_parser_66:
10720 yych = *++m_cursor;
10721 if (yych == 'e')
10722 {
10723 goto basic_json_parser_72;
10724 }
10725 goto basic_json_parser_32;
10726basic_json_parser_67:
10727 ++m_cursor;
10728 {
10729 last_token_type = token_type::literal_null;
10730 break;
10731 }
10732basic_json_parser_69:
10733 ++m_cursor;
10734 {
10735 last_token_type = token_type::literal_true;
10736 break;
10737 }
10738basic_json_parser_71:
10739 ++m_cursor;
10740 if (m_limit <= m_cursor)
10741 {
10742 fill_line_buffer(1); // LCOV_EXCL_LINE
10743 }
10744 yych = *m_cursor;
10745 if (yych <= '@')
10746 {
10747 if (yych <= '/')
10748 {
10749 goto basic_json_parser_32;
10750 }
10751 if (yych <= '9')
10752 {
10753 goto basic_json_parser_74;
10754 }
10755 goto basic_json_parser_32;
10756 }
10757 else
10758 {
10759 if (yych <= 'F')
10760 {
10761 goto basic_json_parser_74;
10762 }
10763 if (yych <= '`')
10764 {
10765 goto basic_json_parser_32;
10766 }
10767 if (yych <= 'f')
10768 {
10769 goto basic_json_parser_74;
10770 }
10771 goto basic_json_parser_32;
10772 }
10773basic_json_parser_72:
10774 ++m_cursor;
10775 {
10776 last_token_type = token_type::literal_false;
10777 break;
10778 }
10779basic_json_parser_74:
10780 ++m_cursor;
10781 if (m_limit <= m_cursor)
10782 {
10783 fill_line_buffer(1); // LCOV_EXCL_LINE
10784 }
10785 yych = *m_cursor;
10786 if (yych <= '@')
10787 {
10788 if (yych <= '/')
10789 {
10790 goto basic_json_parser_32;
10791 }
10792 if (yych <= '9')
10793 {
10794 goto basic_json_parser_30;
10795 }
10796 goto basic_json_parser_32;
10797 }
10798 else
10799 {
10800 if (yych <= 'F')
10801 {
10802 goto basic_json_parser_30;
10803 }
10804 if (yych <= '`')
10805 {
10806 goto basic_json_parser_32;
10807 }
10808 if (yych <= 'f')
10809 {
10810 goto basic_json_parser_30;
10811 }
10812 goto basic_json_parser_32;
10813 }
10814 }
10815
10816 }
10817
10818 return last_token_type;
10819 }
10820
10821 /*!
10822 @brief append data from the stream to the line buffer
10823
10824 This function is called by the scan() function when the end of the
10825 buffer (`m_limit`) is reached and the `m_cursor` pointer cannot be
10826 incremented without leaving the limits of the line buffer. Note re2c
10827 decides when to call this function.
10828
10829 If the lexer reads from contiguous storage, there is no trailing null
10830 byte. Therefore, this function must make sure to add these padding
10831 null bytes.
10832
10833 If the lexer reads from an input stream, this function reads the next
10834 line of the input.
10835
10836 @pre
10837 p p p p p p u u u u u x . . . . . .
10838 ^ ^ ^ ^
10839 m_content m_start | m_limit
10840 m_cursor
10841
10842 @post
10843 u u u u u x x x x x x x . . . . . .
10844 ^ ^ ^
10845 | m_cursor m_limit
10846 m_start
10847 m_content
10848 */
10849 void fill_line_buffer(size_t n = 0)
10850 {
10851 // if line buffer is used, m_content points to its data
10852 assert(m_line_buffer.empty()
10853 or m_content == reinterpret_cast<const lexer_char_t*>(m_line_buffer.data()));
10854
10855 // if line buffer is used, m_limit is set past the end of its data
10856 assert(m_line_buffer.empty()
10857 or m_limit == m_content + m_line_buffer.size());
10858
10859 // pointer relationships
10860 assert(m_content <= m_start);
10861 assert(m_start <= m_cursor);
10862 assert(m_cursor <= m_limit);
10863 assert(m_marker == nullptr or m_marker <= m_limit);
10864
10865 // number of processed characters (p)
10866 const auto num_processed_chars = static_cast<size_t>(m_start - m_content);
10867 // offset for m_marker wrt. to m_start
10868 const auto offset_marker = (m_marker == nullptr) ? 0 : m_marker - m_start;
10869 // number of unprocessed characters (u)
10870 const auto offset_cursor = m_cursor - m_start;
10871
10872 // no stream is used or end of file is reached
10873 if (m_stream == nullptr or m_stream->eof())
10874 {
10875 // m_start may or may not be pointing into m_line_buffer at
10876 // this point. We trust the standard library to do the right
10877 // thing. See http://stackoverflow.com/q/28142011/266378
10878 m_line_buffer.assign(m_start, m_limit);
10879
10880 // append n characters to make sure that there is sufficient
10881 // space between m_cursor and m_limit
10882 m_line_buffer.append(1, '\x00');
10883 if (n > 0)
10884 {
10885 m_line_buffer.append(n - 1, '\x01');
10886 }
10887 }
10888 else
10889 {
10890 // delete processed characters from line buffer
10891 m_line_buffer.erase(0, num_processed_chars);
10892 // read next line from input stream
10893 m_line_buffer_tmp.clear();
10894 std::getline(*m_stream, m_line_buffer_tmp, '\n');
10895
10896 // add line with newline symbol to the line buffer
10897 m_line_buffer += m_line_buffer_tmp;
10898 m_line_buffer.push_back('\n');
10899 }
10900
10901 // set pointers
10902 m_content = reinterpret_cast<const lexer_char_t*>(m_line_buffer.data());
10903 assert(m_content != nullptr);
10904 m_start = m_content;
10905 m_marker = m_start + offset_marker;
10906 m_cursor = m_start + offset_cursor;
10907 m_limit = m_start + m_line_buffer.size();
10908 }
10909
10910 /// return string representation of last read token
10912 {
10913 assert(m_start != nullptr);
10914 return string_t(reinterpret_cast<typename string_t::const_pointer>(m_start),
10915 static_cast<size_t>(m_cursor - m_start));
10916 }
10917
10918 /*!
10919 @brief return string value for string tokens
10920
10921 The function iterates the characters between the opening and closing
10922 quotes of the string value. The complete string is the range
10923 [m_start,m_cursor). Consequently, we iterate from m_start+1 to
10924 m_cursor-1.
10925
10926 We differentiate two cases:
10927
10928 1. Escaped characters. In this case, a new character is constructed
10929 according to the nature of the escape. Some escapes create new
10930 characters (e.g., `"\\n"` is replaced by `"\n"`), some are copied
10931 as is (e.g., `"\\\\"`). Furthermore, Unicode escapes of the shape
10932 `"\\uxxxx"` need special care. In this case, to_unicode takes care
10933 of the construction of the values.
10934 2. Unescaped characters are copied as is.
10935
10936 @pre `m_cursor - m_start >= 2`, meaning the length of the last token
10937 is at least 2 bytes which is trivially true for any string (which
10938 consists of at least two quotes).
10939
10940 " c1 c2 c3 ... "
10941 ^ ^
10942 m_start m_cursor
10943
10944 @complexity Linear in the length of the string.\n
10945
10946 Lemma: The loop body will always terminate.\n
10947
10948 Proof (by contradiction): Assume the loop body does not terminate. As
10949 the loop body does not contain another loop, one of the called
10950 functions must never return. The called functions are `std::strtoul`
10951 and to_unicode. Neither function can loop forever, so the loop body
10952 will never loop forever which contradicts the assumption that the loop
10953 body does not terminate, q.e.d.\n
10954
10955 Lemma: The loop condition for the for loop is eventually false.\n
10956
10957 Proof (by contradiction): Assume the loop does not terminate. Due to
10958 the above lemma, this can only be due to a tautological loop
10959 condition; that is, the loop condition i < m_cursor - 1 must always be
10960 true. Let x be the change of i for any loop iteration. Then
10961 m_start + 1 + x < m_cursor - 1 must hold to loop indefinitely. This
10962 can be rephrased to m_cursor - m_start - 2 > x. With the
10963 precondition, we x <= 0, meaning that the loop condition holds
10964 indefinitely if i is always decreased. However, observe that the value
10965 of i is strictly increasing with each iteration, as it is incremented
10966 by 1 in the iteration expression and never decremented inside the loop
10967 body. Hence, the loop condition will eventually be false which
10968 contradicts the assumption that the loop condition is a tautology,
10969 q.e.d.
10970
10971 @return string value of current token without opening and closing
10972 quotes
10973 @throw std::out_of_range if to_unicode fails
10974 */
10976 {
10977 assert(m_cursor - m_start >= 2);
10978
10979 string_t result;
10980 result.reserve(static_cast<size_t>(m_cursor - m_start - 2));
10981
10982 // iterate the result between the quotes
10983 for (const lexer_char_t* i = m_start + 1; i < m_cursor - 1; ++i)
10984 {
10985 // find next escape character
10986 auto e = std::find(i, m_cursor - 1, '\\');
10987 if (e != i)
10988 {
10989 // see https://github.com/nlohmann/json/issues/365#issuecomment-262874705
10990 for (auto k = i; k < e; k++)
10991 {
10992 result.push_back(static_cast<typename string_t::value_type>(*k));
10993 }
10994 i = e - 1; // -1 because of ++i
10995 }
10996 else
10997 {
10998 // processing escaped character
10999 // read next character
11000 ++i;
11001
11002 switch (*i)
11003 {
11004 // the default escapes
11005 case 't':
11006 {
11007 result += "\t";
11008 break;
11009 }
11010 case 'b':
11011 {
11012 result += "\b";
11013 break;
11014 }
11015 case 'f':
11016 {
11017 result += "\f";
11018 break;
11019 }
11020 case 'n':
11021 {
11022 result += "\n";
11023 break;
11024 }
11025 case 'r':
11026 {
11027 result += "\r";
11028 break;
11029 }
11030 case '\\':
11031 {
11032 result += "\\";
11033 break;
11034 }
11035 case '/':
11036 {
11037 result += "/";
11038 break;
11039 }
11040 case '"':
11041 {
11042 result += "\"";
11043 break;
11044 }
11045
11046 // unicode
11047 case 'u':
11048 {
11049 // get code xxxx from uxxxx
11050 auto codepoint = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>(i + 1),
11051 4).c_str(), nullptr, 16);
11052
11053 // check if codepoint is a high surrogate
11054 if (codepoint >= 0xD800 and codepoint <= 0xDBFF)
11055 {
11056 // make sure there is a subsequent unicode
11057 if ((i + 6 >= m_limit) or * (i + 5) != '\\' or * (i + 6) != 'u')
11058 {
11059 JSON_THROW(std::invalid_argument("missing low surrogate"));
11060 }
11061
11062 // get code yyyy from uxxxx\uyyyy
11063 auto codepoint2 = std::strtoul(std::string(reinterpret_cast<typename string_t::const_pointer>
11064 (i + 7), 4).c_str(), nullptr, 16);
11065 result += to_unicode(codepoint, codepoint2);
11066 // skip the next 10 characters (xxxx\uyyyy)
11067 i += 10;
11068 }
11069 else if (codepoint >= 0xDC00 and codepoint <= 0xDFFF)
11070 {
11071 // we found a lone low surrogate
11072 JSON_THROW(std::invalid_argument("missing high surrogate"));
11073 }
11074 else
11075 {
11076 // add unicode character(s)
11077 result += to_unicode(codepoint);
11078 // skip the next four characters (xxxx)
11079 i += 4;
11080 }
11081 break;
11082 }
11083 }
11084 }
11085 }
11086
11087 return result;
11088 }
11089
11090
11091 /*!
11092 @brief parse string into a built-in arithmetic type as if the current
11093 locale is POSIX.
11094
11095 @note in floating-point case strtod may parse past the token's end -
11096 this is not an error
11097
11098 @note any leading blanks are not handled
11099 */
11101 {
11102 public:
11103 strtonum(const char* start, const char* end)
11104 : m_start(start), m_end(end)
11105 {}
11106
11107 /*!
11108 @return true iff parsed successfully as number of type T
11109
11110 @param[in,out] val shall contain parsed value, or undefined value
11111 if could not parse
11112 */
11113 template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
11114 bool to(T& val) const
11115 {
11116 return parse(val, std::is_integral<T>());
11117 }
11118
11119 private:
11120 const char* const m_start = nullptr;
11121 const char* const m_end = nullptr;
11122
11123 // floating-point conversion
11124
11125 // overloaded wrappers for strtod/strtof/strtold
11126 // that will be called from parse<floating_point_t>
11127 static void strtof(float& f, const char* str, char** endptr)
11128 {
11129 f = std::strtof(str, endptr);
11130 }
11131
11132 static void strtof(double& f, const char* str, char** endptr)
11133 {
11134 f = std::strtod(str, endptr);
11135 }
11136
11137 static void strtof(long double& f, const char* str, char** endptr)
11138 {
11139 f = std::strtold(str, endptr);
11140 }
11141
11142 template<typename T>
11143 bool parse(T& value, /*is_integral=*/std::false_type) const
11144 {
11145 // replace decimal separator with locale-specific version,
11146 // when necessary; data will point to either the original
11147 // string, or buf, or tempstr containing the fixed string.
11148 std::string tempstr;
11149 std::array<char, 64> buf;
11150 const size_t len = static_cast<size_t>(m_end - m_start);
11151
11152 // lexer will reject empty numbers
11153 assert(len > 0);
11154
11155 // since dealing with strtod family of functions, we're
11156 // getting the decimal point char from the C locale facilities
11157 // instead of C++'s numpunct facet of the current std::locale
11158 const auto loc = localeconv();
11159 assert(loc != nullptr);
11160 const char decimal_point_char = (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
11161
11162 const char* data = m_start;
11163
11164 if (decimal_point_char != '.')
11165 {
11166 const size_t ds_pos = static_cast<size_t>(std::find(m_start, m_end, '.') - m_start);
11167
11168 if (ds_pos != len)
11169 {
11170 // copy the data into the local buffer or tempstr, if
11171 // buffer is too small; replace decimal separator, and
11172 // update data to point to the modified bytes
11173 if ((len + 1) < buf.size())
11174 {
11175 std::copy(m_start, m_end, buf.begin());
11176 buf[len] = 0;
11177 buf[ds_pos] = decimal_point_char;
11178 data = buf.data();
11179 }
11180 else
11181 {
11182 tempstr.assign(m_start, m_end);
11183 tempstr[ds_pos] = decimal_point_char;
11184 data = tempstr.c_str();
11185 }
11186 }
11187 }
11188
11189 char* endptr = nullptr;
11190 value = 0;
11191 // this calls appropriate overload depending on T
11192 strtof(value, data, &endptr);
11193
11194 // parsing was successful iff strtof parsed exactly the number
11195 // of characters determined by the lexer (len)
11196 const bool ok = (endptr == (data + len));
11197
11198 if (ok and (value == static_cast<T>(0.0)) and (*data == '-'))
11199 {
11200 // some implementations forget to negate the zero
11201 value = -0.0;
11202 }
11203
11204 return ok;
11205 }
11206
11207 // integral conversion
11208
11209 signed long long parse_integral(char** endptr, /*is_signed*/std::true_type) const
11210 {
11211 return std::strtoll(m_start, endptr, 10);
11212 }
11213
11214 unsigned long long parse_integral(char** endptr, /*is_signed*/std::false_type) const
11215 {
11216 return std::strtoull(m_start, endptr, 10);
11217 }
11218
11219 template<typename T>
11220 bool parse(T& value, /*is_integral=*/std::true_type) const
11221 {
11222 char* endptr = nullptr;
11223 errno = 0; // these are thread-local
11224 const auto x = parse_integral(&endptr, std::is_signed<T>());
11225
11226 // called right overload?
11227 static_assert(std::is_signed<T>() == std::is_signed<decltype(x)>(), "");
11228
11229 value = static_cast<T>(x);
11230
11231 return (x == static_cast<decltype(x)>(value)) // x fits into destination T
11232 and (x < 0) == (value < 0) // preserved sign
11233 //and ((x != 0) or is_integral()) // strto[u]ll did nto fail
11234 and (errno == 0) // strto[u]ll did not overflow
11235 and (m_start < m_end) // token was not empty
11236 and (endptr == m_end); // parsed entire token exactly
11237 }
11238 };
11239
11240 /*!
11241 @brief return number value for number tokens
11242
11243 This function translates the last token into the most appropriate
11244 number type (either integer, unsigned integer or floating point),
11245 which is passed back to the caller via the result parameter.
11246
11247 integral numbers that don't fit into the the range of the respective
11248 type are parsed as number_float_t
11249
11250 floating-point values do not satisfy std::isfinite predicate
11251 are converted to value_t::null
11252
11253 throws if the entire string [m_start .. m_cursor) cannot be
11254 interpreted as a number
11255
11256 @param[out] result @ref basic_json object to receive the number.
11257 @param[in] token the type of the number token
11258 */
11259 bool get_number(basic_json& result, const token_type token) const
11260 {
11261 assert(m_start != nullptr);
11262 assert(m_start < m_cursor);
11263 assert((token == token_type::value_unsigned) or
11264 (token == token_type::value_integer) or
11265 (token == token_type::value_float));
11266
11267 strtonum num_converter(reinterpret_cast<const char*>(m_start),
11268 reinterpret_cast<const char*>(m_cursor));
11269
11270 switch (token)
11271 {
11272 case lexer::token_type::value_unsigned:
11273 {
11275 if (num_converter.to(val))
11276 {
11277 // parsing successful
11278 result.m_type = value_t::number_unsigned;
11279 result.m_value = val;
11280 return true;
11281 }
11282 break;
11283 }
11284
11285 case lexer::token_type::value_integer:
11286 {
11287 number_integer_t val;
11288 if (num_converter.to(val))
11289 {
11290 // parsing successful
11291 result.m_type = value_t::number_integer;
11292 result.m_value = val;
11293 return true;
11294 }
11295 break;
11296 }
11297
11298 default:
11299 {
11300 break;
11301 }
11302 }
11303
11304 // parse float (either explicitly or because a previous conversion
11305 // failed)
11306 number_float_t val;
11307 if (num_converter.to(val))
11308 {
11309 // parsing successful
11310 result.m_type = value_t::number_float;
11311 result.m_value = val;
11312
11313 // replace infinity and NAN by null
11314 if (not std::isfinite(result.m_value.number_float))
11315 {
11316 result.m_type = value_t::null;
11318 }
11319
11320 return true;
11321 }
11322
11323 // couldn't parse number in any format
11324 return false;
11325 }
11326
11327 private:
11328 /// optional input stream
11329 std::istream* m_stream = nullptr;
11330 /// line buffer buffer for m_stream
11331 string_t m_line_buffer {};
11332 /// used for filling m_line_buffer
11333 string_t m_line_buffer_tmp {};
11334 /// the buffer pointer
11335 const lexer_char_t* m_content = nullptr;
11336 /// pointer to the beginning of the current symbol
11337 const lexer_char_t* m_start = nullptr;
11338 /// pointer for backtracking information
11339 const lexer_char_t* m_marker = nullptr;
11340 /// pointer to the current symbol
11341 const lexer_char_t* m_cursor = nullptr;
11342 /// pointer to the end of the buffer
11343 const lexer_char_t* m_limit = nullptr;
11344 /// the last token type
11345 token_type last_token_type = token_type::end_of_input;
11346 };
11347
11348 /*!
11349 @brief syntax analysis
11350
11351 This class implements a recursive decent parser.
11352 */
11354 {
11355 public:
11356 /// a parser reading from a string literal
11357 parser(const char* buff, const parser_callback_t cb = nullptr)
11358 : callback(cb),
11359 m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), std::strlen(buff))
11360 {}
11361
11362 /// a parser reading from an input stream
11363 parser(std::istream& is, const parser_callback_t cb = nullptr)
11364 : callback(cb), m_lexer(is)
11365 {}
11366
11367 /// a parser reading from an iterator range with contiguous storage
11368 template<class IteratorType, typename std::enable_if<
11369 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
11370 , int>::type
11371 = 0>
11372 parser(IteratorType first, IteratorType last, const parser_callback_t cb = nullptr)
11373 : callback(cb),
11374 m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(&(*first)),
11375 static_cast<size_t>(std::distance(first, last)))
11376 {}
11377
11378 /// public parser interface
11380 {
11381 // read first token
11382 get_token();
11383
11384 basic_json result = parse_internal(true);
11385 result.assert_invariant();
11386
11387 expect(lexer::token_type::end_of_input);
11388
11389 // return parser result and replace it with null in case the
11390 // top-level value was discarded by the callback function
11391 return result.is_discarded() ? basic_json() : std::move(result);
11392 }
11393
11394 private:
11395 /// the actual parser
11397 {
11398 auto result = basic_json(value_t::discarded);
11399
11400 switch (last_token)
11401 {
11402 case lexer::token_type::begin_object:
11403 {
11404 if (keep and (not callback
11405 or ((keep = callback(depth++, parse_event_t::object_start, result)) != 0)))
11406 {
11407 // explicitly set result to object to cope with {}
11408 result.m_type = value_t::object;
11409 result.m_value = value_t::object;
11410 }
11411
11412 // read next token
11413 get_token();
11414
11415 // closing } -> we are done
11416 if (last_token == lexer::token_type::end_object)
11417 {
11418 get_token();
11419 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
11420 {
11421 result = basic_json(value_t::discarded);
11422 }
11423 return result;
11424 }
11425
11426 // no comma is expected here
11427 unexpect(lexer::token_type::value_separator);
11428
11429 // otherwise: parse key-value pairs
11430 do
11431 {
11432 // ugly, but could be fixed with loop reorganization
11433 if (last_token == lexer::token_type::value_separator)
11434 {
11435 get_token();
11436 }
11437
11438 // store key
11439 expect(lexer::token_type::value_string);
11440 const auto key = m_lexer.get_string();
11441
11442 bool keep_tag = false;
11443 if (keep)
11444 {
11445 if (callback)
11446 {
11447 basic_json k(key);
11448 keep_tag = callback(depth, parse_event_t::key, k);
11449 }
11450 else
11451 {
11452 keep_tag = true;
11453 }
11454 }
11455
11456 // parse separator (:)
11457 get_token();
11458 expect(lexer::token_type::name_separator);
11459
11460 // parse and add value
11461 get_token();
11462 auto value = parse_internal(keep);
11463 if (keep and keep_tag and not value.is_discarded())
11464 {
11465 result[key] = std::move(value);
11466 }
11467 }
11468 while (last_token == lexer::token_type::value_separator);
11469
11470 // closing }
11471 expect(lexer::token_type::end_object);
11472 get_token();
11473 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
11474 {
11475 result = basic_json(value_t::discarded);
11476 }
11477
11478 return result;
11479 }
11480
11481 case lexer::token_type::begin_array:
11482 {
11483 if (keep and (not callback
11484 or ((keep = callback(depth++, parse_event_t::array_start, result)) != 0)))
11485 {
11486 // explicitly set result to object to cope with []
11487 result.m_type = value_t::array;
11488 result.m_value = value_t::array;
11489 }
11490
11491 // read next token
11492 get_token();
11493
11494 // closing ] -> we are done
11495 if (last_token == lexer::token_type::end_array)
11496 {
11497 get_token();
11498 if (callback and not callback(--depth, parse_event_t::array_end, result))
11499 {
11500 result = basic_json(value_t::discarded);
11501 }
11502 return result;
11503 }
11504
11505 // no comma is expected here
11506 unexpect(lexer::token_type::value_separator);
11507
11508 // otherwise: parse values
11509 do
11510 {
11511 // ugly, but could be fixed with loop reorganization
11512 if (last_token == lexer::token_type::value_separator)
11513 {
11514 get_token();
11515 }
11516
11517 // parse value
11518 auto value = parse_internal(keep);
11519 if (keep and not value.is_discarded())
11520 {
11521 result.push_back(std::move(value));
11522 }
11523 }
11524 while (last_token == lexer::token_type::value_separator);
11525
11526 // closing ]
11527 expect(lexer::token_type::end_array);
11528 get_token();
11529 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
11530 {
11531 result = basic_json(value_t::discarded);
11532 }
11533
11534 return result;
11535 }
11536
11537 case lexer::token_type::literal_null:
11538 {
11539 get_token();
11540 result.m_type = value_t::null;
11541 break;
11542 }
11543
11544 case lexer::token_type::value_string:
11545 {
11546 const auto s = m_lexer.get_string();
11547 get_token();
11548 result = basic_json(s);
11549 break;
11550 }
11551
11552 case lexer::token_type::literal_true:
11553 {
11554 get_token();
11555 result.m_type = value_t::boolean;
11556 result.m_value = true;
11557 break;
11558 }
11559
11560 case lexer::token_type::literal_false:
11561 {
11562 get_token();
11563 result.m_type = value_t::boolean;
11564 result.m_value = false;
11565 break;
11566 }
11567
11568 case lexer::token_type::value_unsigned:
11569 case lexer::token_type::value_integer:
11570 case lexer::token_type::value_float:
11571 {
11572 m_lexer.get_number(result, last_token);
11573 get_token();
11574 break;
11575 }
11576
11577 default:
11578 {
11579 // the last token was unexpected
11580 unexpect(last_token);
11581 }
11582 }
11583
11584 if (keep and callback and not callback(depth, parse_event_t::value, result))
11585 {
11586 result = basic_json(value_t::discarded);
11587 }
11588 return result;
11589 }
11590
11591 /// get next token from lexer
11593 {
11594 last_token = m_lexer.scan();
11595 return last_token;
11596 }
11597
11598 void expect(typename lexer::token_type t) const
11599 {
11600 if (t != last_token)
11601 {
11602 std::string error_msg = "parse error - unexpected ";
11603 error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
11604 "'") :
11605 lexer::token_type_name(last_token));
11606 error_msg += "; expected " + lexer::token_type_name(t);
11607 JSON_THROW(std::invalid_argument(error_msg));
11608 }
11609 }
11610
11611 void unexpect(typename lexer::token_type t) const
11612 {
11613 if (t == last_token)
11614 {
11615 std::string error_msg = "parse error - unexpected ";
11616 error_msg += (last_token == lexer::token_type::parse_error ? ("'" + m_lexer.get_token_string() +
11617 "'") :
11618 lexer::token_type_name(last_token));
11619 JSON_THROW(std::invalid_argument(error_msg));
11620 }
11621 }
11622
11623 private:
11624 /// current level of recursion
11625 int depth = 0;
11626 /// callback function
11627 const parser_callback_t callback = nullptr;
11628 /// the type of the last read token
11629 typename lexer::token_type last_token = lexer::token_type::uninitialized;
11630 /// the lexer
11632 };
11633
11634 public:
11635 /*!
11636 @brief JSON Pointer
11637
11638 A JSON pointer defines a string syntax for identifying a specific value
11639 within a JSON document. It can be used with functions `at` and
11640 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
11641
11642 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
11643
11644 @since version 2.0.0
11645 */
11647 {
11648 /// allow basic_json to access private members
11649 friend class basic_json;
11650
11651 public:
11652 /*!
11653 @brief create JSON pointer
11654
11655 Create a JSON pointer according to the syntax described in
11656 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
11657
11658 @param[in] s string representing the JSON pointer; if omitted, the
11659 empty string is assumed which references the whole JSON
11660 value
11661
11662 @throw std::domain_error if reference token is nonempty and does not
11663 begin with a slash (`/`); example: `"JSON pointer must be empty or
11664 begin with /"`
11665 @throw std::domain_error if a tilde (`~`) is not followed by `0`
11666 (representing `~`) or `1` (representing `/`); example: `"escape error:
11667 ~ must be followed with 0 or 1"`
11668
11669 @liveexample{The example shows the construction several valid JSON
11670 pointers as well as the exceptional behavior.,json_pointer}
11671
11672 @since version 2.0.0
11673 */
11674 explicit json_pointer(const std::string& s = "")
11675 : reference_tokens(split(s))
11676 {}
11677
11678 /*!
11679 @brief return a string representation of the JSON pointer
11680
11681 @invariant For each JSON pointer `ptr`, it holds:
11682 @code {.cpp}
11683 ptr == json_pointer(ptr.to_string());
11684 @endcode
11685
11686 @return a string representation of the JSON pointer
11687
11688 @liveexample{The example shows the result of `to_string`.,
11689 json_pointer__to_string}
11690
11691 @since version 2.0.0
11692 */
11693 std::string to_string() const noexcept
11694 {
11695 return std::accumulate(reference_tokens.begin(),
11696 reference_tokens.end(), std::string{},
11697 [](const std::string & a, const std::string & b)
11698 {
11699 return a + "/" + escape(b);
11700 });
11701 }
11702
11703 /// @copydoc to_string()
11704 operator std::string() const
11705 {
11706 return to_string();
11707 }
11708
11709 private:
11710 /// remove and return last reference pointer
11711 std::string pop_back()
11712 {
11713 if (is_root())
11714 {
11715 JSON_THROW(std::domain_error("JSON pointer has no parent"));
11716 }
11717
11718 auto last = reference_tokens.back();
11719 reference_tokens.pop_back();
11720 return last;
11721 }
11722
11723 /// return whether pointer points to the root document
11724 bool is_root() const
11725 {
11726 return reference_tokens.empty();
11727 }
11728
11730 {
11731 if (is_root())
11732 {
11733 JSON_THROW(std::domain_error("JSON pointer has no parent"));
11734 }
11735
11736 json_pointer result = *this;
11737 result.reference_tokens = {reference_tokens[0]};
11738 return result;
11739 }
11740
11741 /*!
11742 @brief create and return a reference to the pointed to value
11743
11744 @complexity Linear in the number of reference tokens.
11745 */
11747 {
11748 pointer result = &j;
11749
11750 // in case no reference tokens exist, return a reference to the
11751 // JSON value j which will be overwritten by a primitive value
11752 for (const auto& reference_token : reference_tokens)
11753 {
11754 switch (result->m_type)
11755 {
11756 case value_t::null:
11757 {
11758 if (reference_token == "0")
11759 {
11760 // start a new array if reference token is 0
11761 result = &result->operator[](0);
11762 }
11763 else
11764 {
11765 // start a new object otherwise
11766 result = &result->operator[](reference_token);
11767 }
11768 break;
11769 }
11770
11771 case value_t::object:
11772 {
11773 // create an entry in the object
11774 result = &result->operator[](reference_token);
11775 break;
11776 }
11777
11778 case value_t::array:
11779 {
11780 // create an entry in the array
11781 result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
11782 break;
11783 }
11784
11785 /*
11786 The following code is only reached if there exists a
11787 reference token _and_ the current value is primitive. In
11788 this case, we have an error situation, because primitive
11789 values may only occur as single value; that is, with an
11790 empty list of reference tokens.
11791 */
11792 default:
11793 {
11794 JSON_THROW(std::domain_error("invalid value to unflatten"));
11795 }
11796 }
11797 }
11798
11799 return *result;
11800 }
11801
11802 /*!
11803 @brief return a reference to the pointed to value
11804
11805 @note This version does not throw if a value is not present, but tries
11806 to create nested values instead. For instance, calling this function
11807 with pointer `"/this/that"` on a null value is equivalent to calling
11808 `operator[]("this").operator[]("that")` on that value, effectively
11809 changing the null value to an object.
11810
11811 @param[in] ptr a JSON value
11812
11813 @return reference to the JSON value pointed to by the JSON pointer
11814
11815 @complexity Linear in the length of the JSON pointer.
11816
11817 @throw std::out_of_range if the JSON pointer can not be resolved
11818 @throw std::domain_error if an array index begins with '0'
11819 @throw std::invalid_argument if an array index was not a number
11820 */
11822 {
11823 for (const auto& reference_token : reference_tokens)
11824 {
11825 // convert null values to arrays or objects before continuing
11826 if (ptr->m_type == value_t::null)
11827 {
11828 // check if reference token is a number
11829 const bool nums = std::all_of(reference_token.begin(),
11830 reference_token.end(),
11831 [](const char x)
11832 {
11833 return std::isdigit(x);
11834 });
11835
11836 // change value to array for numbers or "-" or to object
11837 // otherwise
11838 if (nums or reference_token == "-")
11839 {
11840 *ptr = value_t::array;
11841 }
11842 else
11843 {
11844 *ptr = value_t::object;
11845 }
11846 }
11847
11848 switch (ptr->m_type)
11849 {
11850 case value_t::object:
11851 {
11852 // use unchecked object access
11853 ptr = &ptr->operator[](reference_token);
11854 break;
11855 }
11856
11857 case value_t::array:
11858 {
11859 // error condition (cf. RFC 6901, Sect. 4)
11860 if (reference_token.size() > 1 and reference_token[0] == '0')
11861 {
11862 JSON_THROW(std::domain_error("array index must not begin with '0'"));
11863 }
11864
11865 if (reference_token == "-")
11866 {
11867 // explicitly treat "-" as index beyond the end
11868 ptr = &ptr->operator[](ptr->m_value.array->size());
11869 }
11870 else
11871 {
11872 // convert array index to number; unchecked access
11873 ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
11874 }
11875 break;
11876 }
11877
11878 default:
11879 {
11880 JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
11881 }
11882 }
11883 }
11884
11885 return *ptr;
11886 }
11887
11889 {
11890 for (const auto& reference_token : reference_tokens)
11891 {
11892 switch (ptr->m_type)
11893 {
11894 case value_t::object:
11895 {
11896 // note: at performs range check
11897 ptr = &ptr->at(reference_token);
11898 break;
11899 }
11900
11901 case value_t::array:
11902 {
11903 if (reference_token == "-")
11904 {
11905 // "-" always fails the range check
11906 JSON_THROW(std::out_of_range("array index '-' (" +
11907 std::to_string(ptr->m_value.array->size()) +
11908 ") is out of range"));
11909 }
11910
11911 // error condition (cf. RFC 6901, Sect. 4)
11912 if (reference_token.size() > 1 and reference_token[0] == '0')
11913 {
11914 JSON_THROW(std::domain_error("array index must not begin with '0'"));
11915 }
11916
11917 // note: at performs range check
11918 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
11919 break;
11920 }
11921
11922 default:
11923 {
11924 JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
11925 }
11926 }
11927 }
11928
11929 return *ptr;
11930 }
11931
11932 /*!
11933 @brief return a const reference to the pointed to value
11934
11935 @param[in] ptr a JSON value
11936
11937 @return const reference to the JSON value pointed to by the JSON
11938 pointer
11939 */
11941 {
11942 for (const auto& reference_token : reference_tokens)
11943 {
11944 switch (ptr->m_type)
11945 {
11946 case value_t::object:
11947 {
11948 // use unchecked object access
11949 ptr = &ptr->operator[](reference_token);
11950 break;
11951 }
11952
11953 case value_t::array:
11954 {
11955 if (reference_token == "-")
11956 {
11957 // "-" cannot be used for const access
11958 JSON_THROW(std::out_of_range("array index '-' (" +
11959 std::to_string(ptr->m_value.array->size()) +
11960 ") is out of range"));
11961 }
11962
11963 // error condition (cf. RFC 6901, Sect. 4)
11964 if (reference_token.size() > 1 and reference_token[0] == '0')
11965 {
11966 JSON_THROW(std::domain_error("array index must not begin with '0'"));
11967 }
11968
11969 // use unchecked array access
11970 ptr = &ptr->operator[](static_cast<size_type>(std::stoi(reference_token)));
11971 break;
11972 }
11973
11974 default:
11975 {
11976 JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
11977 }
11978 }
11979 }
11980
11981 return *ptr;
11982 }
11983
11985 {
11986 for (const auto& reference_token : reference_tokens)
11987 {
11988 switch (ptr->m_type)
11989 {
11990 case value_t::object:
11991 {
11992 // note: at performs range check
11993 ptr = &ptr->at(reference_token);
11994 break;
11995 }
11996
11997 case value_t::array:
11998 {
11999 if (reference_token == "-")
12000 {
12001 // "-" always fails the range check
12002 JSON_THROW(std::out_of_range("array index '-' (" +
12003 std::to_string(ptr->m_value.array->size()) +
12004 ") is out of range"));
12005 }
12006
12007 // error condition (cf. RFC 6901, Sect. 4)
12008 if (reference_token.size() > 1 and reference_token[0] == '0')
12009 {
12010 JSON_THROW(std::domain_error("array index must not begin with '0'"));
12011 }
12012
12013 // note: at performs range check
12014 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
12015 break;
12016 }
12017
12018 default:
12019 {
12020 JSON_THROW(std::out_of_range("unresolved reference token '" + reference_token + "'"));
12021 }
12022 }
12023 }
12024
12025 return *ptr;
12026 }
12027
12028 /// split the string input to reference tokens
12029 static std::vector<std::string> split(const std::string& reference_string)
12030 {
12031 std::vector<std::string> result;
12032
12033 // special case: empty reference string -> no reference tokens
12034 if (reference_string.empty())
12035 {
12036 return result;
12037 }
12038
12039 // check if nonempty reference string begins with slash
12040 if (reference_string[0] != '/')
12041 {
12042 JSON_THROW(std::domain_error("JSON pointer must be empty or begin with '/'"));
12043 }
12044
12045 // extract the reference tokens:
12046 // - slash: position of the last read slash (or end of string)
12047 // - start: position after the previous slash
12048 for (
12049 // search for the first slash after the first character
12050 size_t slash = reference_string.find_first_of('/', 1),
12051 // set the beginning of the first reference token
12052 start = 1;
12053 // we can stop if start == string::npos+1 = 0
12054 start != 0;
12055 // set the beginning of the next reference token
12056 // (will eventually be 0 if slash == std::string::npos)
12057 start = slash + 1,
12058 // find next slash
12059 slash = reference_string.find_first_of('/', start))
12060 {
12061 // use the text between the beginning of the reference token
12062 // (start) and the last slash (slash).
12063 auto reference_token = reference_string.substr(start, slash - start);
12064
12065 // check reference tokens are properly escaped
12066 for (size_t pos = reference_token.find_first_of('~');
12067 pos != std::string::npos;
12068 pos = reference_token.find_first_of('~', pos + 1))
12069 {
12070 assert(reference_token[pos] == '~');
12071
12072 // ~ must be followed by 0 or 1
12073 if (pos == reference_token.size() - 1 or
12074 (reference_token[pos + 1] != '0' and
12075 reference_token[pos + 1] != '1'))
12076 {
12077 JSON_THROW(std::domain_error("escape error: '~' must be followed with '0' or '1'"));
12078 }
12079 }
12080
12081 // finally, store the reference token
12082 unescape(reference_token);
12083 result.push_back(reference_token);
12084 }
12085
12086 return result;
12087 }
12088
12089 private:
12090 /*!
12091 @brief replace all occurrences of a substring by another string
12092
12093 @param[in,out] s the string to manipulate; changed so that all
12094 occurrences of @a f are replaced with @a t
12095 @param[in] f the substring to replace with @a t
12096 @param[in] t the string to replace @a f
12097
12098 @pre The search string @a f must not be empty.
12099
12100 @since version 2.0.0
12101 */
12102 static void replace_substring(std::string& s,
12103 const std::string& f,
12104 const std::string& t)
12105 {
12106 assert(not f.empty());
12107
12108 for (
12109 size_t pos = s.find(f); // find first occurrence of f
12110 pos != std::string::npos; // make sure f was found
12111 s.replace(pos, f.size(), t), // replace with t
12112 pos = s.find(f, pos + t.size()) // find next occurrence of f
12113 );
12114 }
12115
12116 /// escape tilde and slash
12117 static std::string escape(std::string s)
12118 {
12119 // escape "~"" to "~0" and "/" to "~1"
12120 replace_substring(s, "~", "~0");
12121 replace_substring(s, "/", "~1");
12122 return s;
12123 }
12124
12125 /// unescape tilde and slash
12126 static void unescape(std::string& s)
12127 {
12128 // first transform any occurrence of the sequence '~1' to '/'
12129 replace_substring(s, "~1", "/");
12130 // then transform any occurrence of the sequence '~0' to '~'
12131 replace_substring(s, "~0", "~");
12132 }
12133
12134 /*!
12135 @param[in] reference_string the reference string to the current value
12136 @param[in] value the value to consider
12137 @param[in,out] result the result object to insert values to
12138
12139 @note Empty objects or arrays are flattened to `null`.
12140 */
12141 static void flatten(const std::string& reference_string,
12142 const basic_json& value,
12143 basic_json& result)
12144 {
12145 switch (value.m_type)
12146 {
12147 case value_t::array:
12148 {
12149 if (value.m_value.array->empty())
12150 {
12151 // flatten empty array as null
12152 result[reference_string] = nullptr;
12153 }
12154 else
12155 {
12156 // iterate array and use index as reference string
12157 for (size_t i = 0; i < value.m_value.array->size(); ++i)
12158 {
12159 flatten(reference_string + "/" + std::to_string(i),
12160 value.m_value.array->operator[](i), result);
12161 }
12162 }
12163 break;
12164 }
12165
12166 case value_t::object:
12167 {
12168 if (value.m_value.object->empty())
12169 {
12170 // flatten empty object as null
12171 result[reference_string] = nullptr;
12172 }
12173 else
12174 {
12175 // iterate object and use keys as reference string
12176 for (const auto& element : *value.m_value.object)
12177 {
12178 flatten(reference_string + "/" + escape(element.first),
12179 element.second, result);
12180 }
12181 }
12182 break;
12183 }
12184
12185 default:
12186 {
12187 // add primitive value with its reference string
12188 result[reference_string] = value;
12189 break;
12190 }
12191 }
12192 }
12193
12194 /*!
12195 @param[in] value flattened JSON
12196
12197 @return unflattened JSON
12198 */
12199 static basic_json unflatten(const basic_json& value)
12200 {
12201 if (not value.is_object())
12202 {
12203 JSON_THROW(std::domain_error("only objects can be unflattened"));
12204 }
12205
12206 basic_json result;
12207
12208 // iterate the JSON object values
12209 for (const auto& element : *value.m_value.object)
12210 {
12211 if (not element.second.is_primitive())
12212 {
12213 JSON_THROW(std::domain_error("values in object must be primitive"));
12214 }
12215
12216 // assign value to reference pointed to by JSON pointer; Note
12217 // that if the JSON pointer is "" (i.e., points to the whole
12218 // value), function get_and_create returns a reference to
12219 // result itself. An assignment will then create a primitive
12220 // value.
12221 json_pointer(element.first).get_and_create(result) = element.second;
12222 }
12223
12224 return result;
12225 }
12226
12227 private:
12228 friend bool operator==(json_pointer const& lhs,
12229 json_pointer const& rhs) noexcept
12230 {
12231 return lhs.reference_tokens == rhs.reference_tokens;
12232 }
12233
12234 friend bool operator!=(json_pointer const& lhs,
12235 json_pointer const& rhs) noexcept
12236 {
12237 return !(lhs == rhs);
12238 }
12239
12240 /// the reference tokens
12241 std::vector<std::string> reference_tokens {};
12242 };
12243
12244 //////////////////////////
12245 // JSON Pointer support //
12246 //////////////////////////
12247
12248 /// @name JSON Pointer functions
12249 /// @{
12250
12251 /*!
12252 @brief access specified element via JSON Pointer
12253
12254 Uses a JSON pointer to retrieve a reference to the respective JSON value.
12255 No bound checking is performed. Similar to @ref operator[](const typename
12256 object_t::key_type&), `null` values are created in arrays and objects if
12257 necessary.
12258
12259 In particular:
12260 - If the JSON pointer points to an object key that does not exist, it
12261 is created an filled with a `null` value before a reference to it
12262 is returned.
12263 - If the JSON pointer points to an array index that does not exist, it
12264 is created an filled with a `null` value before a reference to it
12265 is returned. All indices between the current maximum and the given
12266 index are also filled with `null`.
12267 - The special value `-` is treated as a synonym for the index past the
12268 end.
12269
12270 @param[in] ptr a JSON pointer
12271
12272 @return reference to the element pointed to by @a ptr
12273
12274 @complexity Constant.
12275
12276 @throw std::out_of_range if the JSON pointer can not be resolved
12277 @throw std::domain_error if an array index begins with '0'
12278 @throw std::invalid_argument if an array index was not a number
12279
12280 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
12281
12282 @since version 2.0.0
12283 */
12285 {
12286 return ptr.get_unchecked(this);
12287 }
12288
12289 /*!
12290 @brief access specified element via JSON Pointer
12291
12292 Uses a JSON pointer to retrieve a reference to the respective JSON value.
12293 No bound checking is performed. The function does not change the JSON
12294 value; no `null` values are created. In particular, the the special value
12295 `-` yields an exception.
12296
12297 @param[in] ptr JSON pointer to the desired element
12298
12299 @return const reference to the element pointed to by @a ptr
12300
12301 @complexity Constant.
12302
12303 @throw std::out_of_range if the JSON pointer can not be resolved
12304 @throw std::domain_error if an array index begins with '0'
12305 @throw std::invalid_argument if an array index was not a number
12306
12307 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
12308
12309 @since version 2.0.0
12310 */
12312 {
12313 return ptr.get_unchecked(this);
12314 }
12315
12316 /*!
12317 @brief access specified element via JSON Pointer
12318
12319 Returns a reference to the element at with specified JSON pointer @a ptr,
12320 with bounds checking.
12321
12322 @param[in] ptr JSON pointer to the desired element
12323
12324 @return reference to the element pointed to by @a ptr
12325
12326 @complexity Constant.
12327
12328 @throw std::out_of_range if the JSON pointer can not be resolved
12329 @throw std::domain_error if an array index begins with '0'
12330 @throw std::invalid_argument if an array index was not a number
12331
12332 @liveexample{The behavior is shown in the example.,at_json_pointer}
12333
12334 @since version 2.0.0
12335 */
12337 {
12338 return ptr.get_checked(this);
12339 }
12340
12341 /*!
12342 @brief access specified element via JSON Pointer
12343
12344 Returns a const reference to the element at with specified JSON pointer @a
12345 ptr, with bounds checking.
12346
12347 @param[in] ptr JSON pointer to the desired element
12348
12349 @return reference to the element pointed to by @a ptr
12350
12351 @complexity Constant.
12352
12353 @throw std::out_of_range if the JSON pointer can not be resolved
12354 @throw std::domain_error if an array index begins with '0'
12355 @throw std::invalid_argument if an array index was not a number
12356
12357 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
12358
12359 @since version 2.0.0
12360 */
12362 {
12363 return ptr.get_checked(this);
12364 }
12365
12366 /*!
12367 @brief return flattened JSON value
12368
12369 The function creates a JSON object whose keys are JSON pointers (see [RFC
12370 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
12371 primitive. The original JSON value can be restored using the @ref
12372 unflatten() function.
12373
12374 @return an object that maps JSON pointers to primitive values
12375
12376 @note Empty objects and arrays are flattened to `null` and will not be
12377 reconstructed correctly by the @ref unflatten() function.
12378
12379 @complexity Linear in the size the JSON value.
12380
12381 @liveexample{The following code shows how a JSON object is flattened to an
12382 object whose keys consist of JSON pointers.,flatten}
12383
12384 @sa @ref unflatten() for the reverse function
12385
12386 @since version 2.0.0
12387 */
12389 {
12390 basic_json result(value_t::object);
12391 json_pointer::flatten("", *this, result);
12392 return result;
12393 }
12394
12395 /*!
12396 @brief unflatten a previously flattened JSON value
12397
12398 The function restores the arbitrary nesting of a JSON value that has been
12399 flattened before using the @ref flatten() function. The JSON value must
12400 meet certain constraints:
12401 1. The value must be an object.
12402 2. The keys must be JSON pointers (see
12403 [RFC 6901](https://tools.ietf.org/html/rfc6901))
12404 3. The mapped values must be primitive JSON types.
12405
12406 @return the original JSON from a flattened version
12407
12408 @note Empty objects and arrays are flattened by @ref flatten() to `null`
12409 values and can not unflattened to their original type. Apart from
12410 this example, for a JSON value `j`, the following is always true:
12411 `j == j.flatten().unflatten()`.
12412
12413 @complexity Linear in the size the JSON value.
12414
12415 @liveexample{The following code shows how a flattened JSON object is
12416 unflattened into the original nested JSON object.,unflatten}
12417
12418 @sa @ref flatten() for the reverse function
12419
12420 @since version 2.0.0
12421 */
12423 {
12424 return json_pointer::unflatten(*this);
12425 }
12426
12427 /// @}
12428
12429 //////////////////////////
12430 // JSON Patch functions //
12431 //////////////////////////
12432
12433 /// @name JSON Patch functions
12434 /// @{
12435
12436 /*!
12437 @brief applies a JSON patch
12438
12439 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
12440 expressing a sequence of operations to apply to a JSON) document. With
12441 this function, a JSON Patch is applied to the current JSON value by
12442 executing all operations from the patch.
12443
12444 @param[in] json_patch JSON patch document
12445 @return patched document
12446
12447 @note The application of a patch is atomic: Either all operations succeed
12448 and the patched document is returned or an exception is thrown. In
12449 any case, the original value is not changed: the patch is applied
12450 to a copy of the value.
12451
12452 @throw std::out_of_range if a JSON pointer inside the patch could not
12453 be resolved successfully in the current JSON value; example: `"key baz
12454 not found"`
12455 @throw invalid_argument if the JSON patch is malformed (e.g., mandatory
12456 attributes are missing); example: `"operation add must have member path"`
12457
12458 @complexity Linear in the size of the JSON value and the length of the
12459 JSON patch. As usually only a fraction of the JSON value is affected by
12460 the patch, the complexity can usually be neglected.
12461
12462 @liveexample{The following code shows how a JSON patch is applied to a
12463 value.,patch}
12464
12465 @sa @ref diff -- create a JSON patch by comparing two JSON values
12466
12467 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
12468 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
12469
12470 @since version 2.0.0
12471 */
12472 basic_json patch(const basic_json& json_patch) const
12473 {
12474 // make a working copy to apply the patch to
12475 basic_json result = *this;
12476
12477 // the valid JSON Patch operations
12478 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
12479
12480 const auto get_op = [](const std::string op)
12481 {
12482 if (op == "add")
12483 {
12484 return patch_operations::add;
12485 }
12486 if (op == "remove")
12487 {
12488 return patch_operations::remove;
12489 }
12490 if (op == "replace")
12491 {
12492 return patch_operations::replace;
12493 }
12494 if (op == "move")
12495 {
12496 return patch_operations::move;
12497 }
12498 if (op == "copy")
12499 {
12500 return patch_operations::copy;
12501 }
12502 if (op == "test")
12503 {
12504 return patch_operations::test;
12505 }
12506
12507 return patch_operations::invalid;
12508 };
12509
12510 // wrapper for "add" operation; add value at ptr
12511 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
12512 {
12513 // adding to the root of the target document means replacing it
12514 if (ptr.is_root())
12515 {
12516 result = val;
12517 }
12518 else
12519 {
12520 // make sure the top element of the pointer exists
12521 json_pointer top_pointer = ptr.top();
12522 if (top_pointer != ptr)
12523 {
12524 result.at(top_pointer);
12525 }
12526
12527 // get reference to parent of JSON pointer ptr
12528 const auto last_path = ptr.pop_back();
12529 basic_json& parent = result[ptr];
12530
12531 switch (parent.m_type)
12532 {
12533 case value_t::null:
12534 case value_t::object:
12535 {
12536 // use operator[] to add value
12537 parent[last_path] = val;
12538 break;
12539 }
12540
12541 case value_t::array:
12542 {
12543 if (last_path == "-")
12544 {
12545 // special case: append to back
12546 parent.push_back(val);
12547 }
12548 else
12549 {
12550 const auto idx = std::stoi(last_path);
12551 if (static_cast<size_type>(idx) > parent.size())
12552 {
12553 // avoid undefined behavior
12554 JSON_THROW(std::out_of_range("array index " + std::to_string(idx) + " is out of range"));
12555 }
12556 else
12557 {
12558 // default case: insert add offset
12559 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
12560 }
12561 }
12562 break;
12563 }
12564
12565 default:
12566 {
12567 // if there exists a parent it cannot be primitive
12568 assert(false); // LCOV_EXCL_LINE
12569 }
12570 }
12571 }
12572 };
12573
12574 // wrapper for "remove" operation; remove value at ptr
12575 const auto operation_remove = [&result](json_pointer & ptr)
12576 {
12577 // get reference to parent of JSON pointer ptr
12578 const auto last_path = ptr.pop_back();
12579 basic_json& parent = result.at(ptr);
12580
12581 // remove child
12582 if (parent.is_object())
12583 {
12584 // perform range check
12585 auto it = parent.find(last_path);
12586 if (it != parent.end())
12587 {
12588 parent.erase(it);
12589 }
12590 else
12591 {
12592 JSON_THROW(std::out_of_range("key '" + last_path + "' not found"));
12593 }
12594 }
12595 else if (parent.is_array())
12596 {
12597 // note erase performs range check
12598 parent.erase(static_cast<size_type>(std::stoi(last_path)));
12599 }
12600 };
12601
12602 // type check
12603 if (not json_patch.is_array())
12604 {
12605 // a JSON patch must be an array of objects
12606 JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
12607 }
12608
12609 // iterate and apply the operations
12610 for (const auto& val : json_patch)
12611 {
12612 // wrapper to get a value for an operation
12613 const auto get_value = [&val](const std::string & op,
12614 const std::string & member,
12615 bool string_type) -> basic_json&
12616 {
12617 // find value
12618 auto it = val.m_value.object->find(member);
12619
12620 // context-sensitive error message
12621 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
12622
12623 // check if desired value is present
12624 if (it == val.m_value.object->end())
12625 {
12626 JSON_THROW(std::invalid_argument(error_msg + " must have member '" + member + "'"));
12627 }
12628
12629 // check if result is of type string
12630 if (string_type and not it->second.is_string())
12631 {
12632 JSON_THROW(std::invalid_argument(error_msg + " must have string member '" + member + "'"));
12633 }
12634
12635 // no error: return value
12636 return it->second;
12637 };
12638
12639 // type check
12640 if (not val.is_object())
12641 {
12642 JSON_THROW(std::invalid_argument("JSON patch must be an array of objects"));
12643 }
12644
12645 // collect mandatory members
12646 const std::string op = get_value("op", "op", true);
12647 const std::string path = get_value(op, "path", true);
12648 json_pointer ptr(path);
12649
12650 switch (get_op(op))
12651 {
12652 case patch_operations::add:
12653 {
12654 operation_add(ptr, get_value("add", "value", false));
12655 break;
12656 }
12657
12658 case patch_operations::remove:
12659 {
12660 operation_remove(ptr);
12661 break;
12662 }
12663
12664 case patch_operations::replace:
12665 {
12666 // the "path" location must exist - use at()
12667 result.at(ptr) = get_value("replace", "value", false);
12668 break;
12669 }
12670
12671 case patch_operations::move:
12672 {
12673 const std::string from_path = get_value("move", "from", true);
12674 json_pointer from_ptr(from_path);
12675
12676 // the "from" location must exist - use at()
12677 basic_json v = result.at(from_ptr);
12678
12679 // The move operation is functionally identical to a
12680 // "remove" operation on the "from" location, followed
12681 // immediately by an "add" operation at the target
12682 // location with the value that was just removed.
12683 operation_remove(from_ptr);
12684 operation_add(ptr, v);
12685 break;
12686 }
12687
12688 case patch_operations::copy:
12689 {
12690 const std::string from_path = get_value("copy", "from", true);;
12691 const json_pointer from_ptr(from_path);
12692
12693 // the "from" location must exist - use at()
12694 result[ptr] = result.at(from_ptr);
12695 break;
12696 }
12697
12698 case patch_operations::test:
12699 {
12700 bool success = false;
12701 JSON_TRY
12702 {
12703 // check if "value" matches the one at "path"
12704 // the "path" location must exist - use at()
12705 success = (result.at(ptr) == get_value("test", "value", false));
12706 }
12707 JSON_CATCH (std::out_of_range&)
12708 {
12709 // ignore out of range errors: success remains false
12710 }
12711
12712 // throw an exception if test fails
12713 if (not success)
12714 {
12715 JSON_THROW(std::domain_error("unsuccessful: " + val.dump()));
12716 }
12717
12718 break;
12719 }
12720
12721 case patch_operations::invalid:
12722 {
12723 // op must be "add", "remove", "replace", "move", "copy", or
12724 // "test"
12725 JSON_THROW(std::invalid_argument("operation value '" + op + "' is invalid"));
12726 }
12727 }
12728 }
12729
12730 return result;
12731 }
12732
12733 /*!
12734 @brief creates a diff as a JSON patch
12735
12736 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
12737 be changed into the value @a target by calling @ref patch function.
12738
12739 @invariant For two JSON values @a source and @a target, the following code
12740 yields always `true`:
12741 @code {.cpp}
12742 source.patch(diff(source, target)) == target;
12743 @endcode
12744
12745 @note Currently, only `remove`, `add`, and `replace` operations are
12746 generated.
12747
12748 @param[in] source JSON value to compare from
12749 @param[in] target JSON value to compare against
12750 @param[in] path helper value to create JSON pointers
12751
12752 @return a JSON patch to convert the @a source to @a target
12753
12754 @complexity Linear in the lengths of @a source and @a target.
12755
12756 @liveexample{The following code shows how a JSON patch is created as a
12757 diff for two JSON values.,diff}
12758
12759 @sa @ref patch -- apply a JSON patch
12760
12761 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
12762
12763 @since version 2.0.0
12764 */
12765 static basic_json diff(const basic_json& source,
12766 const basic_json& target,
12767 const std::string& path = "")
12768 {
12769 // the patch
12770 basic_json result(value_t::array);
12771
12772 // if the values are the same, return empty patch
12773 if (source == target)
12774 {
12775 return result;
12776 }
12777
12778 if (source.type() != target.type())
12779 {
12780 // different types: replace value
12781 result.push_back(
12782 {
12783 {"op", "replace"},
12784 {"path", path},
12785 {"value", target}
12786 });
12787 }
12788 else
12789 {
12790 switch (source.type())
12791 {
12792 case value_t::array:
12793 {
12794 // first pass: traverse common elements
12795 size_t i = 0;
12796 while (i < source.size() and i < target.size())
12797 {
12798 // recursive call to compare array values at index i
12799 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
12800 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
12801 ++i;
12802 }
12803
12804 // i now reached the end of at least one array
12805 // in a second pass, traverse the remaining elements
12806
12807 // remove my remaining elements
12808 const auto end_index = static_cast<difference_type>(result.size());
12809 while (i < source.size())
12810 {
12811 // add operations in reverse order to avoid invalid
12812 // indices
12813 result.insert(result.begin() + end_index, object(
12814 {
12815 {"op", "remove"},
12816 {"path", path + "/" + std::to_string(i)}
12817 }));
12818 ++i;
12819 }
12820
12821 // add other remaining elements
12822 while (i < target.size())
12823 {
12824 result.push_back(
12825 {
12826 {"op", "add"},
12827 {"path", path + "/" + std::to_string(i)},
12828 {"value", target[i]}
12829 });
12830 ++i;
12831 }
12832
12833 break;
12834 }
12835
12836 case value_t::object:
12837 {
12838 // first pass: traverse this object's elements
12839 for (auto it = source.begin(); it != source.end(); ++it)
12840 {
12841 // escape the key name to be used in a JSON patch
12842 const auto key = json_pointer::escape(it.key());
12843
12844 if (target.find(it.key()) != target.end())
12845 {
12846 // recursive call to compare object values at key it
12847 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
12848 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
12849 }
12850 else
12851 {
12852 // found a key that is not in o -> remove it
12853 result.push_back(object(
12854 {
12855 {"op", "remove"},
12856 {"path", path + "/" + key}
12857 }));
12858 }
12859 }
12860
12861 // second pass: traverse other object's elements
12862 for (auto it = target.begin(); it != target.end(); ++it)
12863 {
12864 if (source.find(it.key()) == source.end())
12865 {
12866 // found a key that is not in this -> add it
12867 const auto key = json_pointer::escape(it.key());
12868 result.push_back(
12869 {
12870 {"op", "add"},
12871 {"path", path + "/" + key},
12872 {"value", it.value()}
12873 });
12874 }
12875 }
12876
12877 break;
12878 }
12879
12880 default:
12881 {
12882 // both primitive type: replace value
12883 result.push_back(
12884 {
12885 {"op", "replace"},
12886 {"path", path},
12887 {"value", target}
12888 });
12889 break;
12890 }
12891 }
12892 }
12893
12894 return result;
12895 }
12896
12897 /// @}
12898};
12899
12900/////////////
12901// presets //
12902/////////////
12903
12904/*!
12905@brief default JSON class
12906
12907This type is the default specialization of the @ref basic_json class which
12908uses the standard template types.
12909
12910@since version 1.0.0
12911*/
12913} // namespace nlohmann
12914
12915
12916///////////////////////
12917// nonmember support //
12918///////////////////////
12919
12920// specialization of std::swap, and std::hash
12921namespace std
12922{
12923/*!
12924@brief exchanges the values of two JSON objects
12925
12926@since version 1.0.0
12927*/
12928template<>
12929inline void swap(nlohmann::json& j1,
12930 nlohmann::json& j2) noexcept(
12931 is_nothrow_move_constructible<nlohmann::json>::value and
12932 is_nothrow_move_assignable<nlohmann::json>::value
12933 )
12934{
12935 j1.swap(j2);
12936}
12937
12938/// hash value for JSON objects
12939template<>
12940struct hash<nlohmann::json>
12941{
12942 /*!
12943 @brief return a hash value for a JSON object
12944
12945 @since version 1.0.0
12946 */
12947 std::size_t operator()(const nlohmann::json& j) const
12948 {
12949 // a naive hashing via the string representation
12950 const auto& h = hash<nlohmann::json::string_t>();
12951 return h(j.dump());
12952 }
12953};
12954} // namespace std
12955
12956/*!
12957@brief user-defined string literal for JSON values
12958
12959This operator implements a user-defined string literal for JSON objects. It
12960can be used by adding `"_json"` to a string literal and returns a JSON object
12961if no parse error occurred.
12962
12963@param[in] s a string representation of a JSON object
12964@param[in] n the length of string @a s
12965@return a JSON object
12966
12967@since version 1.0.0
12968*/
12969inline nlohmann::json operator "" _json(const char* s, std::size_t n)
12970{
12971 return nlohmann::json::parse(s, s + n);
12972}
12973
12974/*!
12975@brief user-defined string literal for JSON pointer
12976
12977This operator implements a user-defined string literal for JSON Pointers. It
12978can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
12979object if no parse error occurred.
12980
12981@param[in] s a string representation of a JSON Pointer
12982@param[in] n the length of string @a s
12983@return a JSON pointer object
12984
12985@since version 2.0.0
12986*/
12987inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
12988{
12989 return nlohmann::json::json_pointer(std::string(s, n));
12990}
12991
12992// restore GCC/clang diagnostic settings
12993#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
12994 #pragma GCC diagnostic pop
12995#endif
12996
12997// clean up
12998#undef JSON_CATCH
12999#undef JSON_DEPRECATED
13000#undef JSON_THROW
13001#undef JSON_TRY
13002
13003#endif
SVector< double, 2 > v
Definition: Dict.h:5
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
static Int_t init()
Bool_t operator<=(const TDatime &d1, const TDatime &d2)
Definition: TDatime.h:108
Bool_t operator!=(const TDatime &d1, const TDatime &d2)
Definition: TDatime.h:104
Bool_t operator==(const TDatime &d1, const TDatime &d2)
Definition: TDatime.h:102
#define N
int type
Definition: TGX11.cxx:120
double ldexp(double, int)
double exp(double)
TString operator+(const TString &s1, const TString &s2)
Use the special concatenation constructor.
Definition: TString.cxx:1449
std::string & operator+=(std::string &left, const TString &right)
Definition: TString.h:473
typedef void((*Func_t)())
TTime operator*(const TTime &t1, const TTime &t2)
Definition: TTime.h:85
#define snprintf
Definition: civetweb.c:1540
a template for a random access iterator for the basic_json class
Definition: json.hpp:8838
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:9406
iter_impl operator--(int)
post-decrement (it–)
Definition: json.hpp:9135
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:9311
internal_iterator m_it
the actual iterator of the associated instance
Definition: json.hpp:9431
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:8988
pointer m_object
associated JSON instance
Definition: json.hpp:9429
iter_impl operator+(difference_type i)
add to iterator
Definition: json.hpp:9320
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:9146
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:9342
typename std::conditional< std::is_const< U >::value, typename basic_json::const_pointer, typename basic_json::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:8855
iter_impl()=default
default constructor
typename basic_json::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:8849
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:9271
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:9253
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:9220
iter_impl operator++(int)
post-increment (it++)
Definition: json.hpp:9092
void set_begin() noexcept
set the iterator to the first value
Definition: json.hpp:8951
iter_impl operator-(difference_type i)
subtract from iterator
Definition: json.hpp:9331
reference value() const
return the value of an iterator
Definition: json.hpp:9422
iter_impl(const iter_impl &other) noexcept
copy constructor
Definition: json.hpp:8925
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:9103
typename basic_json::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:8851
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.hpp:8872
iter_impl & operator=(iter_impl other) noexcept(std::is_nothrow_move_constructible< pointer >::value and std::is_nothrow_move_assignable< pointer >::value and std::is_nothrow_move_constructible< internal_iterator >::value and std::is_nothrow_move_assignable< internal_iterator >::value)
copy assignment
Definition: json.hpp:8934
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:9369
std::bidirectional_iterator_tag iterator_category
the category of the iterator
Definition: json.hpp:8861
typename std::conditional< std::is_const< U >::value, typename basic_json::const_reference, typename basic_json::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:8859
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:9019
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:9262
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:9280
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.hpp:9178
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.hpp:9211
pointer operator->() const
dereference the iterator
Definition: json.hpp:9058
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:8788
iteration_proxy_internal & operator*()
dereference operator (needed for range-based for)
Definition: json.hpp:8740
basic_json::string_t key() const
return key of the iterator
Definition: json.hpp:8761
iteration_proxy_internal & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:8746
proxy class for the iterator_wrapper functions
Definition: json.hpp:8723
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:8810
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:8804
IteratorType::reference container
the container to iterate
Definition: json.hpp:8795
iteration_proxy(typename IteratorType::reference cont)
construct iteration proxy from a container
Definition: json.hpp:8799
std::vector< std::string > reference_tokens
the reference tokens
Definition: json.hpp:12241
const_reference get_checked(const_pointer ptr) const
Definition: json.hpp:11984
reference get_unchecked(pointer ptr) const
return a reference to the pointed to value
Definition: json.hpp:11821
static void unescape(std::string &s)
unescape tilde and slash
Definition: json.hpp:12126
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:12228
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.hpp:12234
static std::string escape(std::string s)
escape tilde and slash
Definition: json.hpp:12117
static basic_json unflatten(const basic_json &value)
Definition: json.hpp:12199
json_pointer top() const
Definition: json.hpp:11729
bool is_root() const
return whether pointer points to the root document
Definition: json.hpp:11724
const_reference get_unchecked(const_pointer ptr) const
return a const reference to the pointed to value
Definition: json.hpp:11940
reference get_and_create(reference j) const
create and return a reference to the pointed to value
Definition: json.hpp:11746
reference get_checked(pointer ptr) const
Definition: json.hpp:11888
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11674
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: json.hpp:12029
std::string pop_back()
remove and return last reference pointer
Definition: json.hpp:11711
static void flatten(const std::string &reference_string, const basic_json &value, basic_json &result)
Definition: json.hpp:12141
std::string to_string() const noexcept
return a string representation of the JSON pointer
Definition: json.hpp:11693
static void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition: json.hpp:12102
a template for a reverse iterator class
Definition: json.hpp:9453
json_reverse_iterator operator++(int)
post-increment (it++)
Definition: json.hpp:9471
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:9461
object_t::key_type key() const
return the key of an object iterator
Definition: json.hpp:9532
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:9520
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:9477
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adaptor
Definition: json.hpp:9456
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:9490
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:9504
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:9512
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:9497
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:9458
json_reverse_iterator operator--(int)
post-decrement (it–)
Definition: json.hpp:9484
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:9466
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:9526
reference value() const
return the value of an iterator
Definition: json.hpp:9539
lexical analysis
Definition: json.hpp:9560
void fill_line_buffer(size_t n=0)
append data from the stream to the line buffer
Definition: json.hpp:10849
static std::string token_type_name(const token_type t)
return name of values of type token_type (only used for errors)
Definition: json.hpp:9710
bool get_number(basic_json &result, const token_type token) const
return number value for number tokens
Definition: json.hpp:11259
lexer(const lexer_char_t *buff, const size_t len) noexcept
a lexer from a buffer with given length
Definition: json.hpp:9587
lexer(const lexer &)=delete
token_type
token types for the parser
Definition: json.hpp:9564
token_type scan()
This function implements a scanner for JSON.
Definition: json.hpp:9773
lexer(std::istream &s)
a lexer from an input stream
Definition: json.hpp:9596
unsigned char lexer_char_t
the char type to use in the lexer
Definition: json.hpp:9584
static string_t to_unicode(const std::size_t codepoint1, const std::size_t codepoint2=0)
create a string from one or two Unicode code points
Definition: json.hpp:9645
string_t get_string() const
return string value for string tokens
Definition: json.hpp:10975
lexer operator=(const lexer &)=delete
string_t get_token_string() const
return string representation of last read token
Definition: json.hpp:10911
void unexpect(typename lexer::token_type t) const
Definition: json.hpp:11611
parser(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr)
a parser reading from an iterator range with contiguous storage
Definition: json.hpp:11372
parser(std::istream &is, const parser_callback_t cb=nullptr)
a parser reading from an input stream
Definition: json.hpp:11363
lexer m_lexer
the lexer
Definition: json.hpp:11631
basic_json parse_internal(bool keep)
the actual parser
Definition: json.hpp:11396
void expect(typename lexer::token_type t) const
Definition: json.hpp:11598
parser(const char *buff, const parser_callback_t cb=nullptr)
a parser reading from a string literal
Definition: json.hpp:11357
lexer::token_type get_token()
get next token from lexer
Definition: json.hpp:11592
basic_json parse()
public parser interface
Definition: json.hpp:11379
an iterator for primitive JSON types
Definition: json.hpp:8574
primitive_iterator_t operator+(difference_type i)
Definition: json.hpp:8635
primitive_iterator_t & operator-=(difference_type n)
Definition: json.hpp:8684
constexpr friend bool operator!=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:8610
constexpr friend bool operator<=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:8620
primitive_iterator_t & operator--()
Definition: json.hpp:8665
difference_type get_value() const noexcept
Definition: json.hpp:8577
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:8588
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:8594
friend std::ostream & operator<<(std::ostream &os, primitive_iterator_t it)
Definition: json.hpp:8647
primitive_iterator_t operator++(int)
Definition: json.hpp:8658
constexpr friend bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:8615
constexpr friend difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:8642
primitive_iterator_t operator--(int)
Definition: json.hpp:8671
constexpr friend bool operator>(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:8625
primitive_iterator_t & operator+=(difference_type n)
Definition: json.hpp:8678
difference_type m_it
iterator as signed integer type
Definition: json.hpp:8695
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:8600
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:8582
constexpr friend bool operator>=(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:8630
constexpr friend bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:8605
primitive_iterator_t & operator++()
Definition: json.hpp:8652
a class to store JSON values
Definition: json.hpp:1040
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:3061
reference back()
access the last element
Definition: json.hpp:4235
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:5540
static T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:1626
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:3132
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:4301
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:3037
reference operator+=(std::initializer_list< basic_json > init)
add an object to an object
Definition: json.hpp:5416
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:4670
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:5882
static T get_from_vector(const std::vector< uint8_t > &vec, const size_t current_index)
take sufficient bytes from a vector to fill an integer variable
Definition: json.hpp:6626
void assert_invariant() const
checks the class invariants
Definition: json.hpp:1785
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:4741
reference operator[](T *(&key)[n])
access specified object element
Definition: json.hpp:3887
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:3073
constexpr const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.hpp:3389
bool empty() const noexcept
checks whether the container is empty
Definition: json.hpp:4995
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:3109
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:4751
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:4885
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:5564
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:4811
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:3798
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:5063
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.hpp:4005
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:2681
basic_json value_type
the type of elements in a basic_json container
Definition: json.hpp:1067
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:2812
static basic_json from_msgpack_internal(const std::vector< uint8_t > &v, size_t &idx)
create a JSON value from a given MessagePack vector
Definition: json.hpp:7210
static void to_cbor_internal(const basic_json &j, std::vector< uint8_t > &v)
create a CBOR serialization of a given JSON value
Definition: json.hpp:6898
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:5129
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:4496
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:5593
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:2897
static basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr)
deserialize from an iterator range with contiguous storage
Definition: json.hpp:6412
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:1077
reference front()
access the first element
Definition: json.hpp:4192
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:3115
static basic_json parse(std::istream &&i, const parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:6361
static basic_json from_msgpack(const std::vector< uint8_t > &v, const size_t start_index=0)
create a JSON value from a byte vector in MessagePack format
Definition: json.hpp:7974
static void add_to_vector(std::vector< uint8_t > &vec, size_t bytes, const T number)
Definition: json.hpp:6546
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:5643
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:1072
~basic_json()
destructor
Definition: json.hpp:2575
constexpr const PointerType get() const noexcept
get a pointer value (explicit)
Definition: json.hpp:3327
static void check_length(const size_t size, const size_t len, const size_t offset)
Definition: json.hpp:7175
static basic_json array(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an array from an initializer list
Definition: json.hpp:2165
const_reference front() const
access the first element
Definition: json.hpp:4200
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:4408
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:1407
static basic_json parse(std::istream &i, const parser_callback_t cb=nullptr)
deserialize from stream
Definition: json.hpp:6352
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4680
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:4856
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:4819
size_type count(typename object_t::key_type key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:4630
string_t dump(const int indent=-1) const
serialization
Definition: json.hpp:2647
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:12765
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:3097
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:5492
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:4914
ValueType get() const noexcept(noexcept(JSONSerializer< ValueTypeCV >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.hpp:3278
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:6222
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:6141
StringType string_t
a type for a string
Definition: json.hpp:1381
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:2711
PointerType get() noexcept
get a pointer value (explicit)
Definition: json.hpp:3315
void swap(array_t &other)
exchanges the values
Definition: json.hpp:5770
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:2963
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:3085
basic_json get() const
get special-case overload
Definition: json.hpp:3173
std::string type_name() const
return the type as string
Definition: json.hpp:8065
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:3079
const_iterator find(typename object_t::key_type key) const
find an element in a JSON object
Definition: json.hpp:4597
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:5995
static basic_json parse(const ContiguousContainer &c, const parser_callback_t cb=nullptr)
deserialize from a container with contiguous storage
Definition: json.hpp:6484
static iteration_proxy< iterator > iterator_wrapper(reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:4935
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:1094
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:3531
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:12361
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:6185
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:12422
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:7941
JSON_DEPRECATED basic_json(std::istream &i, const parser_callback_t cb=nullptr)
construct a JSON value given an input stream
Definition: json.hpp:2396
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:2006
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:1055
static basic_json from_cbor_internal(const std::vector< uint8_t > &v, size_t &idx)
create a JSON value from a given CBOR vector
Definition: json.hpp:7448
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:12472
const_reference back() const
access the last element
Definition: json.hpp:4245
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:8004
string_t value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:4162
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:1080
static basic_json parse(T(&array)[N], const parser_callback_t cb=nullptr)
deserialize from an array
Definition: json.hpp:6284
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:6163
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:4531
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:1618
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:12336
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:5738
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:4781
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:2760
value_t m_type
the type of the current element
Definition: json.hpp:8553
static iteration_proxy< const_iterator > iterator_wrapper(const_reference cont)
wrapper to access iterator member functions in range-based for
Definition: json.hpp:4943
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:3621
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:2782
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:1479
basic_json(const value_t value_type_)
create an empty value with a given type
Definition: json.hpp:1916
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:3103
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:2505
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:3760
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:12311
static basic_json object(std::initializer_list< basic_json > init=std::initializer_list< basic_json >())
explicitly create an object from an initializer list
Definition: json.hpp:2205
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:2738
ObjectType< StringType, basic_json, std::less< StringType >, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:1282
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.hpp:3225
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:2990
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:6046
void emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:5444
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:6017
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:3574
const_reference operator[](T *(&key)[n]) const
read-only access specified object element
Definition: json.hpp:3922
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:3847
void push_back(std::initializer_list< basic_json > init)
add an object to an object
Definition: json.hpp:5399
static basic_json parse(const CharT s, const parser_callback_t cb=nullptr)
deserialize from string literal
Definition: json.hpp:6322
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:5294
static std::size_t extra_space(const string_t &s) noexcept
calculates the extra space to escape a JSON string
Definition: json.hpp:8097
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:3055
static basic_json from_cbor(const std::vector< uint8_t > &v, const size_t start_index=0)
create a JSON value from a byte vector in CBOR format
Definition: json.hpp:8037
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:2229
ValueType value(const json_pointer &ptr, ValueType default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:4139
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:12388
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:1550
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:5963
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:2841
reference operator[](T *key)
access specified object element
Definition: json.hpp:3955
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:2869
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:2276
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:5368
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:6241
void clear() noexcept
clears the contents
Definition: json.hpp:5185
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:1092
void swap(object_t &other)
exchanges the values
Definition: json.hpp:5803
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:3451
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:3026
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:12284
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:4848
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:3714
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:5258
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:3049
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:3668
iterator insert(const_iterator pos, std::initializer_list< basic_json > ilist)
inserts elements
Definition: json.hpp:5701
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:4091
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:4710
void swap(string_t &other)
exchanges the values
Definition: json.hpp:5836
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:5318
void dump(std::ostream &o, const bool pretty_print, const unsigned int indent_step, const unsigned int current_indent=0) const
internal implementation of the serialization function
Definition: json.hpp:8415
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:1328
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:5344
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:3043
detail::value_t value_t
Definition: json.hpp:1049
reference & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:2542
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:1940
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:6524
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:5284
parse_event_t
JSON callback events.
Definition: json.hpp:1808
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
json_value m_value
the value of the current element
Definition: json.hpp:8556
std::function< bool(int depth, parse_event_t event, basic_json &parsed)> parser_callback_t
per-element parser callback type
Definition: json.hpp:1877
iterator find(typename object_t::key_type key)
find an element in a JSON object
Definition: json.hpp:4581
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:5974
static basic_json meta()
returns version information on the library
Definition: json.hpp:1130
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:2941
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.hpp:3361
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:1083
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:1102
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:2428
static string_t escape_string(const string_t &s)
escape a string
Definition: json.hpp:8143
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.hpp:3091
static void to_msgpack_internal(const basic_json &j, std::vector< uint8_t > &v)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:6652
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:3067
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:2919
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:6514
ValueType value(const typename object_t::key_type &key, ValueType default_value) const
access specified object element with default value
Definition: json.hpp:4067
basic_json(std::initializer_list< basic_json > init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:2082
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:3438
basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer > basic_json_t
workaround type for MSVC
Definition: json.hpp:1046
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:1075
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:6006
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:1085
#define JSON_DEPRECATED
Definition: json.hpp:89
#define JSON_CATCH(exception)
Definition: json.hpp:100
#define JSON_THROW(exception)
Definition: json.hpp:98
#define JSON_TRY
Definition: json.hpp:99
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
double T(double x)
Definition: ChebyshevPol.h:34
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:151
static constexpr double s
null_t< F > null()
Definition: first.py:1
fill
Definition: fit1_py.py:6
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:202
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:171
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:528
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:205
void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b)
Definition: json.hpp:635
void to_json(BasicJsonType &j, const CompatibleObjectType &arr)
Definition: json.hpp:588
NLOHMANN_JSON_HAS_HELPER(mapped_type)
void from_json(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:799
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:604
value_t
the JSON type enumeration
Definition: json.hpp:150
@ number_integer
number value (signed integer)
@ discarded
discarded by the the parser callback function
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
std::integral_constant< bool, std::is_convertible< T, int >::value and std::is_enum< T >::value > is_unscoped_enum
Definition: json.hpp:211
void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag< 0 >)
Definition: json.hpp:715
namespace for Niels Lohmann
Definition: json.hpp:109
basic_json<> json
default JSON class
Definition: json.hpp:12912
STL namespace.
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value and is_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:12929
Definition: test.py:1
const char * cnt
Definition: TXMLSetup.cxx:74
TCanvas * slash()
Definition: slash.C:1
default JSONSerializer template argument
Definition: json.hpp:912
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
Definition: json.hpp:923
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
Definition: json.hpp:939
object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:8708
internal_iterator() noexcept
create an uninitialized internal_iterator
Definition: json.hpp:8715
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:8712
array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:8710
parse string into a built-in arithmetic type as if the current locale is POSIX.
Definition: json.hpp:11101
bool parse(T &value, std::false_type) const
Definition: json.hpp:11143
signed long long parse_integral(char **endptr, std::true_type) const
Definition: json.hpp:11209
bool parse(T &value, std::true_type) const
Definition: json.hpp:11220
static void strtof(long double &f, const char *str, char **endptr)
Definition: json.hpp:11137
unsigned long long parse_integral(char **endptr, std::false_type) const
Definition: json.hpp:11214
static void strtof(double &f, const char *str, char **endptr)
Definition: json.hpp:11132
static void strtof(float &f, const char *str, char **endptr)
Definition: json.hpp:11127
strtonum(const char *start, const char *end)
Definition: json.hpp:11103
locale-independent serialization for built-in arithmetic types
Definition: json.hpp:8255
const char * c_str() const
Definition: json.hpp:8263
void x_write(NumberType x, std::false_type)
Definition: json.hpp:8307
void x_write(NumberType x, std::true_type)
Definition: json.hpp:8273
numtostr(NumberType value)
Definition: json.hpp:8258
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:327
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:316
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:248
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:272
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:304
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:292
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:341
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:352
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:260
auto call(const BasicJsonType &j, T &val, priority_tag< 1 >) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void())
Definition: json.hpp:860
void operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(std::declval< from_json_fn >().call(j, val, priority_tag< 1 > {})))
Definition: json.hpp:876
void call(const BasicJsonType &, T &, priority_tag< 0 >) const noexcept
Definition: json.hpp:868
static constexpr bool value
Definition: json.hpp:484
static constexpr T value
Definition: json.hpp:887
void operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(std::declval< to_json_fn >().call(j, std::forward< T >(val), priority_tag< 1 > {})))
Definition: json.hpp:849
auto call(BasicJsonType &j, T &&val, priority_tag< 1 >) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:834
void call(BasicJsonType &, T &&, priority_tag< 0 >) const noexcept
Definition: json.hpp:841
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:12947
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:1680
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:1691
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:1770
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:1687
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:1695
json_value()=default
default constructor (for null values)
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:1693
object_t * object
object (stored with pointer to save storage)
Definition: json.hpp:1670
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:1689
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:1764
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:1672
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:1758
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:1674
number_float_t number_float
number (floating-point)
Definition: json.hpp:1682
number_integer_t number_integer
number (integer)
Definition: json.hpp:1678
boolean_t boolean
boolean
Definition: json.hpp:1676
unsigned char byte
Definition: gifdecode.c:10