WPILibC++ 2023.4.3
json.h
Go to the documentation of this file.
1/*----------------------------------------------------------------------------*/
2/* Modifications Copyright (c) 2017-2019 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7/*
8 __ _____ _____ _____
9 __| | __| | | | JSON for Modern C++
10| | |__ | | | | | | version 3.1.2
11|_____|_____|_____|_|___| https://github.com/nlohmann/json
12
13Licensed under the MIT License <http://opensource.org/licenses/MIT>.
14Copyright (c) 2013-2018 Niels Lohmann <http://nlohmann.me>.
15
16Permission is hereby granted, free of charge, to any person obtaining a copy
17of this software and associated documentation files (the "Software"), to deal
18in the Software without restriction, including without limitation the rights
19to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20copies of the Software, and to permit persons to whom the Software is
21furnished to do so, subject to the following conditions:
22
23The above copyright notice and this permission notice shall be included in all
24copies or substantial portions of the Software.
25
26THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32SOFTWARE.
33*/
34
35#ifndef WPIUTIL_JSON_H
36#define WPIUTIL_JSON_H
37
38#define NLOHMANN_JSON_VERSION_MAJOR 3
39#define NLOHMANN_JSON_VERSION_MINOR 1
40#define NLOHMANN_JSON_VERSION_PATCH 2
41
42
43#include <algorithm> // all_of, copy, find, for_each, generate_n, min, reverse, remove, fill, none_of, transform
44#include <array> // array
45#include <cassert> // assert
46#include <cstddef> // nullptr_t, ptrdiff_t, size_t
47#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
48#include <exception> // exception
49#include <functional> // function, hash, less
50#include <initializer_list> // initializer_list
51#include <iterator>
52#include <limits> // numeric_limits
53#include <memory> // allocator, shared_ptr, make_shared, addressof
54#include <span>
55#include <stdexcept> // runtime_error
56#include <string> // string, char_traits, stoi, to_string
57#include <string_view>
58#include <tuple> // tuple, get, make_tuple
59#include <type_traits>
60#include <utility>
61#include <vector> // vector
62
63#include "wpi/StringMap.h"
64
65namespace wpi
66{
67
68class raw_istream;
69class raw_ostream;
70
71class JsonTest;
72
73/*!
74@brief default JSONSerializer template argument
75
76This serializer ignores the template arguments and uses ADL
77([argument-dependent lookup](http://en.cppreference.com/w/cpp/language/adl))
78for serialization.
79*/
80template<typename = void, typename = void>
81struct adl_serializer;
82
83/*!
84@brief JSON Pointer
85
86A JSON pointer defines a string syntax for identifying a specific value
87within a JSON document. It can be used with functions `at` and
88`operator[]`. Furthermore, JSON pointers are the base for JSON patches.
89
90@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
91
92@since version 2.0.0
93*/
94class json_pointer;
95
96/*!
97@brief default JSON class
98
99This type is the default specialization of the @ref json class which
100uses the standard template types.
101
102@since version 1.0.0
103*/
104class json;
105}
106
107// exclude unsupported compilers
108#if defined(__clang__)
109 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
110 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
111 #endif
112#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
113 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
114 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
115 #endif
116#endif
117
118// disable float-equal warnings on GCC/clang
119#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
120 #pragma GCC diagnostic push
121 #pragma GCC diagnostic ignored "-Wfloat-equal"
122#endif
123
124// disable documentation warnings on clang
125#if defined(__clang__)
126 #pragma GCC diagnostic push
127 #pragma GCC diagnostic ignored "-Wdocumentation"
128#endif
129
130// allow to disable exceptions
131#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
132 #define JSON_THROW(exception) throw exception
133 #define JSON_TRY try
134 #define JSON_CATCH(exception) catch(exception)
135#else
136 #define JSON_THROW(exception) std::abort()
137 #define JSON_TRY if(true)
138 #define JSON_CATCH(exception) if(false)
139#endif
140
141// override exception macros
142#if defined(JSON_THROW_USER)
143 #undef JSON_THROW
144 #define JSON_THROW JSON_THROW_USER
145#endif
146#if defined(JSON_TRY_USER)
147 #undef JSON_TRY
148 #define JSON_TRY JSON_TRY_USER
149#endif
150#if defined(JSON_CATCH_USER)
151 #undef JSON_CATCH
152 #define JSON_CATCH JSON_CATCH_USER
153#endif
154
155// manual branch prediction
156#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
157 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
158 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
159#else
160 #define JSON_LIKELY(x) x
161 #define JSON_UNLIKELY(x) x
162#endif
163
164/*!
165@brief Helper to determine whether there's a key_type for T.
166
167This helper is used to tell associative containers apart from other containers
168such as sequence containers. For instance, `std::map` passes the test as it
169contains a `mapped_type`, whereas `std::vector` fails the test.
170
171@sa http://stackoverflow.com/a/7728728/266378
172@since version 1.0.0, overworked in version 2.0.6
173*/
174#define NLOHMANN_JSON_HAS_HELPER(type) \
175 template<typename T> struct has_##type { \
176 private: \
177 template<typename U, typename = typename U::type> \
178 static int detect(U &&); \
179 static void detect(...); \
180 public: \
181 static constexpr bool value = \
182 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
183 }
184
185namespace wpi
186{
187/*!
188@brief detail namespace with internal helper functions
189
190This namespace collects functions that should not be exposed,
191implementations of some @ref json methods, and meta-programming helpers.
192
193@since version 2.1.0
194*/
195namespace detail
196{
197/////////////
198// helpers //
199/////////////
200
201template<typename> struct is_json : std::false_type {};
202
203template<> struct is_json<json> : std::true_type {};
204
205// alias templates to reduce boilerplate
206template<bool B, typename T = void>
208
209template<typename T>
211
212// dispatch utility (taken from ranges-v3)
213template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
214template<> struct priority_tag<0> {};
215
216////////////////////////
217// has_/is_ functions //
218////////////////////////
219
220// source: https://stackoverflow.com/a/37193089/4116453
221
222template <typename T, typename = void>
223struct is_complete_type : std::false_type {};
224
225template <typename T>
226struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
227
232
233template<bool B, class RealType, class CompatibleObjectType>
234struct is_compatible_object_type_impl : std::false_type {};
235
236template<class RealType, class CompatibleObjectType>
237struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
238{
239 static constexpr auto value =
240 std::is_constructible<std::string_view, typename CompatibleObjectType::key_type>::value and
241 std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
242};
243
244template<class BasicJsonType, class CompatibleObjectType>
246{
247 static auto constexpr value = is_compatible_object_type_impl <
248 std::conjunction<std::negation<std::is_same<void, CompatibleObjectType>>,
249 has_mapped_type<CompatibleObjectType>,
250 has_key_type<CompatibleObjectType>>::value,
251 typename BasicJsonType::object_t, CompatibleObjectType >::value;
252};
253
254template<typename BasicJsonType, typename T>
256{
257 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
258 std::is_same<T, typename BasicJsonType::const_iterator>::value or
259 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
260 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
261};
262
263template<class BasicJsonType, class CompatibleArrayType>
265{
266 static auto constexpr value =
267 std::conjunction<std::negation<std::is_same<void, CompatibleArrayType>>,
268 std::negation<is_compatible_object_type<
269 BasicJsonType, CompatibleArrayType>>,
270 std::negation<std::is_constructible<std::string_view,
271 CompatibleArrayType>>,
272 std::negation<is_json_nested_type<BasicJsonType, CompatibleArrayType>>,
273 has_value_type<CompatibleArrayType>,
274 has_iterator<CompatibleArrayType>>::value;
275};
276
277template<bool, typename, typename>
278struct is_compatible_integer_type_impl : std::false_type {};
279
280template<typename RealIntegerType, typename CompatibleNumberIntegerType>
281struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
282{
283 // is there an assert somewhere on overflows?
284 using RealLimits = std::numeric_limits<RealIntegerType>;
285 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
286
287 static constexpr auto value =
288 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
291};
292
293template<typename RealIntegerType, typename CompatibleNumberIntegerType>
295{
296 static constexpr auto value =
298 std::is_integral<CompatibleNumberIntegerType>::value and
299 not std::is_same<bool, CompatibleNumberIntegerType>::value,
300 RealIntegerType, CompatibleNumberIntegerType > ::value;
301};
302
303// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
304template<typename BasicJsonType, typename T>
306{
307 private:
308 // also check the return type of from_json
309 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
310 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
311 static int detect(U&&);
312 static void detect(...);
313
314 public:
315 static constexpr bool value = std::is_integral<decltype(
316 detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
317};
318
319// This trait checks if JSONSerializer<T>::from_json(json const&) exists
320// this overload is used for non-default-constructible user-defined-types
321template<typename BasicJsonType, typename T>
323{
324 private:
325 template <
326 typename U,
327 typename = enable_if_t<std::is_same<
328 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
329 static int detect(U&&);
330 static void detect(...);
331
332 public:
333 static constexpr bool value = std::is_integral<decltype(detect(
334 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
335};
336
337// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
338template<typename BasicJsonType, typename T>
340{
341 private:
342 template<typename U, typename = decltype(uncvref_t<U>::to_json(
343 std::declval<BasicJsonType&>(), std::declval<T>()))>
344 static int detect(U&&);
345 static void detect(...);
346
347 public:
348 static constexpr bool value = std::is_integral<decltype(detect(
349 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
350};
351
352template <typename BasicJsonType, typename CompatibleCompleteType>
354{
355 static constexpr bool value =
356 not std::is_base_of<std::istream, CompatibleCompleteType>::value and
360};
361
362template <typename BasicJsonType, typename CompatibleType>
364 : std::conjunction<is_complete_type<CompatibleType>,
366{
367};
368
369// taken from ranges-v3
370template<typename T>
372{
373 static constexpr T value{};
374};
375
376template<typename T>
377constexpr T static_const<T>::value;
378
379////////////////
380// exceptions //
381////////////////
382
383/*!
384@brief general exception of the @ref json class
385
386This class is an extension of `std::exception` objects with a member @a id for
387exception ids. It is used as the base class for all exceptions thrown by the
388@ref json class. This class can hence be used as "wildcard" to catch
389exceptions.
390
391Subclasses:
392- @ref parse_error for exceptions indicating a parse error
393- @ref invalid_iterator for exceptions indicating errors with iterators
394- @ref type_error for exceptions indicating executing a member function with
395 a wrong type
396- @ref out_of_range for exceptions indicating access out of the defined range
397- @ref other_error for exceptions indicating other library errors
398
399@internal
400@note To have nothrow-copy-constructible exceptions, we internally use
401 `std::runtime_error` which can cope with arbitrary-length error messages.
402 Intermediate strings are built with static functions and then passed to
403 the actual constructor.
404@endinternal
405
406@liveexample{The following code shows how arbitrary library exceptions can be
407caught.,exception}
408
409@since version 3.0.0
410*/
412{
413 public:
414 /// returns the explanatory string
415 const char* what() const noexcept override
416 {
417 return m.what();
418 }
419
420 /// the id of the exception
421 const int id;
422
423 protected:
424 exception(int id_, std::string_view what_arg);
425
426 private:
427 /// an exception object as storage for error messages
428 std::runtime_error m;
429};
430
431/*!
432@brief exception indicating a parse error
433
434This exception is thrown by the library when a parse error occurs. Parse errors
435can occur during the deserialization of JSON text, CBOR, MessagePack, as well
436as when using JSON Patch.
437
438Member @a byte holds the byte index of the last read character in the input
439file.
440
441Exceptions have ids 1xx.
442
443name / id | example message | description
444------------------------------ | --------------- | -------------------------
445json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
446json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
447json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
448json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
449json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
450json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
451json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
452json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
453json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
454json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
455json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
456json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
457
458@note For an input with n bytes, 1 is the index of the first character and n+1
459 is the index of the terminating null byte or the end of file. This also
460 holds true when reading a byte vector (CBOR or MessagePack).
461
462@liveexample{The following code shows how a `parse_error` exception can be
463caught.,parse_error}
464
465@sa @ref exception for the base class of the library exceptions
466@sa @ref invalid_iterator for exceptions indicating errors with iterators
467@sa @ref type_error for exceptions indicating executing a member function with
468 a wrong type
469@sa @ref out_of_range for exceptions indicating access out of the defined range
470@sa @ref other_error for exceptions indicating other library errors
471
472@since version 3.0.0
473*/
474class parse_error : public exception
475{
476 public:
477 /*!
478 @brief create a parse error exception
479 @param[in] id_ the id of the exception
480 @param[in] byte_ the byte index where the error occurred (or 0 if the
481 position cannot be determined)
482 @param[in] what_arg the explanatory string
483 @return parse_error object
484 */
485 static parse_error create(int id_, std::size_t byte_, std::string_view what_arg);
486
487 /*!
488 @brief byte index of the parse error
489
490 The byte index of the last read character in the input file.
491
492 @note For an input with n bytes, 1 is the index of the first character and
493 n+1 is the index of the terminating null byte or the end of file.
494 This also holds true when reading a byte vector (CBOR or MessagePack).
495 */
496 const std::size_t byte;
497
498 private:
499 parse_error(int id_, std::size_t byte_, std::string_view what_arg)
500 : exception(id_, what_arg), byte(byte_) {}
501};
502
503/*!
504@brief exception indicating errors with iterators
505
506This exception is thrown if iterators passed to a library function do not match
507the expected semantics.
508
509Exceptions have ids 2xx.
510
511name / id | example message | description
512----------------------------------- | --------------- | -------------------------
513json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
514json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
515json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
516json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
517json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
518json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
519json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
520json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
521json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
522json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
523json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
524json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
525json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
526json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
527
528@liveexample{The following code shows how an `invalid_iterator` exception can be
529caught.,invalid_iterator}
530
531@sa @ref exception for the base class of the library exceptions
532@sa @ref parse_error for exceptions indicating a parse error
533@sa @ref type_error for exceptions indicating executing a member function with
534 a wrong type
535@sa @ref out_of_range for exceptions indicating access out of the defined range
536@sa @ref other_error for exceptions indicating other library errors
537
538@since version 3.0.0
539*/
541{
542 public:
543 static invalid_iterator create(int id_, std::string_view what_arg);
544 static invalid_iterator create(int id_, std::string_view what_arg, std::string_view type_info);
545
546 private:
547 invalid_iterator(int id_, std::string_view what_arg)
548 : exception(id_, what_arg) {}
549};
550
551/*!
552@brief exception indicating executing a member function with a wrong type
553
554This exception is thrown in case of a type error; that is, a library function is
555executed on a JSON value whose type does not match the expected semantics.
556
557Exceptions have ids 3xx.
558
559name / id | example message | description
560----------------------------- | --------------- | -------------------------
561json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
562json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
563json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t&.
564json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
565json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
566json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
567json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
568json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
569json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
570json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
571json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
572json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
573json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
574json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
575json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
576json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
577
578@liveexample{The following code shows how a `type_error` exception can be
579caught.,type_error}
580
581@sa @ref exception for the base class of the library exceptions
582@sa @ref parse_error for exceptions indicating a parse error
583@sa @ref invalid_iterator for exceptions indicating errors with iterators
584@sa @ref out_of_range for exceptions indicating access out of the defined range
585@sa @ref other_error for exceptions indicating other library errors
586
587@since version 3.0.0
588*/
589class type_error : public exception
590{
591 public:
592 static type_error create(int id_, std::string_view what_arg);
593 static type_error create(int id_, std::string_view what_arg, std::string_view type_info);
594
595 private:
596 type_error(int id_, std::string_view what_arg) : exception(id_, what_arg) {}
597};
598
599/*!
600@brief exception indicating access out of the defined range
601
602This exception is thrown in case a library function is called on an input
603parameter that exceeds the expected range, for instance in case of array
604indices or nonexisting object keys.
605
606Exceptions have ids 4xx.
607
608name / id | example message | description
609------------------------------- | --------------- | -------------------------
610json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
611json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
612json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
613json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
614json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
615json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
616json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON only supports integers numbers up to 9223372036854775807. |
617json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
618
619@liveexample{The following code shows how an `out_of_range` exception can be
620caught.,out_of_range}
621
622@sa @ref exception for the base class of the library exceptions
623@sa @ref parse_error for exceptions indicating a parse error
624@sa @ref invalid_iterator for exceptions indicating errors with iterators
625@sa @ref type_error for exceptions indicating executing a member function with
626 a wrong type
627@sa @ref other_error for exceptions indicating other library errors
628
629@since version 3.0.0
630*/
632{
633 public:
634 static out_of_range create(int id_, std::string_view what_arg);
635
636 private:
637 out_of_range(int id_, std::string_view what_arg) : exception(id_, what_arg) {}
638};
639
640/*!
641@brief exception indicating other library errors
642
643This exception is thrown in case of errors that cannot be classified with the
644other exception types.
645
646Exceptions have ids 5xx.
647
648name / id | example message | description
649------------------------------ | --------------- | -------------------------
650json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
651
652@sa @ref exception for the base class of the library exceptions
653@sa @ref parse_error for exceptions indicating a parse error
654@sa @ref invalid_iterator for exceptions indicating errors with iterators
655@sa @ref type_error for exceptions indicating executing a member function with
656 a wrong type
657@sa @ref out_of_range for exceptions indicating access out of the defined range
658
659@liveexample{The following code shows how an `other_error` exception can be
660caught.,other_error}
661
662@since version 3.0.0
663*/
664class other_error : public exception
665{
666 public:
667 static other_error create(int id_, std::string_view what_arg);
668
669 private:
670 other_error(int id_, std::string_view what_arg) : exception(id_, what_arg) {}
671};
672
673///////////////////////////
674// JSON type enumeration //
675///////////////////////////
676
677/*!
678@brief the JSON type enumeration
679
680This enumeration collects the different JSON types. It is internally used to
681distinguish the stored values, and the functions @ref json::is_null(),
682@ref json::is_object(), @ref json::is_array(),
683@ref json::is_string(), @ref json::is_boolean(),
684@ref json::is_number() (with @ref json::is_number_integer(),
685@ref json::is_number_unsigned(), and @ref json::is_number_float()),
686@ref json::is_discarded(), @ref json::is_primitive(), and
687@ref json::is_structured() rely on it.
688
689@note There are three enumeration entries (number_integer, number_unsigned, and
690number_float), because the library distinguishes these three types for numbers:
691uint64_t is used for unsigned integers,
692int64_t is used for signed integers, and
693double is used for floating-point numbers or to
694approximate integers which do not fit in the limits of their respective type.
695
696@sa @ref json::json(const value_t value_type) -- create a JSON
697value with the default value for a given type
698
699@since version 1.0.0
700*/
702{
703 null, ///< null value
704 object, ///< object (unordered set of name/value pairs)
705 array, ///< array (ordered collection of values)
706 string, ///< string value
707 boolean, ///< boolean value
708 number_integer, ///< number value (signed integer)
709 number_unsigned, ///< number value (unsigned integer)
710 number_float, ///< number value (floating-point)
711 discarded ///< discarded by the the parser callback function
712};
713
714/*!
715@brief comparison operator for JSON types
716
717Returns an ordering that is similar to Python:
718- order: null < boolean < number < object < array < string
719- furthermore, each type is not smaller than itself
720- discarded values are not comparable
721
722@since version 1.0.0
723*/
724inline bool operator<(const value_t lhs, const value_t rhs) noexcept
725{
726 static constexpr std::array<std::uint8_t, 8> order = {{
727 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
728 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
729 }
730 };
731
732 const auto l_index = static_cast<std::size_t>(lhs);
733 const auto r_index = static_cast<std::size_t>(rhs);
734 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
735}
736
737// overloads for json template parameters
738template<typename BasicJsonType, typename ArithmeticType,
740 not std::is_same<ArithmeticType, bool>::value,
741 int> = 0>
742void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
743{
744 switch (static_cast<value_t>(j))
745 {
747 {
748 val = static_cast<ArithmeticType>(*j.template get_ptr<const uint64_t*>());
749 break;
750 }
752 {
753 val = static_cast<ArithmeticType>(*j.template get_ptr<const int64_t*>());
754 break;
755 }
757 {
758 val = static_cast<ArithmeticType>(*j.template get_ptr<const double*>());
759 break;
760 }
761
762 default:
763 JSON_THROW(type_error::create(302, "type must be number, but is", j.type_name()));
764 }
765}
766
767template<typename BasicJsonType>
768void from_json(const BasicJsonType& j, bool& b)
769{
770 if (JSON_UNLIKELY(not j.is_boolean()))
771 {
772 JSON_THROW(type_error::create(302, "type must be boolean, but is", j.type_name()));
773 }
774 b = *j.template get_ptr<const bool*>();
775}
776
777template<typename BasicJsonType>
778void from_json(const BasicJsonType& j, std::string& s)
779{
780 if (JSON_UNLIKELY(not j.is_string()))
781 {
782 JSON_THROW(type_error::create(302, "type must be string, but is", j.type_name()));
783 }
784 s = *j.template get_ptr<const std::string*>();
785}
786
787template<typename BasicJsonType>
788void from_json(const BasicJsonType& j, double& val)
789{
790 get_arithmetic_value(j, val);
791}
792
793template<typename BasicJsonType>
794void from_json(const BasicJsonType& j, uint64_t& val)
795{
796 get_arithmetic_value(j, val);
797}
798
799template<typename BasicJsonType>
800void from_json(const BasicJsonType& j, int64_t& val)
801{
802 get_arithmetic_value(j, val);
803}
804
805template<typename BasicJsonType, typename EnumType,
807void from_json(const BasicJsonType& j, EnumType& e)
808{
810 get_arithmetic_value(j, val);
811 e = static_cast<EnumType>(val);
812}
813
814template<typename BasicJsonType>
815void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
816{
817 if (JSON_UNLIKELY(not j.is_array()))
818 {
819 JSON_THROW(type_error::create(302, "type must be array, but is", j.type_name()));
820 }
821 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
822}
823
824template<typename BasicJsonType, typename CompatibleArrayType>
825void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/)
826{
827 using std::end;
828
829 std::transform(j.begin(), j.end(),
830 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
831 {
832 // get<BasicJsonType>() returns *this, this won't call a from_json
833 // method when value_type is BasicJsonType
834 return i.template get<typename CompatibleArrayType::value_type>();
835 });
836}
837
838template<typename BasicJsonType, typename CompatibleArrayType>
839auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
840-> decltype(
841 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
842 void())
843{
844 using std::end;
845
846 arr.reserve(j.size());
847 std::transform(j.begin(), j.end(),
848 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
849 {
850 // get<BasicJsonType>() returns *this, this won't call a from_json
851 // method when value_type is BasicJsonType
852 return i.template get<typename CompatibleArrayType::value_type>();
853 });
854}
855
856template<typename BasicJsonType, typename T, std::size_t N>
857void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
858{
859 for (std::size_t i = 0; i < N; ++i)
860 {
861 arr[i] = j.at(i).template get<T>();
862 }
863}
864
865template <
866 typename BasicJsonType, typename CompatibleArrayType,
869 not std::is_same<typename BasicJsonType::array_t,
870 CompatibleArrayType>::value and
871 std::is_constructible <
872 BasicJsonType, typename CompatibleArrayType::value_type >::value,
873 int > = 0 >
874void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
875{
876 if (JSON_UNLIKELY(not j.is_array()))
877 {
878 JSON_THROW(type_error::create(302, "type must be array, but is", j.type_name()));
879 }
880
882}
883
884template<typename BasicJsonType>
885inline
886void from_json(const BasicJsonType& j, typename BasicJsonType::object_t& obj)
887{
888 if (!j.is_object())
889 {
890 JSON_THROW(type_error::create(302, "type must be object, but is", j.type_name()));
891 }
892
893 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
894 for (const auto& i : *inner_object) {
895 obj.try_emplace(i.first(), i.second);
896 }
897}
898
899template<typename BasicJsonType, typename CompatibleObjectType,
901 not std::is_same<typename BasicJsonType::object_t, CompatibleObjectType>::value, int> = 0>
902void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
903{
904 if (JSON_UNLIKELY(not j.is_object()))
905 {
906 JSON_THROW(type_error::create(302, "type must be object, but is", j.type_name()));
907 }
908
909 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
910 using std::begin;
911 using std::end;
912 using value_type = typename CompatibleObjectType::value_type;
913 std::vector<value_type> v;
914 v.reserve(j.size());
915 for (const auto& p : *inner_object)
916 {
917 v.emplace_back(
918 p.first(),
919 p.second
920 .template get<typename CompatibleObjectType::mapped_type>());
921 }
922 // we could avoid the assignment, but this might require a for loop, which
923 // might be less efficient than the container constructor for some
924 // containers (would it?)
925 obj = CompatibleObjectType(std::make_move_iterator(begin(v)),
926 std::make_move_iterator(end(v)));
927}
928
929// overload for arithmetic types, not chosen for json template arguments
930// (BooleanType, etc..); note: Is it really necessary to provide explicit
931// overloads for bool etc. in case of a custom BooleanType which is not
932// an arithmetic type?
933template<typename BasicJsonType, typename ArithmeticType,
935 std::is_arithmetic<ArithmeticType>::value and
936 not std::is_same<ArithmeticType, uint64_t>::value and
937 not std::is_same<ArithmeticType, int64_t>::value and
938 not std::is_same<ArithmeticType, double>::value and
939 not std::is_same<ArithmeticType, bool>::value,
940 int> = 0>
941void from_json(const BasicJsonType& j, ArithmeticType& val)
942{
943 switch (static_cast<value_t>(j))
944 {
946 {
947 val = static_cast<ArithmeticType>(*j.template get_ptr<const uint64_t*>());
948 break;
949 }
951 {
952 val = static_cast<ArithmeticType>(*j.template get_ptr<const int64_t*>());
953 break;
954 }
956 {
957 val = static_cast<ArithmeticType>(*j.template get_ptr<const double*>());
958 break;
959 }
960 case value_t::boolean:
961 {
962 val = static_cast<ArithmeticType>(*j.template get_ptr<const bool*>());
963 break;
964 }
965
966 default:
967 JSON_THROW(type_error::create(302, "type must be number, but is", j.type_name()));
968 }
969}
970
971template<typename BasicJsonType, typename A1, typename A2>
972void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
973{
974 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
975}
976
977template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
978void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, std::index_sequence<Idx...>)
979{
980 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
981}
982
983template<typename BasicJsonType, typename... Args>
984void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
985{
986 from_json_tuple_impl(j, t, std::index_sequence_for<Args...> {});
987}
988
990{
991 private:
992 template<typename BasicJsonType, typename T>
993 auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const
994 noexcept(noexcept(from_json(j, val)))
995 -> decltype(from_json(j, val), void())
996 {
997 return from_json(j, val);
998 }
999
1000 template<typename BasicJsonType, typename T>
1001 void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1002 {
1003 static_assert(sizeof(BasicJsonType) == 0,
1004 "could not find from_json() method in T's namespace");
1005#ifdef _MSC_VER
1006 // MSVC does not show a stacktrace for the above assert
1007 using decayed = uncvref_t<T>;
1008 static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1009 "forcing MSVC stacktrace to show which T we're talking about.");
1010#endif
1011 }
1012
1013 public:
1014 template<typename BasicJsonType, typename T>
1015 void operator()(const BasicJsonType& j, T& val) const
1016 noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1017 {
1018 return call(j, val, priority_tag<1> {});
1019 }
1020};
1021}
1022
1023// namespace to hold default `from_json` function
1024// to see why this is required:
1025// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
1026namespace
1027{
1029}
1030
1031namespace detail
1032{
1033//////////////////
1034// constructors //
1035//////////////////
1036
1037template<value_t> struct external_constructor;
1038
1039template<>
1041{
1042 template<typename BasicJsonType>
1043 static void construct(BasicJsonType& j, bool b) noexcept
1044 {
1045 j.m_type = value_t::boolean;
1046 j.m_value = b;
1047 j.assert_invariant();
1048 }
1049};
1050
1051template<>
1053{
1054 template<typename BasicJsonType>
1055 static void construct(BasicJsonType& j, std::string_view s)
1056 {
1057 j.m_type = value_t::string;
1058 j.m_value = s;
1059 j.assert_invariant();
1060 }
1061
1062 template<typename BasicJsonType, typename T,
1064 static void construct(BasicJsonType& j, T&& s)
1065 {
1066 j.m_type = value_t::string;
1067 j.m_value = std::move(s);
1068 j.assert_invariant();
1069 }
1070};
1071
1072template<>
1074{
1075 template<typename BasicJsonType>
1076 static void construct(BasicJsonType& j, double val) noexcept
1077 {
1078 j.m_type = value_t::number_float;
1079 j.m_value = val;
1080 j.assert_invariant();
1081 }
1082};
1083
1084template<>
1086{
1087 template<typename BasicJsonType>
1088 static void construct(BasicJsonType& j, uint64_t val) noexcept
1089 {
1090 j.m_type = value_t::number_unsigned;
1091 j.m_value = val;
1092 j.assert_invariant();
1093 }
1094};
1095
1096template<>
1098{
1099 template<typename BasicJsonType>
1100 static void construct(BasicJsonType& j, int64_t val) noexcept
1101 {
1102 j.m_type = value_t::number_integer;
1103 j.m_value = val;
1104 j.assert_invariant();
1105 }
1106};
1107
1108template<>
1110{
1111 template<typename BasicJsonType>
1112 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1113 {
1114 j.m_type = value_t::array;
1115 j.m_value = arr;
1116 j.assert_invariant();
1117 }
1118
1119 template<typename BasicJsonType>
1120 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1121 {
1122 j.m_type = value_t::array;
1123 j.m_value = std::move(arr);
1124 j.assert_invariant();
1125 }
1126
1127 template<typename BasicJsonType, typename T>
1128 static void construct(BasicJsonType& j, std::span<T> arr)
1129 {
1130 using std::begin;
1131 using std::end;
1132 j.m_type = value_t::array;
1133 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1134 j.assert_invariant();
1135 }
1136
1137 template<typename BasicJsonType, typename CompatibleArrayType,
1139 int> = 0>
1140 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1141 {
1142 using std::begin;
1143 using std::end;
1144 j.m_type = value_t::array;
1145 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1146 j.assert_invariant();
1147 }
1148
1149 template<typename BasicJsonType>
1150 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1151 {
1152 j.m_type = value_t::array;
1153 j.m_value = value_t::array;
1154 j.m_value.array->reserve(arr.size());
1155 for (const bool x : arr)
1156 {
1157 j.m_value.array->push_back(x);
1158 }
1159 j.assert_invariant();
1160 }
1161};
1162
1163template<>
1165{
1166 template<typename BasicJsonType>
1167 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1168 {
1169 j.m_type = value_t::object;
1170 j.m_value = obj;
1171 j.assert_invariant();
1172 }
1173
1174 template<typename BasicJsonType>
1175 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1176 {
1177 j.m_type = value_t::object;
1178 j.m_value = std::move(obj);
1179 j.assert_invariant();
1180 }
1181
1182 template<typename BasicJsonType, typename CompatibleObjectType,
1184 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
1185 {
1186 j.m_type = value_t::object;
1187 j.m_value = value_t::object;
1188 for (const auto& x : obj)
1189 {
1190 j.m_value.object->try_emplace(x.first, x.second);
1191 }
1192 j.assert_invariant();
1193 }
1194};
1195
1196/////////////
1197// to_json //
1198/////////////
1199
1200template<typename BasicJsonType, typename T,
1202void to_json(BasicJsonType& j, T b) noexcept
1203{
1205}
1206
1207template<typename BasicJsonType, typename CompatibleString,
1209void to_json(BasicJsonType& j, const CompatibleString& s)
1210{
1212}
1213
1214template<typename BasicJsonType, typename T,
1216void to_json(BasicJsonType& j, T&& s)
1217{
1219}
1220
1221template<typename BasicJsonType, typename FloatType,
1223void to_json(BasicJsonType& j, FloatType val) noexcept
1224{
1225 external_constructor<value_t::number_float>::construct(j, static_cast<double>(val));
1226}
1227
1228template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
1230void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
1231{
1233}
1234
1235template<typename BasicJsonType, typename CompatibleNumberIntegerType,
1237void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
1238{
1240}
1241
1242template<typename BasicJsonType, typename EnumType,
1244void to_json(BasicJsonType& j, EnumType e) noexcept
1245{
1246 using underlying_type = typename std::underlying_type<EnumType>::type;
1247 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1248}
1249
1250template<typename BasicJsonType>
1251void to_json(BasicJsonType& j, const std::vector<bool>& e)
1252{
1254}
1255
1256template<typename BasicJsonType, typename CompatibleArrayType,
1258 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1259 int> = 0>
1260void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
1261{
1263}
1264
1265template<typename BasicJsonType>
1266void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1267{
1269}
1270
1271template<typename BasicJsonType, typename CompatibleObjectType,
1273void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
1274{
1276}
1277
1278template<typename BasicJsonType>
1279void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1280{
1282}
1283
1284template<typename BasicJsonType, typename T, std::size_t N,
1285 enable_if_t<not std::is_constructible<std::string_view, T (&)[N]>::value, int> = 0>
1286void to_json(BasicJsonType& j, T (&arr)[N])
1287{
1289}
1290
1291template<typename BasicJsonType, typename... Args>
1292void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1293{
1294 j = {p.first, p.second};
1295}
1296
1297template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
1298void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, std::index_sequence<Idx...>)
1299{
1300 j = {std::get<Idx>(t)...};
1301}
1302
1303template<typename BasicJsonType, typename... Args>
1304void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1305{
1306 to_json_tuple_impl(j, t, std::index_sequence_for<Args...> {});
1307}
1308
1310{
1311 private:
1312 template<typename BasicJsonType, typename T>
1313 auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1314 -> decltype(to_json(j, std::forward<T>(val)), void())
1315 {
1316 return to_json(j, std::forward<T>(val));
1317 }
1318
1319 template<typename BasicJsonType, typename T>
1320 void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1321 {
1322 static_assert(sizeof(BasicJsonType) == 0,
1323 "could not find to_json() method in T's namespace");
1324
1325#ifdef _MSC_VER
1326 // MSVC does not show a stacktrace for the above assert
1327 using decayed = uncvref_t<T>;
1328 static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0,
1329 "forcing MSVC stacktrace to show which T we're talking about.");
1330#endif
1331 }
1332
1333 public:
1334 template<typename BasicJsonType, typename T>
1335 void operator()(BasicJsonType& j, T&& val) const
1336 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1337 {
1338 return call(j, std::forward<T>(val), priority_tag<1> {});
1339 }
1340};
1341}
1342
1343// namespace to hold default `to_json` function
1344namespace
1345{
1347}
1348
1349namespace detail
1350{
1351/*
1352@brief an iterator for primitive JSON types
1353
1354This class models an iterator for primitive JSON types (boolean, number,
1355string). It's only purpose is to allow the iterator/const_iterator classes
1356to "iterate" over primitive values. Internally, the iterator is modeled by
1357a `difference_type` variable. Value begin_value (`0`) models the begin,
1358end_value (`1`) models past the end.
1359*/
1361{
1362 private:
1363 using difference_type = std::ptrdiff_t;
1364 static constexpr difference_type begin_value = 0;
1365 static constexpr difference_type end_value = begin_value + 1;
1366
1367 /// iterator as signed integer type
1368 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
1369
1370 public:
1371 constexpr difference_type get_value() const noexcept
1372 {
1373 return m_it;
1374 }
1375
1376 /// set iterator to a defined beginning
1377 void set_begin() noexcept
1378 {
1379 m_it = begin_value;
1380 }
1381
1382 /// set iterator to a defined past the end
1383 void set_end() noexcept
1384 {
1385 m_it = end_value;
1386 }
1387
1388 /// return whether the iterator can be dereferenced
1389 constexpr bool is_begin() const noexcept
1390 {
1391 return m_it == begin_value;
1392 }
1393
1394 /// return whether the iterator is at end
1395 constexpr bool is_end() const noexcept
1396 {
1397 return m_it == end_value;
1398 }
1399
1400 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
1401 {
1402 return lhs.m_it == rhs.m_it;
1403 }
1404
1405 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
1406 {
1407 return lhs.m_it < rhs.m_it;
1408 }
1409
1410 primitive_iterator_t operator+(difference_type n) noexcept
1411 {
1412 auto result = *this;
1413 result += n;
1414 return result;
1415 }
1416
1417 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
1418 {
1419 return lhs.m_it - rhs.m_it;
1420 }
1421
1423 {
1424 ++m_it;
1425 return *this;
1426 }
1427
1429 {
1430 auto result = *this;
1431 m_it++;
1432 return result;
1433 }
1434
1436 {
1437 --m_it;
1438 return *this;
1439 }
1440
1442 {
1443 auto result = *this;
1444 m_it--;
1445 return result;
1446 }
1447
1448 primitive_iterator_t& operator+=(difference_type n) noexcept
1449 {
1450 m_it += n;
1451 return *this;
1452 }
1453
1454 primitive_iterator_t& operator-=(difference_type n) noexcept
1455 {
1456 m_it -= n;
1457 return *this;
1458 }
1459};
1460
1461/*!
1462@brief an iterator value
1463
1464@note This structure could easily be a union, but MSVC currently does not allow
1465unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
1466*/
1467template<typename BasicJsonType> struct internal_iterator
1468{
1469 /// iterator for JSON objects
1470 typename BasicJsonType::object_t::iterator object_iterator {};
1471 /// iterator for JSON arrays
1472 typename BasicJsonType::array_t::iterator array_iterator {};
1473 /// generic iterator for all other types
1475};
1476
1477// forward declare, to be able to friend it later on
1478template<typename IteratorType> class iteration_proxy;
1479
1480/*!
1481@brief a template for a bidirectional iterator for the @ref json class
1482
1483This class implements a both iterators (iterator and const_iterator) for the
1484@ref json class.
1485
1486@note An iterator is called *initialized* when a pointer to a JSON value has
1487 been set (e.g., by a constructor or a copy assignment). If the iterator is
1488 default-constructed, it is *uninitialized* and most methods are undefined.
1489 **The library uses assertions to detect calls on uninitialized iterators.**
1490
1491@requirement The class satisfies the following concept requirements:
1492-
1493[BidirectionalIterator](http://en.cppreference.com/w/cpp/concept/BidirectionalIterator):
1494 The iterator that can be moved can be moved in both directions (i.e.
1495 incremented and decremented).
1496
1497@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
1498 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
1499*/
1500template<typename BasicJsonType>
1502{
1503 /// allow json to access private members
1505 friend BasicJsonType;
1507 friend class ::wpi::JsonTest;
1508
1509 using object_t = typename BasicJsonType::object_t;
1510 using array_t = typename BasicJsonType::array_t;
1511 // make sure BasicJsonType is json or const json
1513 "iter_impl only accepts (const) json");
1514
1515 public:
1516
1517 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
1518 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
1519 /// A user-defined iterator should provide publicly accessible typedefs named
1520 /// iterator_category, value_type, difference_type, pointer, and reference.
1521 /// Note that value_type is required to be non-const, even for constant iterators.
1522 using iterator_category = std::bidirectional_iterator_tag;
1523
1524 /// the type of the values when the iterator is dereferenced
1525 using value_type = typename BasicJsonType::value_type;
1526 /// a type to represent differences between iterators
1527 using difference_type = typename BasicJsonType::difference_type;
1528 /// defines a pointer to the type iterated over (value_type)
1529 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
1530 typename BasicJsonType::const_pointer,
1531 typename BasicJsonType::pointer>::type;
1532 /// defines a reference to the type iterated over (value_type)
1534 typename std::conditional<std::is_const<BasicJsonType>::value,
1535 typename BasicJsonType::const_reference,
1536 typename BasicJsonType::reference>::type;
1537
1538 /// default constructor
1539 iter_impl() = default;
1540
1541 /*!
1542 @brief constructor for a given JSON instance
1543 @param[in] object pointer to a JSON object for this iterator
1544 @pre object != nullptr
1545 @post The iterator is initialized; i.e. `m_object != nullptr`.
1546 */
1547 explicit iter_impl(pointer object) noexcept : m_object(object)
1548 {
1549 assert(m_object != nullptr);
1550
1551 switch (m_object->m_type)
1552 {
1553 case value_t::object:
1554 {
1555 m_it.object_iterator = typename object_t::iterator();
1556 break;
1557 }
1558
1559 case value_t::array:
1560 {
1561 m_it.array_iterator = typename array_t::iterator();
1562 break;
1563 }
1564
1565 default:
1566 {
1568 break;
1569 }
1570 }
1571 }
1572
1573 /*!
1574 @note The conventional copy constructor and copy assignment are implicitly
1575 defined. Combined with the following converting constructor and
1576 assignment, they support: (1) copy from iterator to iterator, (2)
1577 copy from const iterator to const iterator, and (3) conversion from
1578 iterator to const iterator. However conversion from const iterator
1579 to iterator is not defined.
1580 */
1581
1582 /*!
1583 @brief converting constructor
1584 @param[in] other non-const iterator to copy from
1585 @note It is not checked whether @a other is initialized.
1586 */
1588 : m_object(other.m_object), m_it(other.m_it) {}
1589
1590 /*!
1591 @brief converting assignment
1592 @param[in,out] other non-const iterator to copy from
1593 @return const/non-const iterator
1594 @note It is not checked whether @a other is initialized.
1595 */
1597 {
1598 m_object = other.m_object;
1599 m_it = other.m_it;
1600 return *this;
1601 }
1602
1603 private:
1604 /*!
1605 @brief set the iterator to the first value
1606 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1607 */
1608 void set_begin() noexcept
1609 {
1610 assert(m_object != nullptr);
1611
1612 switch (m_object->m_type)
1613 {
1614 case value_t::object:
1615 {
1616 m_it.object_iterator = m_object->m_value.object->begin();
1617 break;
1618 }
1619
1620 case value_t::array:
1621 {
1622 m_it.array_iterator = m_object->m_value.array->begin();
1623 break;
1624 }
1625
1626 case value_t::null:
1627 {
1628 // set to end so begin()==end() is true: null is empty
1630 break;
1631 }
1632
1633 default:
1634 {
1636 break;
1637 }
1638 }
1639 }
1640
1641 /*!
1642 @brief set the iterator past the last value
1643 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1644 */
1645 void set_end() noexcept
1646 {
1647 assert(m_object != nullptr);
1648
1649 switch (m_object->m_type)
1650 {
1651 case value_t::object:
1652 {
1653 m_it.object_iterator = m_object->m_value.object->end();
1654 break;
1655 }
1656
1657 case value_t::array:
1658 {
1659 m_it.array_iterator = m_object->m_value.array->end();
1660 break;
1661 }
1662
1663 default:
1664 {
1666 break;
1667 }
1668 }
1669 }
1670
1671 public:
1672 /*!
1673 @brief return a reference to the value pointed to by the iterator
1674 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1675 */
1677 {
1678 assert(m_object != nullptr);
1679
1680 switch (m_object->m_type)
1681 {
1682 case value_t::object:
1683 {
1684 assert(m_it.object_iterator != m_object->m_value.object->end());
1685 return m_it.object_iterator->second;
1686 }
1687
1688 case value_t::array:
1689 {
1690 assert(m_it.array_iterator != m_object->m_value.array->end());
1691 return *m_it.array_iterator;
1692 }
1693
1694 case value_t::null:
1695 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
1696
1697 default:
1698 {
1700 {
1701 return *m_object;
1702 }
1703
1704 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
1705 }
1706 }
1707 }
1708
1709 /*!
1710 @brief dereference the iterator
1711 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1712 */
1714 {
1715 assert(m_object != nullptr);
1716
1717 switch (m_object->m_type)
1718 {
1719 case value_t::object:
1720 {
1721 assert(m_it.object_iterator != m_object->m_value.object->end());
1722 return &(m_it.object_iterator->second);
1723 }
1724
1725 case value_t::array:
1726 {
1727 assert(m_it.array_iterator != m_object->m_value.array->end());
1728 return &*m_it.array_iterator;
1729 }
1730
1731 default:
1732 {
1734 {
1735 return m_object;
1736 }
1737
1738 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
1739 }
1740 }
1741 }
1742
1743 /*!
1744 @brief post-increment (it++)
1745 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1746 */
1748 {
1749 auto result = *this;
1750 ++(*this);
1751 return result;
1752 }
1753
1754 /*!
1755 @brief pre-increment (++it)
1756 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1757 */
1759 {
1760 assert(m_object != nullptr);
1761
1762 switch (m_object->m_type)
1763 {
1764 case value_t::object:
1765 {
1766 ++m_it.object_iterator;
1767 break;
1768 }
1769
1770 case value_t::array:
1771 {
1772 std::advance(m_it.array_iterator, 1);
1773 break;
1774 }
1775
1776 default:
1777 {
1778 ++m_it.primitive_iterator;
1779 break;
1780 }
1781 }
1782
1783 return *this;
1784 }
1785
1786 /*!
1787 @brief post-decrement (it--)
1788 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1789 */
1791 {
1792 auto result = *this;
1793 --(*this);
1794 return result;
1795 }
1796
1797 /*!
1798 @brief pre-decrement (--it)
1799 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1800 */
1802 {
1803 assert(m_object != nullptr);
1804
1805 switch (m_object->m_type)
1806 {
1807 case value_t::object:
1808 {
1809 --m_it.object_iterator;
1810 break;
1811 }
1812
1813 case value_t::array:
1814 {
1815 std::advance(m_it.array_iterator, -1);
1816 break;
1817 }
1818
1819 default:
1820 {
1821 --m_it.primitive_iterator;
1822 break;
1823 }
1824 }
1825
1826 return *this;
1827 }
1828
1829 /*!
1830 @brief comparison: equal
1831 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1832 */
1833 bool operator==(const iter_impl& other) const
1834 {
1835 // if objects are not the same, the comparison is undefined
1836 if (JSON_UNLIKELY(m_object != other.m_object))
1837 {
1838 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
1839 }
1840
1841 assert(m_object != nullptr);
1842
1843 switch (m_object->m_type)
1844 {
1845 case value_t::object:
1846 return (m_it.object_iterator == other.m_it.object_iterator);
1847
1848 case value_t::array:
1849 return (m_it.array_iterator == other.m_it.array_iterator);
1850
1851 default:
1852 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
1853 }
1854 }
1855
1856 /*!
1857 @brief comparison: not equal
1858 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1859 */
1860 bool operator!=(const iter_impl& other) const
1861 {
1862 return not operator==(other);
1863 }
1864
1865 /*!
1866 @brief comparison: smaller
1867 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1868 */
1869 bool operator<(const iter_impl& other) const
1870 {
1871 // if objects are not the same, the comparison is undefined
1872 if (JSON_UNLIKELY(m_object != other.m_object))
1873 {
1874 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
1875 }
1876
1877 assert(m_object != nullptr);
1878
1879 switch (m_object->m_type)
1880 {
1881 case value_t::object:
1882 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
1883
1884 case value_t::array:
1885 return (m_it.array_iterator < other.m_it.array_iterator);
1886
1887 default:
1888 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
1889 }
1890 }
1891
1892 /*!
1893 @brief comparison: less than or equal
1894 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1895 */
1896 bool operator<=(const iter_impl& other) const
1897 {
1898 return not other.operator < (*this);
1899 }
1900
1901 /*!
1902 @brief comparison: greater than
1903 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1904 */
1905 bool operator>(const iter_impl& other) const
1906 {
1907 return not operator<=(other);
1908 }
1909
1910 /*!
1911 @brief comparison: greater than or equal
1912 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1913 */
1914 bool operator>=(const iter_impl& other) const
1915 {
1916 return not operator<(other);
1917 }
1918
1919 /*!
1920 @brief add to iterator
1921 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1922 */
1924 {
1925 assert(m_object != nullptr);
1926
1927 switch (m_object->m_type)
1928 {
1929 case value_t::object:
1930 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
1931
1932 case value_t::array:
1933 {
1934 std::advance(m_it.array_iterator, i);
1935 break;
1936 }
1937
1938 default:
1939 {
1940 m_it.primitive_iterator += i;
1941 break;
1942 }
1943 }
1944
1945 return *this;
1946 }
1947
1948 /*!
1949 @brief subtract from iterator
1950 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1951 */
1953 {
1954 return operator+=(-i);
1955 }
1956
1957 /*!
1958 @brief add to iterator
1959 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1960 */
1962 {
1963 auto result = *this;
1964 result += i;
1965 return result;
1966 }
1967
1968 /*!
1969 @brief addition of distance and iterator
1970 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1971 */
1973 {
1974 auto result = it;
1975 result += i;
1976 return result;
1977 }
1978
1979 /*!
1980 @brief subtract from iterator
1981 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1982 */
1984 {
1985 auto result = *this;
1986 result -= i;
1987 return result;
1988 }
1989
1990 /*!
1991 @brief return difference
1992 @pre The iterator is initialized; i.e. `m_object != nullptr`.
1993 */
1995 {
1996 assert(m_object != nullptr);
1997
1998 switch (m_object->m_type)
1999 {
2000 case value_t::object:
2001 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
2002
2003 case value_t::array:
2004 return m_it.array_iterator - other.m_it.array_iterator;
2005
2006 default:
2007 return m_it.primitive_iterator - other.m_it.primitive_iterator;
2008 }
2009 }
2010
2011 /*!
2012 @brief access to successor
2013 @pre The iterator is initialized; i.e. `m_object != nullptr`.
2014 */
2016 {
2017 assert(m_object != nullptr);
2018
2019 switch (m_object->m_type)
2020 {
2021 case value_t::object:
2022 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
2023
2024 case value_t::array:
2025 return *std::next(m_it.array_iterator, n);
2026
2027 case value_t::null:
2028 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
2029
2030 default:
2031 {
2032 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
2033 {
2034 return *m_object;
2035 }
2036
2037 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
2038 }
2039 }
2040 }
2041
2042 /*!
2043 @brief return the key of an object iterator
2044 @pre The iterator is initialized; i.e. `m_object != nullptr`.
2045 */
2047 {
2048 assert(m_object != nullptr);
2049
2050 if (JSON_LIKELY(m_object->is_object()))
2051 {
2052 return m_it.object_iterator->first();
2053 }
2054
2055 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
2056 }
2057
2058 /*!
2059 @brief return the value of an iterator
2060 @pre The iterator is initialized; i.e. `m_object != nullptr`.
2061 */
2063 {
2064 return operator*();
2065 }
2066
2067 private:
2068 /// associated JSON instance
2069 pointer m_object = nullptr;
2070 /// the actual iterator of the associated instance
2072};
2073
2074/// proxy class for the items() function
2075template<typename IteratorType> class iteration_proxy
2076{
2077 private:
2078 /// helper class for iteration
2079 class iteration_proxy_internal
2080 {
2081 private:
2082 /// the iterator
2083 IteratorType anchor;
2084 /// an index for arrays (used to create key names)
2085 std::size_t array_index = 0;
2086
2087 public:
2088 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
2089
2090 /// dereference operator (needed for range-based for)
2091 iteration_proxy_internal& operator*()
2092 {
2093 return *this;
2094 }
2095
2096 /// increment operator (needed for range-based for)
2097 iteration_proxy_internal& operator++()
2098 {
2099 ++anchor;
2100 ++array_index;
2101
2102 return *this;
2103 }
2104
2105 /// inequality operator (needed for range-based for)
2106 bool operator!=(const iteration_proxy_internal& o) const noexcept
2107 {
2108 return anchor != o.anchor;
2109 }
2110
2111 /// return key of the iterator
2112 std::string key() const
2113 {
2114 assert(anchor.m_object != nullptr);
2115
2116 switch (anchor.m_object->type())
2117 {
2118 // use integer array index as key
2119 case value_t::array:
2120 return std::to_string(array_index);
2121
2122 // use key from the object
2123 case value_t::object:
2124 return std::string{anchor.key()};
2125
2126 // use an empty key for all primitive types
2127 default:
2128 return "";
2129 }
2130 }
2131
2132 /// return value of the iterator
2133 typename IteratorType::reference value() const
2134 {
2135 return anchor.value();
2136 }
2137 };
2138
2139 /// the container to iterate
2140 typename IteratorType::reference container;
2141
2142 public:
2143 /// construct iteration proxy from a container
2144 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
2145 : container(cont) {}
2146
2147 /// return iterator begin (needed for range-based for)
2148 iteration_proxy_internal begin() noexcept
2149 {
2150 return iteration_proxy_internal(container.begin());
2151 }
2152
2153 /// return iterator end (needed for range-based for)
2154 iteration_proxy_internal end() noexcept
2155 {
2156 return iteration_proxy_internal(container.end());
2157 }
2158};
2159
2160//////////////////////
2161// reverse_iterator //
2162//////////////////////
2163
2164/*!
2165@brief a template for a reverse iterator class
2166
2167@tparam Base the base iterator type to reverse. Valid types are @ref
2168iterator (to create @ref reverse_iterator) and @ref const_iterator (to
2169create @ref const_reverse_iterator).
2170
2171@requirement The class satisfies the following concept requirements:
2172-
2173[BidirectionalIterator](http://en.cppreference.com/w/cpp/concept/BidirectionalIterator):
2174 The iterator that can be moved can be moved in both directions (i.e.
2175 incremented and decremented).
2176- [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
2177 It is possible to write to the pointed-to element (only if @a Base is
2178 @ref iterator).
2179
2180@since version 1.0.0
2181*/
2182template<typename Base>
2183class json_reverse_iterator : public std::reverse_iterator<Base>
2184{
2185 public:
2186 using difference_type = std::ptrdiff_t;
2187 /// shortcut to the reverse iterator adapter
2188 using base_iterator = std::reverse_iterator<Base>;
2189 /// the reference type for the pointed-to element
2190 using reference = typename Base::reference;
2191
2192 /// create reverse iterator from iterator
2193 json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
2194 : base_iterator(it) {}
2195
2196 /// create reverse iterator from base class
2198
2199 /// post-increment (it++)
2201 {
2202 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
2203 }
2204
2205 /// pre-increment (++it)
2207 {
2208 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
2209 }
2210
2211 /// post-decrement (it--)
2213 {
2214 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
2215 }
2216
2217 /// pre-decrement (--it)
2219 {
2220 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
2221 }
2222
2223 /// add to iterator
2225 {
2226 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
2227 }
2228
2229 /// add to iterator
2231 {
2232 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
2233 }
2234
2235 /// subtract from iterator
2237 {
2238 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
2239 }
2240
2241 /// return difference
2243 {
2244 return base_iterator(*this) - base_iterator(other);
2245 }
2246
2247 /// access to successor
2249 {
2250 return *(this->operator+(n));
2251 }
2252
2253 /// return the key of an object iterator
2254 auto key() const -> decltype(std::declval<Base>().key())
2255 {
2256 auto it = --this->base();
2257 return it.key();
2258 }
2259
2260 /// return the value of an iterator
2262 {
2263 auto it = --this->base();
2264 return it.operator * ();
2265 }
2266};
2267
2268template<typename BasicJsonType>
2270{
2271 public:
2272 using value_type = BasicJsonType;
2273
2275 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
2276 {}
2277
2279 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
2280 {}
2281
2282 json_ref(std::initializer_list<json_ref> init)
2283 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
2284 {}
2285
2286 template<class... Args>
2287 json_ref(Args&& ... args)
2288 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value), is_rvalue(true)
2289 {}
2290
2291 // class should be movable only
2292 json_ref(json_ref&&) = default;
2293 json_ref(const json_ref&) = delete;
2294 json_ref& operator=(const json_ref&) = delete;
2295
2297 {
2298 if (is_rvalue)
2299 {
2300 return std::move(*value_ref);
2301 }
2302 return *value_ref;
2303 }
2304
2305 value_type const& operator*() const
2306 {
2307 return *static_cast<value_type const*>(value_ref);
2308 }
2309
2310 value_type const* operator->() const
2311 {
2312 return static_cast<value_type const*>(value_ref);
2313 }
2314
2315 private:
2316 mutable value_type owned_value = nullptr;
2317 value_type* value_ref = nullptr;
2318 const bool is_rvalue;
2319};
2320} // namespace detail
2321
2323{
2324 // allow json to access private members
2325 friend class json;
2326 friend class JsonTest;
2327
2328 public:
2329 /*!
2330 @brief create JSON pointer
2331
2332 Create a JSON pointer according to the syntax described in
2333 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
2334
2335 @param[in] s string representing the JSON pointer; if omitted, the empty
2336 string is assumed which references the whole JSON value
2337
2338 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
2339 not begin with a slash (`/`); see example below
2340
2341 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
2342 not followed by `0` (representing `~`) or `1` (representing `/`); see
2343 example below
2344
2345 @liveexample{The example shows the construction several valid JSON pointers
2346 as well as the exceptional behavior.,json_pointer}
2347
2348 @since version 2.0.0
2349 */
2351 : reference_tokens(split(s))
2352 {}
2353
2354 /*!
2355 @brief return a string representation of the JSON pointer
2356
2357 @invariant For each JSON pointer `ptr`, it holds:
2358 @code {.cpp}
2359 ptr == json_pointer(ptr.to_string());
2360 @endcode
2361
2362 @return a string representation of the JSON pointer
2363
2364 @liveexample{The example shows the result of `to_string`.,
2365 json_pointer__to_string}
2366
2367 @since version 2.0.0
2368 */
2369 std::string to_string() const noexcept;
2370
2371 /// @copydoc to_string()
2372 operator std::string() const
2373 {
2374 return to_string();
2375 }
2376
2377 /*!
2378 @param[in] s reference token to be converted into an array index
2379
2380 @return integer representation of @a s
2381
2382 @throw out_of_range.404 if string @a s could not be converted to an integer
2383 */
2385
2386 private:
2387 /*!
2388 @brief remove and return last reference pointer
2389 @throw out_of_range.405 if JSON pointer has no parent
2390 */
2391 std::string pop_back()
2392 {
2393 if (JSON_UNLIKELY(is_root()))
2394 {
2395 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
2396 }
2397
2398 auto last = reference_tokens.back();
2399 reference_tokens.pop_back();
2400 return last;
2401 }
2402
2403 /// return whether pointer points to the root document
2404 bool is_root() const
2405 {
2406 return reference_tokens.empty();
2407 }
2408
2409 json_pointer top() const
2410 {
2411 if (JSON_UNLIKELY(is_root()))
2412 {
2413 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
2414 }
2415
2416 json_pointer result = *this;
2417 result.reference_tokens = {reference_tokens[0]};
2418 return result;
2419 }
2420
2421 /*!
2422 @brief create and return a reference to the pointed to value
2423
2424 @complexity Linear in the number of reference tokens.
2425
2426 @throw parse_error.109 if array index is not a number
2427 @throw type_error.313 if value cannot be unflattened
2428 */
2429 json& get_and_create(json& j) const;
2430
2431 /*!
2432 @brief return a reference to the pointed to value
2433
2434 @note This version does not throw if a value is not present, but tries to
2435 create nested values instead. For instance, calling this function
2436 with pointer `"/this/that"` on a null value is equivalent to calling
2437 `operator[]("this").operator[]("that")` on that value, effectively
2438 changing the null value to an object.
2439
2440 @param[in] ptr a JSON value
2441
2442 @return reference to the JSON value pointed to by the JSON pointer
2443
2444 @complexity Linear in the length of the JSON pointer.
2445
2446 @throw parse_error.106 if an array index begins with '0'
2447 @throw parse_error.109 if an array index was not a number
2448 @throw out_of_range.404 if the JSON pointer can not be resolved
2449 */
2450 json& get_unchecked(json* ptr) const;
2451
2452 /*!
2453 @throw parse_error.106 if an array index begins with '0'
2454 @throw parse_error.109 if an array index was not a number
2455 @throw out_of_range.402 if the array index '-' is used
2456 @throw out_of_range.404 if the JSON pointer can not be resolved
2457 */
2458 json& get_checked(json* ptr) const;
2459
2460 /*!
2461 @brief return a const reference to the pointed to value
2462
2463 @param[in] ptr a JSON value
2464
2465 @return const reference to the JSON value pointed to by the JSON
2466 pointer
2467
2468 @throw parse_error.106 if an array index begins with '0'
2469 @throw parse_error.109 if an array index was not a number
2470 @throw out_of_range.402 if the array index '-' is used
2471 @throw out_of_range.404 if the JSON pointer can not be resolved
2472 */
2473 const json& get_unchecked(const json* ptr) const;
2474
2475 /*!
2476 @throw parse_error.106 if an array index begins with '0'
2477 @throw parse_error.109 if an array index was not a number
2478 @throw out_of_range.402 if the array index '-' is used
2479 @throw out_of_range.404 if the JSON pointer can not be resolved
2480 */
2481 const json& get_checked(const json* ptr) const;
2482
2483 /*!
2484 @brief split the string input to reference tokens
2485
2486 @note This function is only called by the json_pointer constructor.
2487 All exceptions below are documented there.
2488
2489 @throw parse_error.107 if the pointer is not empty or begins with '/'
2490 @throw parse_error.108 if character '~' is not followed by '0' or '1'
2491 */
2492 static std::vector<std::string> split(std::string_view reference_string);
2493
2494 /*!
2495 @brief replace all occurrences of a substring by another string
2496
2497 @param[in,out] s the string to manipulate; changed so that all
2498 occurrences of @a f are replaced with @a t
2499 @param[in] f the substring to replace with @a t
2500 @param[in] t the string to replace @a f
2501
2502 @pre The search string @a f must not be empty. **This precondition is
2503 enforced with an assertion.**
2504
2505 @since version 2.0.0
2506 */
2507 static void replace_substring(std::string& s, const std::string& f,
2508 const std::string& t);
2509
2510 /// escape "~"" to "~0" and "/" to "~1"
2511 static std::string escape(std::string s);
2512
2513 /// unescape "~1" to tilde and "~0" to slash (order is important!)
2514 static void unescape(std::string& s);
2515
2516 /*!
2517 @param[in] reference_string the reference string to the current value
2518 @param[in] value the value to consider
2519 @param[in,out] result the result object to insert values to
2520
2521 @note Empty objects or arrays are flattened to `null`.
2522 */
2523 static void flatten(std::string_view reference_string,
2524 const json& value,
2525 json& result);
2526
2527 /*!
2528 @param[in] value flattened JSON
2529
2530 @return unflattened JSON
2531
2532 @throw parse_error.109 if array index is not a number
2533 @throw type_error.314 if value is not an object
2534 @throw type_error.315 if object values are not primitive
2535 @throw type_error.313 if value cannot be unflattened
2536 */
2537 static json
2538 unflatten(const json& value);
2539
2540 friend bool operator==(json_pointer const& lhs,
2541 json_pointer const& rhs) noexcept
2542 {
2543 return (lhs.reference_tokens == rhs.reference_tokens);
2544 }
2545
2546 friend bool operator!=(json_pointer const& lhs,
2547 json_pointer const& rhs) noexcept
2548 {
2549 return not (lhs == rhs);
2550 }
2551
2552 /// the reference tokens
2553 std::vector<std::string> reference_tokens;
2554};
2555
2556template<typename, typename>
2558{
2559 /*!
2560 @brief convert a JSON value to any value type
2561
2562 This function is usually called by the `get()` function of the
2563 @ref json class (either explicit or via conversion operators).
2564
2565 @param[in] j JSON value to read from
2566 @param[in,out] val value to write to
2567 */
2568 template<typename BasicJsonType, typename ValueType>
2569 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
2570 noexcept(::wpi::from_json(std::forward<BasicJsonType>(j), val)))
2571 {
2572 ::wpi::from_json(std::forward<BasicJsonType>(j), val);
2573 }
2574
2575 /*!
2576 @brief convert any value type to a JSON value
2577
2578 This function is usually called by the constructors of the @ref json
2579 class.
2580
2581 @param[in,out] j JSON value to write to
2582 @param[in] val value to read from
2583 */
2584 template<typename BasicJsonType, typename ValueType>
2585 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
2586 noexcept(::wpi::to_json(j, std::forward<ValueType>(val))))
2587 {
2588 ::wpi::to_json(j, std::forward<ValueType>(val));
2589 }
2590};
2591
2592/*!
2593@brief a class to store JSON values
2594
2595@requirement The class satisfies the following concept requirements:
2596- Basic
2597 - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
2598 JSON values can be default constructed. The result will be a JSON null
2599 value.
2600 - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
2601 A JSON value can be constructed from an rvalue argument.
2602 - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
2603 A JSON value can be copy-constructed from an lvalue expression.
2604 - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
2605 A JSON value van be assigned from an rvalue argument.
2606 - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
2607 A JSON value can be copy-assigned from an lvalue expression.
2608 - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
2609 JSON values can be destructed.
2610- Layout
2611 - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
2612 JSON values have
2613 [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
2614 All non-static data members are private and standard layout types, the
2615 class has no virtual functions or (virtual) base classes.
2616- Library-wide
2617 - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
2618 JSON values can be compared with `==`, see @ref
2619 operator==(const_reference,const_reference).
2620 - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
2621 JSON values can be compared with `<`, see @ref
2622 operator<(const_reference,const_reference).
2623 - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
2624 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
2625 other compatible types, using unqualified function call @ref swap().
2626 - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
2627 JSON values can be compared against `std::nullptr_t` objects which are used
2628 to model the `null` value.
2629- Container
2630 - [Container](http://en.cppreference.com/w/cpp/concept/Container):
2631 JSON values can be used like STL containers and provide iterator access.
2632 - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
2633 JSON values can be used like STL containers and provide reverse iterator
2634 access.
2635
2636@invariant The member variables @a m_value and @a m_type have the following
2637relationship:
2638- If `m_type == value_t::object`, then `m_value.object != nullptr`.
2639- If `m_type == value_t::array`, then `m_value.array != nullptr`.
2640- If `m_type == value_t::string`, then `m_value.string != nullptr`.
2641The invariants are checked by member function assert_invariant().
2642
2643@internal
2644@note ObjectType trick from http://stackoverflow.com/a/9860911
2645@endinternal
2646
2647@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
2648Format](http://rfc7159.net/rfc7159)
2649
2650@since version 1.0.0
2651
2652@nosubgrouping
2653*/
2654class json
2655{
2656 private:
2657 template<detail::value_t> friend struct detail::external_constructor;
2658 friend ::wpi::json_pointer;
2659 template<typename BasicJsonType>
2660 friend class ::wpi::detail::iter_impl;
2661 friend class JsonTest;
2662
2663 /// workaround type for MSVC
2664 using json_t = json;
2665
2666 // convenience aliases for types residing in namespace detail;
2668 template<typename BasicJsonType>
2670 template<typename BasicJsonType>
2672 template<typename Iterator>
2675
2676 class binary_reader;
2677 class binary_writer;
2678 class lexer;
2679 class parser;
2680
2681 public:
2682 class serializer;
2683
2685 /// @copydoc wpi::json_pointer
2687 template<typename T, typename SFINAE>
2689 /// helper type for initializer lists of json values
2690 using initializer_list_t = std::initializer_list<detail::json_ref<json>>;
2691
2692 ////////////////
2693 // exceptions //
2694 ////////////////
2695
2696 /// @name exceptions
2697 /// Classes to implement user-defined exceptions.
2698 /// @{
2699
2700 /// @copydoc detail::exception
2702 /// @copydoc detail::parse_error
2704 /// @copydoc detail::invalid_iterator
2706 /// @copydoc detail::type_error
2708 /// @copydoc detail::out_of_range
2710 /// @copydoc detail::other_error
2712
2713 /// @}
2714
2715
2716 /////////////////////
2717 // container types //
2718 /////////////////////
2719
2720 /// @name container types
2721 /// The canonic container types to use @ref json like any other STL
2722 /// container.
2723 /// @{
2724
2725 /// the type of elements in a json container
2727
2728 /// the type of an element reference
2730 /// the type of an element const reference
2732
2733 /// a type to represent differences between iterators
2734 using difference_type = std::ptrdiff_t;
2735 /// a type to represent container sizes
2736 using size_type = std::size_t;
2737
2738 /// the allocator type
2739 using allocator_type = std::allocator<json>;
2740
2741 /// the type of an element pointer
2742 using pointer = json*;
2743 /// the type of an element const pointer
2744 using const_pointer = const json*;
2745
2746 /// an iterator for a json container
2748 /// a const iterator for a json container
2750 /// a reverse iterator for a json container
2752 /// a const reverse iterator for a json container
2754
2755 /// @}
2756
2757
2758 /*!
2759 @brief returns the allocator associated with the container
2760 */
2762 {
2763 return allocator_type();
2764 }
2765
2766 /*!
2767 @brief returns version information on the library
2768
2769 This function returns a JSON object with information about the library,
2770 including the version number and information on the platform and compiler.
2771
2772 @return JSON object holding version information
2773 key | description
2774 ----------- | ---------------
2775 `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).
2776 `copyright` | The copyright line for the library as string.
2777 `name` | The name of the library as string.
2778 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
2779 `url` | The URL of the project as string.
2780 `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).
2781
2782 @liveexample{The following code shows an example output of the `meta()`
2783 function.,meta}
2784
2785 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
2786 changes to any JSON value.
2787
2788 @complexity Constant.
2789
2790 @since 2.1.0
2791 */
2792 static json meta();
2793
2794
2795 ///////////////////////////
2796 // JSON value data types //
2797 ///////////////////////////
2798
2799 /// @name JSON value data types
2800 /// The data types to store a JSON value. These types are derived from
2801 /// the template arguments passed to class @ref json.
2802 /// @{
2803
2804 // Use transparent comparator if possible, combined with perfect forwarding
2805 // on find() and count() calls prevents unnecessary string construction.
2806 using object_comparator_t = std::less<>;
2807
2808 /*!
2809 @brief a type for an object
2810
2811 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
2812 > An object is an unordered collection of zero or more name/value pairs,
2813 > where a name is a string and a value is a string, number, boolean, null,
2814 > object, or array.
2815
2816 #### Behavior
2817
2818 The choice of @a object_t influences the behavior of the JSON class. With
2819 the default type, objects have the following behavior:
2820
2821 - When all names are unique, objects will be interoperable in the sense
2822 that all software implementations receiving that object will agree on
2823 the name-value mappings.
2824 - When the names within an object are not unique, it is unspecified which
2825 one of the values for a given key will be chosen. For instance,
2826 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
2827 `{"key": 2}`.
2828 - Internally, name/value pairs are stored in lexicographical order of the
2829 names. Objects will also be serialized (see @ref dump) in this order.
2830 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
2831 and serialized as `{"a": 2, "b": 1}`.
2832 - When comparing objects, the order of the name/value pairs is irrelevant.
2833 This makes objects interoperable in the sense that they will not be
2834 affected by these differences. For instance, `{"b": 1, "a": 2}` and
2835 `{"a": 2, "b": 1}` will be treated as equal.
2836
2837 #### Limits
2838
2839 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
2840 > An implementation may set limits on the maximum depth of nesting.
2841
2842 In this class, the object's limit of nesting is not explicitly constrained.
2843 However, a maximum depth of nesting may be introduced by the compiler or
2844 runtime environment. A theoretical limit can be queried by calling the
2845 @ref max_size function of a JSON object.
2846
2847 #### Storage
2848
2849 Objects are stored as pointers in a @ref json type. That is, for any
2850 access to object values, a pointer of type `object_t*` must be
2851 dereferenced.
2852
2853 @since version 1.0.0
2854
2855 @note The order name/value pairs are added to the object is *not*
2856 preserved by the library. Therefore, iterating an object may return
2857 name/value pairs in a different order than they were originally stored. In
2858 fact, keys will be traversed in alphabetical order as `std::map` with
2859 `std::less` is used by default. Please note this behavior conforms to [RFC
2860 7159](http://rfc7159.net/rfc7159), because any order implements the
2861 specified "unordered" nature of JSON objects.
2862 */
2864
2865 /*!
2866 @brief a type for an array
2867
2868 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
2869 > An array is an ordered sequence of zero or more values.
2870
2871 #### Limits
2872
2873 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
2874 > An implementation may set limits on the maximum depth of nesting.
2875
2876 In this class, the array's limit of nesting is not explicitly constrained.
2877 However, a maximum depth of nesting may be introduced by the compiler or
2878 runtime environment. A theoretical limit can be queried by calling the
2879 @ref max_size function of a JSON array.
2880
2881 #### Storage
2882
2883 Arrays are stored as pointers in a @ref json type. That is, for any
2884 access to array values, a pointer of type `array_t*` must be dereferenced.
2885
2886 @sa @ref object_t -- type for an object value
2887
2888 @since version 1.0.0
2889 */
2890 using array_t = std::vector<json>;
2891
2892 /// @}
2893
2894 private:
2895
2896 /// helper for exception-safe object creation
2897 template<typename T, typename... Args>
2898 static T* create(Args&& ... args)
2899 {
2900 std::allocator<T> alloc;
2901
2902 using AllocatorTraits = std::allocator_traits<std::allocator<T>>;
2903
2904 auto deleter = [&](T * object)
2905 {
2906 AllocatorTraits::deallocate(alloc, object, 1);
2907 };
2908 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
2909 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
2910 assert(object != nullptr);
2911 return object.release();
2912 }
2913
2914 ////////////////////////
2915 // JSON value storage //
2916 ////////////////////////
2917
2918 /*!
2919 @brief a JSON value
2920
2921 The actual storage for a JSON value of the @ref json class. This
2922 union combines the different storage types for the JSON value types
2923 defined in @ref value_t.
2924
2925 JSON type | value_t type | used type
2926 --------- | --------------- | ------------------------
2927 object | object | pointer to @ref object_t
2928 array | array | pointer to @ref array_t
2929 string | string | pointer to std::string
2930 boolean | boolean | bool
2931 number | number_integer | int64_t
2932 number | number_unsigned | uint64_t
2933 number | number_float | double
2934 null | null | *no value is stored*
2935
2936 @note Variable-length types (objects, arrays, and strings) are stored as
2937 pointers. The size of the union should not exceed 64 bits if the default
2938 value types are used.
2939
2940 @since version 1.0.0
2941 */
2942 union json_value
2943 {
2944 /// object (stored with pointer to save storage)
2946 /// array (stored with pointer to save storage)
2947 array_t* array;
2948 /// string (stored with pointer to save storage)
2949 std::string* string;
2950 /// boolean
2951 bool boolean;
2952 /// number (integer)
2953 int64_t number_integer;
2954 /// number (unsigned integer)
2955 uint64_t number_unsigned;
2956 /// number (floating-point)
2957 double number_float;
2958
2959 /// default constructor (for null values)
2960 json_value() = default;
2961 /// constructor for booleans
2962 json_value(bool v) noexcept : boolean(v) {}
2963 /// constructor for numbers (integer)
2964 json_value(int64_t v) noexcept : number_integer(v) {}
2965 /// constructor for numbers (unsigned)
2966 json_value(uint64_t v) noexcept : number_unsigned(v) {}
2967 /// constructor for numbers (floating-point)
2968 json_value(double v) noexcept : number_float(v) {}
2969 /// constructor for empty values of a given type
2970 json_value(value_t t);
2971
2972 /// constructor for strings
2973 json_value(std::string_view value)
2974 {
2975 string = create<std::string>(value);
2976 }
2977
2978 /// constructor for strings
2979 json_value(const std::string& value)
2980 {
2981 string = create<std::string>(value);
2982 }
2983
2984 /// constructor for rvalue strings
2985 json_value(std::string&& value)
2986 {
2987 string = create<std::string>(std::move(value));
2988 }
2989
2990 /// constructor for objects
2991 json_value(const object_t& value)
2992 {
2993 object = create<object_t>(value);
2994 }
2995
2996 /// constructor for rvalue objects
2997 json_value(object_t&& value)
2998 {
2999 object = create<object_t>(std::move(value));
3000 }
3001
3002 /// constructor for arrays
3003 json_value(const array_t& value)
3004 {
3005 array = create<array_t>(value);
3006 }
3007
3008 /// constructor for rvalue arrays
3009 json_value(array_t&& value)
3010 {
3011 array = create<array_t>(std::move(value));
3012 }
3013
3014 void destroy(value_t t) noexcept;
3015 };
3016
3017 /*!
3018 @brief checks the class invariants
3019
3020 This function asserts the class invariants. It needs to be called at the
3021 end of every constructor to make sure that created objects respect the
3022 invariant. Furthermore, it has to be called each time the type of a JSON
3023 value is changed, because the invariant expresses a relationship between
3024 @a m_type and @a m_value.
3025 */
3026 void assert_invariant() const noexcept
3027 {
3028 assert(m_type != value_t::object or m_value.object != nullptr);
3029 assert(m_type != value_t::array or m_value.array != nullptr);
3030 assert(m_type != value_t::string or m_value.string != nullptr);
3031 }
3032
3033 public:
3034 //////////////////////////
3035 // JSON parser callback //
3036 //////////////////////////
3037
3038 /*!
3039 @brief parser event types
3040
3041 The parser callback distinguishes the following events:
3042 - `object_start`: the parser read `{` and started to process a JSON object
3043 - `key`: the parser read a key of a value in an object
3044 - `object_end`: the parser read `}` and finished processing a JSON object
3045 - `array_start`: the parser read `[` and started to process a JSON array
3046 - `array_end`: the parser read `]` and finished processing a JSON array
3047 - `value`: the parser finished reading a JSON value
3048
3049 @image html callback_events.png "Example when certain parse events are triggered"
3050
3051 @sa @ref parser_callback_t for more information and examples
3052 */
3054 {
3055 /// the parser read `{` and started to process a JSON object
3056 object_start,
3057 /// the parser read `}` and finished processing a JSON object
3058 object_end,
3059 /// the parser read `[` and started to process a JSON array
3060 array_start,
3061 /// the parser read `]` and finished processing a JSON array
3062 array_end,
3063 /// the parser read a key of a value in an object
3064 key,
3065 /// the parser finished reading a JSON value
3066 value
3067 };
3068
3069 /*!
3070 @brief per-element parser callback type
3071
3072 With a parser callback function, the result of parsing a JSON text can be
3073 influenced. When passed to @ref parse, it is called on certain events
3074 (passed as @ref parse_event_t via parameter @a event) with a set recursion
3075 depth @a depth and context JSON value @a parsed. The return value of the
3076 callback function is a boolean indicating whether the element that emitted
3077 the callback shall be kept or not.
3078
3079 We distinguish six scenarios (determined by the event type) in which the
3080 callback function can be called. The following table describes the values
3081 of the parameters @a depth, @a event, and @a parsed.
3082
3083 parameter @a event | description | parameter @a depth | parameter @a parsed
3084 ------------------ | ----------- | ------------------ | -------------------
3085 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
3086 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
3087 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
3088 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
3089 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
3090 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
3091
3092 @image html callback_events.png "Example when certain parse events are triggered"
3093
3094 Discarding a value (i.e., returning `false`) has different effects
3095 depending on the context in which function was called:
3096
3097 - Discarded values in structured types are skipped. That is, the parser
3098 will behave as if the discarded value was never read.
3099 - In case a value outside a structured type is skipped, it is replaced
3100 with `null`. This case happens if the top-level element is skipped.
3101
3102 @param[in] depth the depth of the recursion during parsing
3103
3104 @param[in] event an event of type parse_event_t indicating the context in
3105 the callback function has been called
3106
3107 @param[in,out] parsed the current intermediate parse result; note that
3108 writing to this value has no effect for parse_event_t::key events
3109
3110 @return Whether the JSON value which called the function during parsing
3111 should be kept (`true`) or not (`false`). In the latter case, it is either
3112 skipped completely or replaced by an empty discarded object.
3113
3114 @sa @ref parse for examples
3115
3116 @since version 1.0.0
3117 */
3119 std::function<bool(int depth, parse_event_t event, json& parsed)>;
3120
3121
3122 //////////////////
3123 // constructors //
3124 //////////////////
3125
3126 /// @name constructors and destructors
3127 /// Constructors of class @ref json, copy/move constructor, copy
3128 /// assignment, static functions creating objects, and the destructor.
3129 /// @{
3130
3131 /*!
3132 @brief create an empty value with a given type
3133
3134 Create an empty JSON value with a given type. The value will be default
3135 initialized with an empty value which depends on the type:
3136
3137 Value type | initial value
3138 ----------- | -------------
3139 null | `null`
3140 boolean | `false`
3141 string | `""`
3142 number | `0`
3143 object | `{}`
3144 array | `[]`
3145
3146 @param[in] v the type of the value to create
3147
3148 @complexity Constant.
3149
3150 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3151 changes to any JSON value.
3152
3153 @liveexample{The following code shows the constructor for different @ref
3154 value_t values,json__value_t}
3155
3156 @sa @ref clear() -- restores the postcondition of this constructor
3157
3158 @since version 1.0.0
3159 */
3160 json(const value_t v)
3161 : m_type(v), m_value(v)
3162 {
3163 assert_invariant();
3164 }
3165
3166 /*!
3167 @brief create a null object
3168
3169 Create a `null` JSON value. It either takes a null pointer as parameter
3170 (explicitly creating `null`) or no parameter (implicitly creating `null`).
3171 The passed null pointer itself is not read -- it is only used to choose
3172 the right constructor.
3173
3174 @complexity Constant.
3175
3176 @exceptionsafety No-throw guarantee: this constructor never throws
3177 exceptions.
3178
3179 @liveexample{The following code shows the constructor with and without a
3180 null pointer parameter.,json__nullptr_t}
3181
3182 @since version 1.0.0
3183 */
3184 json(std::nullptr_t = nullptr) noexcept
3185 : json(value_t::null)
3186 {
3187 assert_invariant();
3188 }
3189
3190 /*!
3191 @brief create a JSON value
3192
3193 This is a "catch all" constructor for all compatible JSON types; that is,
3194 types for which a `to_json()` method exists. The constructor forwards the
3195 parameter @a val to that method (to `json_serializer<U>::to_json` method
3196 with `U = uncvref_t<CompatibleType>`, to be exact).
3197
3198 Template type @a CompatibleType includes, but is not limited to, the
3199 following types:
3200 - **arrays**: @ref array_t and all kinds of compatible containers such as
3201 `std::vector`, `std::deque`, `std::list`,
3202 `std::array`, `std::set`, `std::unordered_set`,
3203 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
3204 which a @ref json value can be constructed.
3205 - **objects**: @ref object_t and all kinds of compatible associative
3206 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
3207 and `std::unordered_multimap` with a `key_type` compatible to
3208 `std::string` and a `value_type` from which a @ref json value can
3209 be constructed.
3210 - **strings**: `std::string`, string literals, and all compatible string
3211 containers can be used.
3212 - **numbers**: int64_t, uint64_t,
3213 double, and all convertible number types such as `int`,
3214 `size_t`, `int64_t`, `float` or `double` can be used.
3215 - **boolean**: `bool` can be used.
3216
3217 See the examples below.
3218
3219 @tparam CompatibleType a type such that:
3220 - @a CompatibleType is not derived from `std::istream`,
3221 - @a CompatibleType is not @ref json (to avoid hijacking copy/move
3222 constructors),
3223 - @a CompatibleType is not a different @ref json type (i.e. with different template arguments)
3224 - @a CompatibleType is not a @ref json nested type (e.g.,
3225 @ref json_pointer, @ref iterator, etc ...)
3226 - @ref @ref json_serializer<U> has a
3227 `to_json(json_t&, CompatibleType&&)` method
3228
3229 @tparam U = `uncvref_t<CompatibleType>`
3230
3231 @param[in] val the value to be forwarded to the respective constructor
3232
3233 @complexity Usually linear in the size of the passed @a val, also
3234 depending on the implementation of the called `to_json()`
3235 method.
3236
3237 @exceptionsafety Depends on the called constructor. For types directly
3238 supported by the library (i.e., all types for which no `to_json()` function
3239 was provided), strong guarantee holds: if an exception is thrown, there are
3240 no changes to any JSON value.
3241
3242 @liveexample{The following code shows the constructor with several
3243 compatible types.,json__CompatibleType}
3244
3245 @since version 2.1.0
3246 */
3247 template <typename CompatibleType,
3251 json(CompatibleType && val) noexcept(noexcept(
3252 adl_serializer<U, void>::to_json(std::declval<json_t&>(),
3253 std::forward<CompatibleType>(val))))
3254 {
3255 adl_serializer<U, void>::to_json(*this, std::forward<CompatibleType>(val));
3256 assert_invariant();
3257 }
3258
3259 /*!
3260 @brief create a container (array or object) from an initializer list
3261
3262 Creates a JSON value of type array or object from the passed initializer
3263 list @a init. In case @a type_deduction is `true` (default), the type of
3264 the JSON value to be created is deducted from the initializer list @a init
3265 according to the following rules:
3266
3267 1. If the list is empty, an empty JSON object value `{}` is created.
3268 2. If the list consists of pairs whose first element is a string, a JSON
3269 object value is created where the first elements of the pairs are
3270 treated as keys and the second elements are as values.
3271 3. In all other cases, an array is created.
3272
3273 The rules aim to create the best fit between a C++ initializer list and
3274 JSON values. The rationale is as follows:
3275
3276 1. The empty initializer list is written as `{}` which is exactly an empty
3277 JSON object.
3278 2. C++ has no way of describing mapped types other than to list a list of
3279 pairs. As JSON requires that keys must be of type string, rule 2 is the
3280 weakest constraint one can pose on initializer lists to interpret them
3281 as an object.
3282 3. In all other cases, the initializer list could not be interpreted as
3283 JSON object type, so interpreting it as JSON array type is safe.
3284
3285 With the rules described above, the following JSON values cannot be
3286 expressed by an initializer list:
3287
3288 - the empty array (`[]`): use @ref array(initializer_list_t)
3289 with an empty initializer list in this case
3290 - arrays whose elements satisfy rule 2: use @ref
3291 array(initializer_list_t) with the same initializer list
3292 in this case
3293
3294 @note When used without parentheses around an empty initializer list, @ref
3295 json() is called instead of this function, yielding the JSON null
3296 value.
3297
3298 @param[in] init initializer list with JSON values
3299
3300 @param[in] type_deduction internal parameter; when set to `true`, the type
3301 of the JSON value is deducted from the initializer list @a init; when set
3302 to `false`, the type provided via @a manual_type is forced. This mode is
3303 used by the functions @ref array(initializer_list_t) and
3304 @ref object(initializer_list_t).
3305
3306 @param[in] manual_type internal parameter; when @a type_deduction is set
3307 to `false`, the created JSON value will use the provided type (only @ref
3308 value_t::array and @ref value_t::object are valid); when @a type_deduction
3309 is set to `true`, this parameter has no effect
3310
3311 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
3312 `value_t::object`, but @a init contains an element which is not a pair
3313 whose first element is a string. In this case, the constructor could not
3314 create an object. If @a type_deduction would have be `true`, an array
3315 would have been created. See @ref object(initializer_list_t)
3316 for an example.
3317
3318 @complexity Linear in the size of the initializer list @a init.
3319
3320 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3321 changes to any JSON value.
3322
3323 @liveexample{The example below shows how JSON values are created from
3324 initializer lists.,json__list_init_t}
3325
3326 @sa @ref array(initializer_list_t) -- create a JSON array
3327 value from an initializer list
3328 @sa @ref object(initializer_list_t) -- create a JSON object
3329 value from an initializer list
3330
3331 @since version 1.0.0
3332 */
3334 bool type_deduction = true,
3335 value_t manual_type = value_t::array);
3336
3337 /*!
3338 @brief explicitly create an array from an initializer list
3339
3340 Creates a JSON array value from a given initializer list. That is, given a
3341 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
3342 initializer list is empty, the empty array `[]` is created.
3343
3344 @note This function is only needed to express two edge cases that cannot
3345 be realized with the initializer list constructor (@ref
3346 json(initializer_list_t, bool, value_t)). These cases
3347 are:
3348 1. creating an array whose elements are all pairs whose first element is a
3349 string -- in this case, the initializer list constructor would create an
3350 object, taking the first elements as keys
3351 2. creating an empty array -- passing the empty initializer list to the
3352 initializer list constructor yields an empty object
3353
3354 @param[in] init initializer list with JSON values to create an array from
3355 (optional)
3356
3357 @return JSON array value
3358
3359 @complexity Linear in the size of @a init.
3360
3361 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3362 changes to any JSON value.
3363
3364 @liveexample{The following code shows an example for the `array`
3365 function.,array}
3366
3367 @sa @ref json(initializer_list_t, bool, value_t) --
3368 create a JSON value from an initializer list
3369 @sa @ref object(initializer_list_t) -- create a JSON object
3370 value from an initializer list
3371
3372 @since version 1.0.0
3373 */
3375 {
3376 return json(init, false, value_t::array);
3377 }
3378
3379 /*!
3380 @brief explicitly create an object from an initializer list
3381
3382 Creates a JSON object value from a given initializer list. The initializer
3383 lists elements must be pairs, and their first elements must be strings. If
3384 the initializer list is empty, the empty object `{}` is created.
3385
3386 @note This function is only added for symmetry reasons. In contrast to the
3387 related function @ref array(initializer_list_t), there are
3388 no cases which can only be expressed by this function. That is, any
3389 initializer list @a init can also be passed to the initializer list
3390 constructor @ref json(initializer_list_t, bool, value_t).
3391
3392 @param[in] init initializer list to create an object from (optional)
3393
3394 @return JSON object value
3395
3396 @throw type_error.301 if @a init is not a list of pairs whose first
3397 elements are strings. In this case, no object can be created. When such a
3398 value is passed to @ref json(initializer_list_t, bool, value_t),
3399 an array would have been created from the passed initializer list @a init.
3400 See example below.
3401
3402 @complexity Linear in the size of @a init.
3403
3404 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3405 changes to any JSON value.
3406
3407 @liveexample{The following code shows an example for the `object`
3408 function.,object}
3409
3410 @sa @ref json(initializer_list_t, bool, value_t) --
3411 create a JSON value from an initializer list
3412 @sa @ref array(initializer_list_t) -- create a JSON array
3413 value from an initializer list
3414
3415 @since version 1.0.0
3416 */
3418 {
3419 return json(init, false, value_t::object);
3420 }
3421
3422 /*!
3423 @brief construct an array with count copies of given value
3424
3425 Constructs a JSON array value by creating @a cnt copies of a passed value.
3426 In case @a cnt is `0`, an empty array is created.
3427
3428 @param[in] cnt the number of JSON copies of @a val to create
3429 @param[in] val the JSON value to copy
3430
3431 @post `std::distance(begin(),end()) == cnt` holds.
3432
3433 @complexity Linear in @a cnt.
3434
3435 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3436 changes to any JSON value.
3437
3438 @liveexample{The following code shows examples for the @ref
3439 json(size_type\, const json&)
3440 constructor.,json__size_type_json}
3441
3442 @since version 1.0.0
3443 */
3444 json(size_type cnt, const json& val);
3445
3446 /*!
3447 @brief construct a JSON container given an iterator range
3448
3449 Constructs the JSON value with the contents of the range `[first, last)`.
3450 The semantics depends on the different types a JSON value can have:
3451 - In case of a null type, invalid_iterator.206 is thrown.
3452 - In case of other primitive types (number, boolean, or string), @a first
3453 must be `begin()` and @a last must be `end()`. In this case, the value is
3454 copied. Otherwise, invalid_iterator.204 is thrown.
3455 - In case of structured types (array, object), the constructor behaves as
3456 similar versions for `std::vector` or `std::map`; that is, a JSON array
3457 or object is constructed from the values in the range.
3458
3459 @tparam InputIT an input iterator type (@ref iterator or @ref
3460 const_iterator)
3461
3462 @param[in] first begin of the range to copy from (included)
3463 @param[in] last end of the range to copy from (excluded)
3464
3465 @pre Iterators @a first and @a last must be initialized. **This
3466 precondition is enforced with an assertion (see warning).** If
3467 assertions are switched off, a violation of this precondition yields
3468 undefined behavior.
3469
3470 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
3471 checked efficiently. Only certain edge cases are detected; see the
3472 description of the exceptions below. A violation of this precondition
3473 yields undefined behavior.
3474
3475 @warning A precondition is enforced with a runtime assertion that will
3476 result in calling `std::abort` if this precondition is not met.
3477 Assertions can be disabled by defining `NDEBUG` at compile time.
3478 See http://en.cppreference.com/w/cpp/error/assert for more
3479 information.
3480
3481 @throw invalid_iterator.201 if iterators @a first and @a last are not
3482 compatible (i.e., do not belong to the same JSON value). In this case,
3483 the range `[first, last)` is undefined.
3484 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
3485 primitive type (number, boolean, or string), but @a first does not point
3486 to the first element any more. In this case, the range `[first, last)` is
3487 undefined. See example code below.
3488 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
3489 null value. In this case, the range `[first, last)` is undefined.
3490
3491 @complexity Linear in distance between @a first and @a last.
3492
3493 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3494 changes to any JSON value.
3495
3496 @liveexample{The example below shows several ways to create JSON values by
3497 specifying a subrange with iterators.,json__InputIt_InputIt}
3498
3499 @since version 1.0.0
3500 */
3501 template<class InputIT, typename std::enable_if<
3502 std::is_same<InputIT, typename json_t::iterator>::value or
3503 std::is_same<InputIT, typename json_t::const_iterator>::value, int>::type = 0>
3504 json(InputIT first, InputIT last)
3505 {
3506 assert(first.m_object != nullptr);
3507 assert(last.m_object != nullptr);
3508
3509 // make sure iterator fits the current value
3510 if (JSON_UNLIKELY(first.m_object != last.m_object))
3511 {
3512 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
3513 }
3514
3515 // copy type from first iterator
3516 m_type = first.m_object->m_type;
3517
3518 // check if iterator range is complete for primitive values
3519 switch (m_type)
3520 {
3521 case value_t::boolean:
3525 case value_t::string:
3526 {
3527 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
3528 or not last.m_it.primitive_iterator.is_end()))
3529 {
3530 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
3531 }
3532 break;
3533 }
3534
3535 default:
3536 break;
3537 }
3538
3539 switch (m_type)
3540 {
3542 {
3543 m_value.number_integer = first.m_object->m_value.number_integer;
3544 break;
3545 }
3546
3548 {
3549 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
3550 break;
3551 }
3552
3554 {
3555 m_value.number_float = first.m_object->m_value.number_float;
3556 break;
3557 }
3558
3559 case value_t::boolean:
3560 {
3561 m_value.boolean = first.m_object->m_value.boolean;
3562 break;
3563 }
3564
3565 case value_t::string:
3566 {
3567 m_value = *first.m_object->m_value.string;
3568 break;
3569 }
3570
3571 case value_t::array:
3572 {
3573 m_value.array = create<array_t>(first.m_it.array_iterator,
3574 last.m_it.array_iterator);
3575 break;
3576 }
3577
3578 default:
3579 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from", first.m_object->type_name()));
3580 }
3581
3582 assert_invariant();
3583 }
3584
3585
3586 ///////////////////////////////////////
3587 // other constructors and destructor //
3588 ///////////////////////////////////////
3589
3590 /// @private
3591 json(const detail::json_ref<json>& ref)
3592 : json(ref.moved_or_copied())
3593 {}
3594
3595 /*!
3596 @brief copy constructor
3597
3598 Creates a copy of a given JSON value.
3599
3600 @param[in] other the JSON value to copy
3601
3602 @post `*this == other`
3603
3604 @complexity Linear in the size of @a other.
3605
3606 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3607 changes to any JSON value.
3608
3609 @requirement This function helps `json` satisfying the
3610 [Container](http://en.cppreference.com/w/cpp/concept/Container)
3611 requirements:
3612 - The complexity is linear.
3613 - As postcondition, it holds: `other == json(other)`.
3614
3615 @liveexample{The following code shows an example for the copy
3616 constructor.,json__json}
3617
3618 @since version 1.0.0
3619 */
3620 json(const json& other);
3621
3622 /*!
3623 @brief move constructor
3624
3625 Move constructor. Constructs a JSON value with the contents of the given
3626 value @a other using move semantics. It "steals" the resources from @a
3627 other and leaves it as JSON null value.
3628
3629 @param[in,out] other value to move to this object
3630
3631 @post `*this` has the same value as @a other before the call.
3632 @post @a other is a JSON null value.
3633
3634 @complexity Constant.
3635
3636 @exceptionsafety No-throw guarantee: this constructor never throws
3637 exceptions.
3638
3639 @requirement This function helps `json` satisfying the
3640 [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible)
3641 requirements.
3642
3643 @liveexample{The code below shows the move constructor explicitly called
3644 via std::move.,json__moveconstructor}
3645
3646 @since version 1.0.0
3647 */
3648 json(json&& other) noexcept
3649 : m_type(std::move(other.m_type)),
3650 m_value(std::move(other.m_value))
3651 {
3652 // check that passed value is valid
3653 other.assert_invariant();
3654
3655 // invalidate payload
3656 other.m_type = value_t::null;
3657 other.m_value = {};
3658
3659 assert_invariant();
3660 }
3661
3662 /*!
3663 @brief copy assignment
3664
3665 Copy assignment operator. Copies a JSON value via the "copy and swap"
3666 strategy: It is expressed in terms of the copy constructor, destructor,
3667 and the `swap()` member function.
3668
3669 @param[in] other value to copy from
3670
3671 @complexity Linear.
3672
3673 @requirement This function helps `json` satisfying the
3674 [Container](http://en.cppreference.com/w/cpp/concept/Container)
3675 requirements:
3676 - The complexity is linear.
3677
3678 @liveexample{The code below shows and example for the copy assignment. It
3679 creates a copy of value `a` which is then swapped with `b`. Finally\, the
3680 copy of `a` (which is the null value after the swap) is
3681 destroyed.,json__copyassignment}
3682
3683 @since version 1.0.0
3684 */
3685 reference& operator=(json other) noexcept (
3686 std::is_nothrow_move_constructible<value_t>::value and
3687 std::is_nothrow_move_assignable<value_t>::value and
3688 std::is_nothrow_move_constructible<json_value>::value and
3689 std::is_nothrow_move_assignable<json_value>::value
3690 )
3691 {
3692 // check that passed value is valid
3693 other.assert_invariant();
3694
3695 using std::swap;
3696 swap(m_type, other.m_type);
3697 swap(m_value, other.m_value);
3698
3699 assert_invariant();
3700 return *this;
3701 }
3702
3703 /*!
3704 @brief destructor
3705
3706 Destroys the JSON value and frees all allocated memory.
3707
3708 @complexity Linear.
3709
3710 @requirement This function helps `json` satisfying the
3711 [Container](http://en.cppreference.com/w/cpp/concept/Container)
3712 requirements:
3713 - The complexity is linear.
3714 - All stored elements are destroyed and all memory is freed.
3715
3716 @since version 1.0.0
3717 */
3718 ~json() noexcept
3719 {
3720 assert_invariant();
3721 m_value.destroy(m_type);
3722 }
3723
3724 /// @}
3725
3726 public:
3727 ///////////////////////
3728 // object inspection //
3729 ///////////////////////
3730
3731 /// @name object inspection
3732 /// Functions to inspect the type of a JSON value.
3733 /// @{
3734
3735 /*!
3736 @brief serialization
3737
3738 Serialization function for JSON values. The function tries to mimic
3739 Python's `json.dumps()` function, and currently supports its @a indent
3740 and @a ensure_ascii parameters.
3741
3742 @param[in] indent If indent is nonnegative, then array elements and object
3743 members will be pretty-printed with that indent level. An indent level of
3744 `0` will only insert newlines. `-1` (the default) selects the most compact
3745 representation.
3746 @param[in] indent_char The character to use for indentation if @a indent is
3747 greater than `0`. The default is ` ` (space).
3748 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
3749 in the output are escaped with `\uXXXX` sequences, and the result consists
3750 of ASCII characters only.
3751
3752 @return string containing the serialization of the JSON value
3753
3754 @throw type_error.316 if a string stored inside the JSON value is not
3755 UTF-8 encoded
3756
3757 @complexity Linear.
3758
3759 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
3760 changes in the JSON value.
3761
3762 @liveexample{The following example shows the effect of different @a indent\,
3763 @a indent_char\, and @a ensure_ascii parameters to the result of the
3764 serialization.,dump}
3765
3766 @see https://docs.python.org/2/library/json.html#json.dump
3767
3768 @since version 1.0.0; indentation character @a indent_char, option
3769 @a ensure_ascii and exceptions added in version 3.0.0
3770 */
3771 std::string dump(const int indent = -1, const char indent_char = ' ',
3772 const bool ensure_ascii = false) const;
3773
3774 void dump(raw_ostream& os, int indent = -1, const char indent_char = ' ',
3775 const bool ensure_ascii = false) const;
3776
3777 /*!
3778 @brief return the type of the JSON value (explicit)
3779
3780 Return the type of the JSON value as a value from the @ref value_t
3781 enumeration.
3782
3783 @return the type of the JSON value
3784 Value type | return value
3785 ------------------------- | -------------------------
3786 null | value_t::null
3787 boolean | value_t::boolean
3788 string | value_t::string
3789 number (integer) | value_t::number_integer
3790 number (unsigned integer) | value_t::number_unsigned
3791 number (floating-point) | value_t::number_float
3792 object | value_t::object
3793 array | value_t::array
3794 discarded | value_t::discarded
3795
3796 @complexity Constant.
3797
3798 @exceptionsafety No-throw guarantee: this member function never throws
3799 exceptions.
3800
3801 @liveexample{The following code exemplifies `type()` for all JSON
3802 types.,type}
3803
3804 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
3805 @sa @ref type_name() -- return the type as string
3806
3807 @since version 1.0.0
3808 */
3809 value_t type() const noexcept
3810 {
3811 return m_type;
3812 }
3813
3814 /*!
3815 @brief return whether type is primitive
3816
3817 This function returns true if and only if the JSON type is primitive
3818 (string, number, boolean, or null).
3819
3820 @return `true` if type is primitive (string, number, boolean, or null),
3821 `false` otherwise.
3822
3823 @complexity Constant.
3824
3825 @exceptionsafety No-throw guarantee: this member function never throws
3826 exceptions.
3827
3828 @liveexample{The following code exemplifies `is_primitive()` for all JSON
3829 types.,is_primitive}
3830
3831 @sa @ref is_structured() -- returns whether JSON value is structured
3832 @sa @ref is_null() -- returns whether JSON value is `null`
3833 @sa @ref is_string() -- returns whether JSON value is a string
3834 @sa @ref is_boolean() -- returns whether JSON value is a boolean
3835 @sa @ref is_number() -- returns whether JSON value is a number
3836
3837 @since version 1.0.0
3838 */
3839 bool is_primitive() const noexcept
3840 {
3841 return is_null() or is_string() or is_boolean() or is_number();
3842 }
3843
3844 /*!
3845 @brief return whether type is structured
3846
3847 This function returns true if and only if the JSON type is structured
3848 (array or object).
3849
3850 @return `true` if type is structured (array or object), `false` otherwise.
3851
3852 @complexity Constant.
3853
3854 @exceptionsafety No-throw guarantee: this member function never throws
3855 exceptions.
3856
3857 @liveexample{The following code exemplifies `is_structured()` for all JSON
3858 types.,is_structured}
3859
3860 @sa @ref is_primitive() -- returns whether value is primitive
3861 @sa @ref is_array() -- returns whether value is an array
3862 @sa @ref is_object() -- returns whether value is an object
3863
3864 @since version 1.0.0
3865 */
3866 bool is_structured() const noexcept
3867 {
3868 return is_array() or is_object();
3869 }
3870
3871 /*!
3872 @brief return whether value is null
3873
3874 This function returns true if and only if the JSON value is null.
3875
3876 @return `true` if type is null, `false` otherwise.
3877
3878 @complexity Constant.
3879
3880 @exceptionsafety No-throw guarantee: this member function never throws
3881 exceptions.
3882
3883 @liveexample{The following code exemplifies `is_null()` for all JSON
3884 types.,is_null}
3885
3886 @since version 1.0.0
3887 */
3888 bool is_null() const noexcept
3889 {
3890 return (m_type == value_t::null);
3891 }
3892
3893 /*!
3894 @brief return whether value is a boolean
3895
3896 This function returns true if and only if the JSON value is a boolean.
3897
3898 @return `true` if type is boolean, `false` otherwise.
3899
3900 @complexity Constant.
3901
3902 @exceptionsafety No-throw guarantee: this member function never throws
3903 exceptions.
3904
3905 @liveexample{The following code exemplifies `is_boolean()` for all JSON
3906 types.,is_boolean}
3907
3908 @since version 1.0.0
3909 */
3910 bool is_boolean() const noexcept
3911 {
3912 return (m_type == value_t::boolean);
3913 }
3914
3915 /*!
3916 @brief return whether value is a number
3917
3918 This function returns true if and only if the JSON value is a number. This
3919 includes both integer (signed and unsigned) and floating-point values.
3920
3921 @return `true` if type is number (regardless whether integer, unsigned
3922 integer or floating-type), `false` otherwise.
3923
3924 @complexity Constant.
3925
3926 @exceptionsafety No-throw guarantee: this member function never throws
3927 exceptions.
3928
3929 @liveexample{The following code exemplifies `is_number()` for all JSON
3930 types.,is_number}
3931
3932 @sa @ref is_number_integer() -- check if value is an integer or unsigned
3933 integer number
3934 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
3935 number
3936 @sa @ref is_number_float() -- check if value is a floating-point number
3937
3938 @since version 1.0.0
3939 */
3940 bool is_number() const noexcept
3941 {
3943 }
3944
3945 /*!
3946 @brief return whether value is an integer number
3947
3948 This function returns true if and only if the JSON value is a signed or
3949 unsigned integer number. This excludes floating-point values.
3950
3951 @return `true` if type is an integer or unsigned integer number, `false`
3952 otherwise.
3953
3954 @complexity Constant.
3955
3956 @exceptionsafety No-throw guarantee: this member function never throws
3957 exceptions.
3958
3959 @liveexample{The following code exemplifies `is_number_integer()` for all
3960 JSON types.,is_number_integer}
3961
3962 @sa @ref is_number() -- check if value is a number
3963 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
3964 number
3965 @sa @ref is_number_float() -- check if value is a floating-point number
3966
3967 @since version 1.0.0
3968 */
3969 bool is_number_integer() const noexcept
3970 {
3971 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
3972 }
3973
3974 /*!
3975 @brief return whether value is an unsigned integer number
3976
3977 This function returns true if and only if the JSON value is an unsigned
3978 integer number. This excludes floating-point and signed integer values.
3979
3980 @return `true` if type is an unsigned integer number, `false` otherwise.
3981
3982 @complexity Constant.
3983
3984 @exceptionsafety No-throw guarantee: this member function never throws
3985 exceptions.
3986
3987 @liveexample{The following code exemplifies `is_number_unsigned()` for all
3988 JSON types.,is_number_unsigned}
3989
3990 @sa @ref is_number() -- check if value is a number
3991 @sa @ref is_number_integer() -- check if value is an integer or unsigned
3992 integer number
3993 @sa @ref is_number_float() -- check if value is a floating-point number
3994
3995 @since version 2.0.0
3996 */
3997 bool is_number_unsigned() const noexcept
3998 {
3999 return (m_type == value_t::number_unsigned);
4000 }
4001
4002 /*!
4003 @brief return whether value is a floating-point number
4004
4005 This function returns true if and only if the JSON value is a
4006 floating-point number. This excludes signed and unsigned integer values.
4007
4008 @return `true` if type is a floating-point number, `false` otherwise.
4009
4010 @complexity Constant.
4011
4012 @exceptionsafety No-throw guarantee: this member function never throws
4013 exceptions.
4014
4015 @liveexample{The following code exemplifies `is_number_float()` for all
4016 JSON types.,is_number_float}
4017
4018 @sa @ref is_number() -- check if value is number
4019 @sa @ref is_number_integer() -- check if value is an integer number
4020 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
4021 number
4022
4023 @since version 1.0.0
4024 */
4025 bool is_number_float() const noexcept
4026 {
4027 return (m_type == value_t::number_float);
4028 }
4029
4030 /*!
4031 @brief return whether value is an object
4032
4033 This function returns true if and only if the JSON value is an object.
4034
4035 @return `true` if type is object, `false` otherwise.
4036
4037 @complexity Constant.
4038
4039 @exceptionsafety No-throw guarantee: this member function never throws
4040 exceptions.
4041
4042 @liveexample{The following code exemplifies `is_object()` for all JSON
4043 types.,is_object}
4044
4045 @since version 1.0.0
4046 */
4047 bool is_object() const noexcept
4048 {
4049 return (m_type == value_t::object);
4050 }
4051
4052 /*!
4053 @brief return whether value is an array
4054
4055 This function returns true if and only if the JSON value is an array.
4056
4057 @return `true` if type is array, `false` otherwise.
4058
4059 @complexity Constant.
4060
4061 @exceptionsafety No-throw guarantee: this member function never throws
4062 exceptions.
4063
4064 @liveexample{The following code exemplifies `is_array()` for all JSON
4065 types.,is_array}
4066
4067 @since version 1.0.0
4068 */
4069 bool is_array() const noexcept
4070 {
4071 return (m_type == value_t::array);
4072 }
4073
4074 /*!
4075 @brief return whether value is a string
4076
4077 This function returns true if and only if the JSON value is a string.
4078
4079 @return `true` if type is string, `false` otherwise.
4080
4081 @complexity Constant.
4082
4083 @exceptionsafety No-throw guarantee: this member function never throws
4084 exceptions.
4085
4086 @liveexample{The following code exemplifies `is_string()` for all JSON
4087 types.,is_string}
4088
4089 @since version 1.0.0
4090 */
4091 bool is_string() const noexcept
4092 {
4093 return (m_type == value_t::string);
4094 }
4095
4096 /*!
4097 @brief return whether value is discarded
4098
4099 This function returns true if and only if the JSON value was discarded
4100 during parsing with a callback function (see @ref parser_callback_t).
4101
4102 @note This function will always be `false` for JSON values after parsing.
4103 That is, discarded values can only occur during parsing, but will be
4104 removed when inside a structured value or replaced by null in other cases.
4105
4106 @return `true` if type is discarded, `false` otherwise.
4107
4108 @complexity Constant.
4109
4110 @exceptionsafety No-throw guarantee: this member function never throws
4111 exceptions.
4112
4113 @liveexample{The following code exemplifies `is_discarded()` for all JSON
4114 types.,is_discarded}
4115
4116 @since version 1.0.0
4117 */
4118 bool is_discarded() const noexcept
4119 {
4120 return (m_type == value_t::discarded);
4121 }
4122
4123 /*!
4124 @brief return the type of the JSON value (implicit)
4125
4126 Implicitly return the type of the JSON value as a value from the @ref
4127 value_t enumeration.
4128
4129 @return the type of the JSON value
4130
4131 @complexity Constant.
4132
4133 @exceptionsafety No-throw guarantee: this member function never throws
4134 exceptions.
4135
4136 @liveexample{The following code exemplifies the @ref value_t operator for
4137 all JSON types.,operator__value_t}
4138
4139 @sa @ref type() -- return the type of the JSON value (explicit)
4140 @sa @ref type_name() -- return the type as string
4141
4142 @since version 1.0.0
4143 */
4144 operator value_t() const noexcept
4145 {
4146 return m_type;
4147 }
4148
4149 /// @}
4150
4151 private:
4152 //////////////////
4153 // value access //
4154 //////////////////
4155
4156 /// get a boolean (explicit)
4157 bool get_impl(bool* /*unused*/) const
4158 {
4159 if (JSON_LIKELY(is_boolean()))
4160 {
4161 return m_value.boolean;
4162 }
4163
4164 JSON_THROW(type_error::create(302, "type must be boolean, but is", type_name()));
4165 }
4166
4167 /// get a pointer to the value (object)
4168 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
4169 {
4170 return is_object() ? m_value.object : nullptr;
4171 }
4172
4173 /// get a pointer to the value (object)
4174 const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
4175 {
4176 return is_object() ? m_value.object : nullptr;
4177 }
4178
4179 /// get a pointer to the value (array)
4180 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
4181 {
4182 return is_array() ? m_value.array : nullptr;
4183 }
4184
4185 /// get a pointer to the value (array)
4186 const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
4187 {
4188 return is_array() ? m_value.array : nullptr;
4189 }
4190
4191 /// get a pointer to the value (string)
4192 std::string* get_impl_ptr(std::string* /*unused*/) noexcept
4193 {
4194 return is_string() ? m_value.string : nullptr;
4195 }
4196
4197 /// get a pointer to the value (string)
4198 const std::string* get_impl_ptr(const std::string* /*unused*/) const noexcept
4199 {
4200 return is_string() ? m_value.string : nullptr;
4201 }
4202
4203 /// get a pointer to the value (boolean)
4204 bool* get_impl_ptr(bool* /*unused*/) noexcept
4205 {
4206 return is_boolean() ? &m_value.boolean : nullptr;
4207 }
4208
4209 /// get a pointer to the value (boolean)
4210 const bool* get_impl_ptr(const bool* /*unused*/) const noexcept
4211 {
4212 return is_boolean() ? &m_value.boolean : nullptr;
4213 }
4214
4215 /// get a pointer to the value (integer number)
4216 int64_t* get_impl_ptr(int64_t* /*unused*/) noexcept
4217 {
4218 return is_number_integer() ? &m_value.number_integer : nullptr;
4219 }
4220
4221 /// get a pointer to the value (integer number)
4222 const int64_t* get_impl_ptr(const int64_t* /*unused*/) const noexcept
4223 {
4224 return is_number_integer() ? &m_value.number_integer : nullptr;
4225 }
4226
4227 /// get a pointer to the value (unsigned number)
4228 uint64_t* get_impl_ptr(uint64_t* /*unused*/) noexcept
4229 {
4230 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
4231 }
4232
4233 /// get a pointer to the value (unsigned number)
4234 const uint64_t* get_impl_ptr(const uint64_t* /*unused*/) const noexcept
4235 {
4236 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
4237 }
4238
4239 /// get a pointer to the value (floating-point number)
4240 double* get_impl_ptr(double* /*unused*/) noexcept
4241 {
4242 return is_number_float() ? &m_value.number_float : nullptr;
4243 }
4244
4245 /// get a pointer to the value (floating-point number)
4246 const double* get_impl_ptr(const double* /*unused*/) const noexcept
4247 {
4248 return is_number_float() ? &m_value.number_float : nullptr;
4249 }
4250
4251 /*!
4252 @brief helper function to implement get_ref()
4253
4254 This function helps to implement get_ref() without code duplication for
4255 const and non-const overloads
4256
4257 @tparam ThisType will be deduced as `json` or `const json`
4258
4259 @throw type_error.303 if ReferenceType does not match underlying value
4260 type of the current JSON
4261 */
4262 template<typename ReferenceType, typename ThisType>
4263 static ReferenceType get_ref_impl(ThisType& obj)
4264 {
4265 // delegate the call to get_ptr<>()
4267
4268 if (JSON_LIKELY(ptr != nullptr))
4269 {
4270 return *ptr;
4271 }
4272
4273 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is", obj.type_name()));
4274 }
4275
4276 public:
4277 /// @name value access
4278 /// Direct access to the stored value of a JSON value.
4279 /// @{
4280
4281 /*!
4282 @brief get special-case overload
4283
4284 This overloads avoids a lot of template boilerplate, it can be seen as the
4285 identity method
4286
4287 @tparam BasicJsonType == @ref json
4288
4289 @return a copy of *this
4290
4291 @complexity Constant.
4292
4293 @since version 2.1.0
4294 */
4295 template<typename BasicJsonType, detail::enable_if_t<
4297 int> = 0>
4298 json get() const
4299 {
4300 return *this;
4301 }
4302
4303 /*!
4304 @brief get a value (explicit)
4305
4306 Explicit type conversion between the JSON value and a compatible value
4307 which is [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
4308 and [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
4309 The value is converted by calling the @ref json_serializer<ValueType>
4310 `from_json()` method.
4311
4312 The function is equivalent to executing
4313 @code {.cpp}
4314 ValueType ret;
4315 adl_serializer<ValueType, void>::from_json(*this, ret);
4316 return ret;
4317 @endcode
4318
4319 This overloads is chosen if:
4320 - @a ValueType is not @ref json,
4321 - @ref json_serializer<ValueType> has a `from_json()` method of the form
4322 `void from_json(const json&, ValueType&)`, and
4323 - @ref json_serializer<ValueType> does not have a `from_json()` method of
4324 the form `ValueType from_json(const json&)`
4325
4326 @tparam ValueTypeCV the provided value type
4327 @tparam ValueType the returned value type
4328
4329 @return copy of the JSON value, converted to @a ValueType
4330
4331 @throw what @ref json_serializer<ValueType> `from_json()` method throws
4332
4333 @liveexample{The example below shows several conversions from JSON values
4334 to other types. There a few things to note: (1) Floating-point numbers can
4335 be converted to integers\, (2) A JSON array can be converted to a standard
4336 `std::vector<short>`\, (3) A JSON object can be converted to C++
4337 associative containers such as `std::unordered_map<std::string\,
4338 json>`.,get__ValueType_const}
4339
4340 @since version 2.1.0
4341 */
4342 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
4343 detail::enable_if_t <
4344 not detail::is_json<ValueType>::value and
4345 detail::has_from_json<json_t, ValueType>::value and
4346 not detail::has_non_default_from_json<json_t, ValueType>::value,
4347 int> = 0>
4348 ValueType get() const noexcept(noexcept(
4349 adl_serializer<ValueType, void>::from_json(std::declval<const json_t&>(), std::declval<ValueType&>())))
4350 {
4351 // we cannot static_assert on ValueTypeCV being non-const, because
4352 // there is support for get<const json_t>(), which is why we
4353 // still need the uncvref
4354 static_assert(not std::is_reference<ValueTypeCV>::value,
4355 "get() cannot be used with reference types, you might want to use get_ref()");
4356 static_assert(std::is_default_constructible<ValueType>::value,
4357 "types must be DefaultConstructible when used with get()");
4358
4359 ValueType ret;
4361 return ret;
4362 }
4363
4364 /*!
4365 @brief get a value (explicit); special case
4366
4367 Explicit type conversion between the JSON value and a compatible value
4368 which is **not** [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
4369 and **not** [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
4370 The value is converted by calling the @ref json_serializer<ValueType>
4371 `from_json()` method.
4372
4373 The function is equivalent to executing
4374 @code {.cpp}
4375 return adl_serializer<ValueTypeCV, void>::from_json(*this);
4376 @endcode
4377
4378 This overloads is chosen if:
4379 - @a ValueType is not @ref json and
4380 - @ref json_serializer<ValueType> has a `from_json()` method of the form
4381 `ValueType from_json(const json&)`
4382
4383 @note If @ref json_serializer<ValueType> has both overloads of
4384 `from_json()`, this one is chosen.
4385
4386 @tparam ValueTypeCV the provided value type
4387 @tparam ValueType the returned value type
4388
4389 @return copy of the JSON value, converted to @a ValueType
4390
4391 @throw what @ref json_serializer<ValueType> `from_json()` method throws
4392
4393 @since version 2.1.0
4394 */
4395 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
4396 detail::enable_if_t<not std::is_same<json_t, ValueType>::value and
4397 detail::has_non_default_from_json<json_t, ValueType>::value,
4398 int> = 0>
4399 ValueType get() const noexcept(noexcept(
4400 adl_serializer<ValueTypeCV, void>::from_json(std::declval<const json_t&>())))
4401 {
4402 static_assert(not std::is_reference<ValueTypeCV>::value,
4403 "get() cannot be used with reference types, you might want to use get_ref()");
4405 }
4406
4407 /*!
4408 @brief get a pointer value (explicit)
4409
4410 Explicit pointer access to the internally stored JSON value. No copies are
4411 made.
4412
4413 @warning The pointer becomes invalid if the underlying JSON object
4414 changes.
4415
4416 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
4417 object_t, `std::string`, bool, int64_t, uint64_t, or double.
4418
4419 @return pointer to the internally stored JSON value if the requested
4420 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
4421
4422 @complexity Constant.
4423
4424 @liveexample{The example below shows how pointers to internal values of a
4425 JSON value can be requested. Note that no type conversions are made and a
4426 `nullptr` is returned if the value and the requested pointer type does not
4427 match.,get__PointerType}
4428
4429 @sa @ref get_ptr() for explicit pointer-member access
4430
4431 @since version 1.0.0
4432 */
4433 template<typename PointerType, typename std::enable_if<
4434 std::is_pointer<PointerType>::value, int>::type = 0>
4435 PointerType get() noexcept
4436 {
4437 // delegate the call to get_ptr
4438 return get_ptr<PointerType>();
4439 }
4440
4441 /*!
4442 @brief get a pointer value (explicit)
4443 @copydoc get()
4444 */
4445 template<typename PointerType, typename std::enable_if<
4446 std::is_pointer<PointerType>::value, int>::type = 0>
4447 const PointerType get() const noexcept
4448 {
4449 // delegate the call to get_ptr
4450 return get_ptr<PointerType>();
4451 }
4452
4453 /*!
4454 @brief get a pointer value (implicit)
4455
4456 Implicit pointer access to the internally stored JSON value. No copies are
4457 made.
4458
4459 @warning Writing data to the pointee of the result yields an undefined
4460 state.
4461
4462 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
4463 object_t, `std::string`, bool, int64_t,
4464 uint64_t, or double. Enforced by a static assertion.
4465
4466 @return pointer to the internally stored JSON value if the requested
4467 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
4468
4469 @complexity Constant.
4470
4471 @liveexample{The example below shows how pointers to internal values of a
4472 JSON value can be requested. Note that no type conversions are made and a
4473 `nullptr` is returned if the value and the requested pointer type does not
4474 match.,get_ptr}
4475
4476 @since version 1.0.0
4477 */
4478 template<typename PointerType, typename std::enable_if<
4479 std::is_pointer<PointerType>::value, int>::type = 0>
4480 PointerType get_ptr() noexcept
4481 {
4482 // get the type of the PointerType (remove pointer and const)
4483 using pointee_t = typename std::remove_const<typename
4484 std::remove_pointer<typename
4486 // make sure the type matches the allowed types
4487 static_assert(
4488 std::is_same<object_t, pointee_t>::value
4489 or std::is_same<array_t, pointee_t>::value
4490 or std::is_same<std::string, pointee_t>::value
4491 or std::is_same<bool, pointee_t>::value
4492 or std::is_same<int64_t, pointee_t>::value
4493 or std::is_same<uint64_t, pointee_t>::value
4494 or std::is_same<double, pointee_t>::value
4495 , "incompatible pointer type");
4496
4497 // delegate the call to get_impl_ptr<>()
4498 return get_impl_ptr(static_cast<PointerType>(nullptr));
4499 }
4500
4501 /*!
4502 @brief get a pointer value (implicit)
4503 @copydoc get_ptr()
4504 */
4505 template<typename PointerType, typename std::enable_if<
4506 std::is_pointer<PointerType>::value and
4508 const PointerType get_ptr() const noexcept
4509 {
4510 // get the type of the PointerType (remove pointer and const)
4511 using pointee_t = typename std::remove_const<typename
4512 std::remove_pointer<typename
4514 // make sure the type matches the allowed types
4515 static_assert(
4516 std::is_same<object_t, pointee_t>::value
4517 or std::is_same<array_t, pointee_t>::value
4518 or std::is_same<std::string, pointee_t>::value
4519 or std::is_same<bool, pointee_t>::value
4520 or std::is_same<int64_t, pointee_t>::value
4521 or std::is_same<uint64_t, pointee_t>::value
4522 or std::is_same<double, pointee_t>::value
4523 , "incompatible pointer type");
4524
4525 // delegate the call to get_impl_ptr<>() const
4526 return get_impl_ptr(static_cast<PointerType>(nullptr));
4527 }
4528
4529 /*!
4530 @brief get a reference value (implicit)
4531
4532 Implicit reference access to the internally stored JSON value. No copies
4533 are made.
4534
4535 @warning Writing data to the referee of the result yields an undefined
4536 state.
4537
4538 @tparam ReferenceType reference type; must be a reference to @ref array_t,
4539 @ref object_t, std::string, bool, int64_t, or
4540 double. Enforced by static assertion.
4541
4542 @return reference to the internally stored JSON value if the requested
4543 reference type @a ReferenceType fits to the JSON value; throws
4544 type_error.303 otherwise
4545
4546 @throw type_error.303 in case passed type @a ReferenceType is incompatible
4547 with the stored JSON value; see example below
4548
4549 @complexity Constant.
4550
4551 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
4552
4553 @since version 1.1.0
4554 */
4555 template<typename ReferenceType, typename std::enable_if<
4556 std::is_reference<ReferenceType>::value, int>::type = 0>
4557 ReferenceType get_ref()
4558 {
4559 // delegate call to get_ref_impl
4560 return get_ref_impl<ReferenceType>(*this);
4561 }
4562
4563 /*!
4564 @brief get a reference value (implicit)
4565 @copydoc get_ref()
4566 */
4567 template<typename ReferenceType, typename std::enable_if<
4568 std::is_reference<ReferenceType>::value and
4570 ReferenceType get_ref() const
4571 {
4572 // delegate call to get_ref_impl
4573 return get_ref_impl<ReferenceType>(*this);
4574 }
4575
4576 /*!
4577 @brief get a value (implicit)
4578
4579 Implicit type conversion between the JSON value and a compatible value.
4580 The call is realized by calling @ref get() const.
4581
4582 @tparam ValueType non-pointer type compatible to the JSON value, for
4583 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
4584 `std::vector` types for JSON arrays. The character type of `std::string`
4585 as well as an initializer list of this type is excluded to avoid
4586 ambiguities as these types implicitly convert to `std::string`.
4587
4588 @return copy of the JSON value, converted to type @a ValueType
4589
4590 @throw type_error.302 in case passed type @a ValueType is incompatible
4591 to the JSON value type (e.g., the JSON value is of type boolean, but a
4592 string is requested); see example below
4593
4594 @complexity Linear in the size of the JSON value.
4595
4596 @liveexample{The example below shows several conversions from JSON values
4597 to other types. There a few things to note: (1) Floating-point numbers can
4598 be converted to integers\, (2) A JSON array can be converted to a standard
4599 `std::vector<short>`\, (3) A JSON object can be converted to C++
4600 associative containers such as `std::unordered_map<std::string\,
4601 json>`.,operator__ValueType}
4602
4603 @since version 1.0.0
4604 */
4605 template < typename ValueType, typename std::enable_if <
4606 not std::is_pointer<ValueType>::value and
4607 not std::is_same<ValueType, detail::json_ref<json>>::value and
4608 not std::is_same<ValueType, std::string::value_type>::value and
4610#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
4611 and not std::is_same<ValueType, std::initializer_list<std::string::value_type>>::value
4612#endif
4613 and not std::is_same<ValueType, typename std::string_view>::value
4614 , int >::type = 0 >
4615 operator ValueType() const
4616 {
4617 // delegate the call to get<>() const
4618 return get<ValueType>();
4619 }
4620
4621 /// @}
4622
4623
4624 ////////////////////
4625 // element access //
4626 ////////////////////
4627
4628 /// @name element access
4629 /// Access to the JSON value.
4630 /// @{
4631
4632 /*!
4633 @brief access specified array element with bounds checking
4634
4635 Returns a reference to the element at specified location @a idx, with
4636 bounds checking.
4637
4638 @param[in] idx index of the element to access
4639
4640 @return reference to the element at index @a idx
4641
4642 @throw type_error.304 if the JSON value is not an array; in this case,
4643 calling `at` with an index makes no sense. See example below.
4644 @throw out_of_range.401 if the index @a idx is out of range of the array;
4645 that is, `idx >= size()`. See example below.
4646
4647 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
4648 changes in the JSON value.
4649
4650 @complexity Constant.
4651
4652 @since version 1.0.0
4653
4654 @liveexample{The example below shows how array elements can be read and
4655 written using `at()`. It also demonstrates the different exceptions that
4656 can be thrown.,at__size_type}
4657 */
4659
4660 /*!
4661 @brief access specified array element with bounds checking
4662
4663 Returns a const reference to the element at specified location @a idx,
4664 with bounds checking.
4665
4666 @param[in] idx index of the element to access
4667
4668 @return const reference to the element at index @a idx
4669
4670 @throw type_error.304 if the JSON value is not an array; in this case,
4671 calling `at` with an index makes no sense. See example below.
4672 @throw out_of_range.401 if the index @a idx is out of range of the array;
4673 that is, `idx >= size()`. See example below.
4674
4675 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
4676 changes in the JSON value.
4677
4678 @complexity Constant.
4679
4680 @since version 1.0.0
4681
4682 @liveexample{The example below shows how array elements can be read using
4683 `at()`. It also demonstrates the different exceptions that can be thrown.,
4684 at__size_type_const}
4685 */
4687
4688 /*!
4689 @brief access specified object element with bounds checking
4690
4691 Returns a reference to the element at with specified key @a key, with
4692 bounds checking.
4693
4694 @param[in] key key of the element to access
4695
4696 @return reference to the element at key @a key
4697
4698 @throw type_error.304 if the JSON value is not an object; in this case,
4699 calling `at` with a key makes no sense. See example below.
4700 @throw out_of_range.403 if the key @a key is is not stored in the object;
4701 that is, `find(key) == end()`. See example below.
4702
4703 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
4704 changes in the JSON value.
4705
4706 @complexity Logarithmic in the size of the container.
4707
4708 @sa @ref operator[](const typename object_t::key_type&) for unchecked
4709 access by reference
4710 @sa @ref value() for access by value with a default value
4711
4712 @since version 1.0.0
4713
4714 @liveexample{The example below shows how object elements can be read and
4715 written using `at()`. It also demonstrates the different exceptions that
4716 can be thrown.,at__object_t_key_type}
4717 */
4719
4720 /*!
4721 @brief access specified object element with bounds checking
4722
4723 Returns a const reference to the element at with specified key @a key,
4724 with bounds checking.
4725
4726 @param[in] key key of the element to access
4727
4728 @return const reference to the element at key @a key
4729
4730 @throw type_error.304 if the JSON value is not an object; in this case,
4731 calling `at` with a key makes no sense. See example below.
4732 @throw out_of_range.403 if the key @a key is is not stored in the object;
4733 that is, `find(key) == end()`. See example below.
4734
4735 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
4736 changes in the JSON value.
4737
4738 @complexity Logarithmic in the size of the container.
4739
4740 @sa @ref operator[](const typename object_t::key_type&) for unchecked
4741 access by reference
4742 @sa @ref value() for access by value with a default value
4743
4744 @since version 1.0.0
4745
4746 @liveexample{The example below shows how object elements can be read using
4747 `at()`. It also demonstrates the different exceptions that can be thrown.,
4748 at__object_t_key_type_const}
4749 */
4751
4752 /*!
4753 @brief access specified array element
4754
4755 Returns a reference to the element at specified location @a idx.
4756
4757 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
4758 then the array is silently filled up with `null` values to make `idx` a
4759 valid reference to the last stored element.
4760
4761 @param[in] idx index of the element to access
4762
4763 @return reference to the element at index @a idx
4764
4765 @throw type_error.305 if the JSON value is not an array or null; in that
4766 cases, using the [] operator with an index makes no sense.
4767
4768 @complexity Constant if @a idx is in the range of the array. Otherwise
4769 linear in `idx - size()`.
4770
4771 @liveexample{The example below shows how array elements can be read and
4772 written using `[]` operator. Note the addition of `null`
4773 values.,operatorarray__size_type}
4774
4775 @since version 1.0.0
4776 */
4778
4779 /*!
4780 @brief access specified array element
4781
4782 Returns a const reference to the element at specified location @a idx.
4783
4784 @param[in] idx index of the element to access
4785
4786 @return const reference to the element at index @a idx
4787
4788 @throw type_error.305 if the JSON value is not an array; in that case,
4789 using the [] operator with an index makes no sense.
4790
4791 @complexity Constant.
4792
4793 @liveexample{The example below shows how array elements can be read using
4794 the `[]` operator.,operatorarray__size_type_const}
4795
4796 @since version 1.0.0
4797 */
4799
4800 /*!
4801 @brief access specified object element
4802
4803 Returns a reference to the element at with specified key @a key.
4804
4805 @note If @a key is not found in the object, then it is silently added to
4806 the object and filled with a `null` value to make `key` a valid reference.
4807 In case the value was `null` before, it is converted to an object.
4808
4809 @param[in] key key of the element to access
4810
4811 @return reference to the element at key @a key
4812
4813 @throw type_error.305 if the JSON value is not an object or null; in that
4814 cases, using the [] operator with a key makes no sense.
4815
4816 @complexity Logarithmic in the size of the container.
4817
4818 @liveexample{The example below shows how object elements can be read and
4819 written using the `[]` operator.,operatorarray__key_type}
4820
4821 @sa @ref at(const typename object_t::key_type&) for access by reference
4822 with range checking
4823 @sa @ref value() for access by value with a default value
4824
4825 @since version 1.0.0
4826 */
4828
4829 /*!
4830 @brief read-only access specified object element
4831
4832 Returns a const reference to the element at with specified key @a key. No
4833 bounds checking is performed.
4834
4835 @warning If the element with key @a key does not exist, the behavior is
4836 undefined.
4837
4838 @param[in] key key of the element to access
4839
4840 @return const reference to the element at key @a key
4841
4842 @pre The element with key @a key must exist. **This precondition is
4843 enforced with an assertion.**
4844
4845 @throw type_error.305 if the JSON value is not an object; in that case,
4846 using the [] operator with a key makes no sense.
4847
4848 @complexity Logarithmic in the size of the container.
4849
4850 @liveexample{The example below shows how object elements can be read using
4851 the `[]` operator.,operatorarray__key_type_const}
4852
4853 @sa @ref at(const typename object_t::key_type&) for access by reference
4854 with range checking
4855 @sa @ref value() for access by value with a default value
4856
4857 @since version 1.0.0
4858 */
4860
4861 /*!
4862 @brief access specified object element
4863
4864 Returns a reference to the element at with specified key @a key.
4865
4866 @note If @a key is not found in the object, then it is silently added to
4867 the object and filled with a `null` value to make `key` a valid reference.
4868 In case the value was `null` before, it is converted to an object.
4869
4870 @param[in] key key of the element to access
4871
4872 @return reference to the element at key @a key
4873
4874 @throw type_error.305 if the JSON value is not an object or null; in that
4875 cases, using the [] operator with a key makes no sense.
4876
4877 @complexity Logarithmic in the size of the container.
4878
4879 @liveexample{The example below shows how object elements can be read and
4880 written using the `[]` operator.,operatorarray__key_type}
4881
4882 @sa @ref at(const typename object_t::key_type&) for access by reference
4883 with range checking
4884 @sa @ref value() for access by value with a default value
4885
4886 @since version 1.1.0
4887 */
4888 template<typename T>
4890 {
4891 // implicitly convert null to object
4892 if (is_null())
4893 {
4894 m_type = value_t::object;
4895 m_value = value_t::object;
4896 assert_invariant();
4897 }
4898
4899 // at only works for objects
4900 if (JSON_LIKELY(is_object()))
4901 {
4902 return m_value.object->operator[](key);
4903 }
4904
4905 JSON_THROW(type_error::create(305, "cannot use operator[] with", type_name()));
4906 }
4907
4908 /*!
4909 @brief read-only access specified object element
4910
4911 Returns a const reference to the element at with specified key @a key. No
4912 bounds checking is performed.
4913
4914 @warning If the element with key @a key does not exist, the behavior is
4915 undefined.
4916
4917 @param[in] key key of the element to access
4918
4919 @return const reference to the element at key @a key
4920
4921 @pre The element with key @a key must exist. **This precondition is
4922 enforced with an assertion.**
4923
4924 @throw type_error.305 if the JSON value is not an object; in that case,
4925 using the [] operator with a key makes no sense.
4926
4927 @complexity Logarithmic in the size of the container.
4928
4929 @liveexample{The example below shows how object elements can be read using
4930 the `[]` operator.,operatorarray__key_type_const}
4931
4932 @sa @ref at(const typename object_t::key_type&) for access by reference
4933 with range checking
4934 @sa @ref value() for access by value with a default value
4935
4936 @since version 1.1.0
4937 */
4938 template<typename T>
4940 {
4941 // at only works for objects
4942 if (JSON_LIKELY(is_object()))
4943 {
4944 assert(m_value.object->find(key) != m_value.object->end());
4945 return m_value.object->find(key)->second;
4946 }
4947
4948 JSON_THROW(type_error::create(305, "cannot use operator[] with", type_name()));
4949 }
4950
4951 /*!
4952 @brief access specified object element with default value
4953
4954 Returns either a copy of an object's element at the specified key @a key
4955 or a given default value if no element with key @a key exists.
4956
4957 The function is basically equivalent to executing
4958 @code {.cpp}
4959 try {
4960 return at(key);
4961 } catch(out_of_range) {
4962 return default_value;
4963 }
4964 @endcode
4965
4966 @note Unlike @ref at(const typename object_t::key_type&), this function
4967 does not throw if the given key @a key was not found.
4968
4969 @note Unlike @ref operator[](const typename object_t::key_type& key), this
4970 function does not implicitly add an element to the position defined by @a
4971 key. This function is furthermore also applicable to const objects.
4972
4973 @param[in] key key of the element to access
4974 @param[in] default_value the value to return if @a key is not found
4975
4976 @tparam ValueType type compatible to JSON values, for instance `int` for
4977 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
4978 JSON arrays. Note the type of the expected value at @a key and the default
4979 value @a default_value must be compatible.
4980
4981 @return copy of the element at key @a key or @a default_value if @a key
4982 is not found
4983
4984 @throw type_error.306 if the JSON value is not an object; in that case,
4985 using `value()` with a key makes no sense.
4986
4987 @complexity Logarithmic in the size of the container.
4988
4989 @liveexample{The example below shows how object elements can be queried
4990 with a default value.,json__value}
4991
4992 @sa @ref at(const typename object_t::key_type&) for access by reference
4993 with range checking
4994 @sa @ref operator[](const typename object_t::key_type&) for unchecked
4995 access by reference
4996
4997 @since version 1.0.0
4998 */
4999 template<class ValueType, typename std::enable_if<
5000 std::is_convertible<json_t, ValueType>::value, int>::type = 0>
5001 ValueType value(std::string_view key, const ValueType& default_value) const
5002 {
5003 // at only works for objects
5004 if (JSON_LIKELY(is_object()))
5005 {
5006 // if key is found, return value and given default value otherwise
5007 const auto it = find(key);
5008 if (it != end())
5009 {
5010 return *it;
5011 }
5012
5013 return default_value;
5014 }
5015
5016 JSON_THROW(type_error::create(306, "cannot use value() with", type_name()));
5017 }
5018
5019 /*!
5020 @brief overload for a default value of type const char*
5021 @copydoc json::value(const typename object_t::key_type&, ValueType) const
5022 */
5023 std::string value(std::string_view key, const char* default_value) const
5024 {
5025 return value(key, std::string(default_value));
5026 }
5027
5028 /*!
5029 @brief access specified object element via JSON Pointer with default value
5030
5031 Returns either a copy of an object's element at the specified key @a key
5032 or a given default value if no element with key @a key exists.
5033
5034 The function is basically equivalent to executing
5035 @code {.cpp}
5036 try {
5037 return at(ptr);
5038 } catch(out_of_range) {
5039 return default_value;
5040 }
5041 @endcode
5042
5043 @note Unlike @ref at(const json_pointer&), this function does not throw
5044 if the given key @a key was not found.
5045
5046 @param[in] ptr a JSON pointer to the element to access
5047 @param[in] default_value the value to return if @a ptr found no value
5048
5049 @tparam ValueType type compatible to JSON values, for instance `int` for
5050 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
5051 JSON arrays. Note the type of the expected value at @a key and the default
5052 value @a default_value must be compatible.
5053
5054 @return copy of the element at key @a key or @a default_value if @a key
5055 is not found
5056
5057 @throw type_error.306 if the JSON value is not an object; in that case,
5058 using `value()` with a key makes no sense.
5059
5060 @complexity Logarithmic in the size of the container.
5061
5062 @liveexample{The example below shows how object elements can be queried
5063 with a default value.,json__value_ptr}
5064
5065 @sa @ref operator[](const json_pointer&) for unchecked access by reference
5066
5067 @since version 2.0.2
5068 */
5069 template<class ValueType, typename std::enable_if<
5070 std::is_convertible<json_t, ValueType>::value, int>::type = 0>
5071 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
5072 {
5073 // at only works for objects
5074 if (JSON_LIKELY(is_object()))
5075 {
5076 // if pointer resolves a value, return it or use default value
5077 JSON_TRY
5078 {
5079 return ptr.get_checked(this);
5080 }
5082 {
5083 return default_value;
5084 }
5085 }
5086
5087 JSON_THROW(type_error::create(306, "cannot use value() with", type_name()));
5088 }
5089
5090 /*!
5091 @brief overload for a default value of type const char*
5092 @copydoc json::value(const json_pointer&, ValueType) const
5093 */
5094 std::string value(const json_pointer& ptr, const char* default_value) const
5095 {
5096 return value(ptr, std::string(default_value));
5097 }
5098
5099 /*!
5100 @brief access the first element
5101
5102 Returns a reference to the first element in the container. For a JSON
5103 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
5104
5105 @return In case of a structured type (array or object), a reference to the
5106 first element is returned. In case of number, string, or boolean values, a
5107 reference to the value is returned.
5108
5109 @complexity Constant.
5110
5111 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
5112 or an empty array or object (undefined behavior, **guarded by
5113 assertions**).
5114 @post The JSON value remains unchanged.
5115
5116 @throw invalid_iterator.214 when called on `null` value
5117
5118 @liveexample{The following code shows an example for `front()`.,front}
5119
5120 @sa @ref back() -- access the last element
5121
5122 @since version 1.0.0
5123 */
5125 {
5126 return *begin();
5127 }
5128
5129 /*!
5130 @copydoc json::front()
5131 */
5133 {
5134 return *cbegin();
5135 }
5136
5137 /*!
5138 @brief access the last element
5139
5140 Returns a reference to the last element in the container. For a JSON
5141 container `c`, the expression `c.back()` is equivalent to
5142 @code {.cpp}
5143 auto tmp = c.end();
5144 --tmp;
5145 return *tmp;
5146 @endcode
5147
5148 @return In case of a structured type (array or object), a reference to the
5149 last element is returned. In case of number, string, or boolean values, a
5150 reference to the value is returned.
5151
5152 @complexity Constant.
5153
5154 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
5155 or an empty array or object (undefined behavior, **guarded by
5156 assertions**).
5157 @post The JSON value remains unchanged.
5158
5159 @throw invalid_iterator.214 when called on a `null` value. See example
5160 below.
5161
5162 @liveexample{The following code shows an example for `back()`.,back}
5163
5164 @sa @ref front() -- access the first element
5165
5166 @since version 1.0.0
5167 */
5169 {
5170 auto tmp = end();
5171 --tmp;
5172 return *tmp;
5173 }
5174
5175 /*!
5176 @copydoc json::back()
5177 */
5179 {
5180 auto tmp = cend();
5181 --tmp;
5182 return *tmp;
5183 }
5184
5185 /*!
5186 @brief remove element given an iterator
5187
5188 Removes the element specified by iterator @a pos. The iterator @a pos must
5189 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
5190 but is not dereferenceable) cannot be used as a value for @a pos.
5191
5192 If called on a primitive type other than `null`, the resulting JSON value
5193 will be `null`.
5194
5195 @param[in] pos iterator to the element to remove
5196
5197 @tparam IteratorType an @ref iterator or @ref const_iterator
5198
5199 @post Invalidates iterators and references at or after the point of the
5200 erase, including the `end()` iterator.
5201
5202 @throw type_error.307 if called on a `null` value; example: `"cannot use
5203 erase() with null"`
5204 @throw invalid_iterator.202 if called on an iterator which does not belong
5205 to the current JSON value; example: `"iterator does not fit current
5206 value"`
5207 @throw invalid_iterator.205 if called on a primitive type with invalid
5208 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
5209 out of range"`
5210
5211 @complexity The complexity depends on the type:
5212 - objects: amortized constant
5213 - arrays: linear in distance between @a pos and the end of the container
5214 - strings: linear in the length of the string
5215 - other types: constant
5216
5217 @liveexample{The example shows the result of `erase()` for different JSON
5218 types.,erase__IteratorType}
5219
5220 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
5221 the given range
5222 @sa @ref erase(std::string_view) -- removes the element
5223 from an object at the given key
5224 @sa @ref erase(const size_type) -- removes the element from an array at
5225 the given index
5226
5227 @since version 1.0.0
5228 */
5229 template<class IteratorType, typename std::enable_if<
5230 std::is_same<IteratorType, typename json_t::iterator>::value or
5231 std::is_same<IteratorType, typename json_t::const_iterator>::value, int>::type
5232 = 0>
5233 void erase(IteratorType pos)
5234 {
5235 // make sure iterator fits the current value
5236 if (JSON_UNLIKELY(this != pos.m_object))
5237 {
5238 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
5239 }
5240
5241 switch (m_type)
5242 {
5243 case value_t::boolean:
5247 case value_t::string:
5248 {
5249 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
5250 {
5251 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
5252 }
5253
5254 if (is_string())
5255 {
5256 std::allocator<std::string> alloc;
5257 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
5258 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
5259 m_value.string = nullptr;
5260 }
5261
5262 m_type = value_t::null;
5263 assert_invariant();
5264 break;
5265 }
5266
5267 case value_t::object:
5268 {
5269 m_value.object->erase(pos.m_it.object_iterator);
5270 break;
5271 }
5272
5273 case value_t::array:
5274 {
5275 m_value.array->erase(pos.m_it.array_iterator);
5276 break;
5277 }
5278
5279 default:
5280 JSON_THROW(type_error::create(307, "cannot use erase() with", type_name()));
5281 }
5282 }
5283
5284 /*!
5285 @brief remove elements given an iterator range
5286
5287 Removes the element specified by the range `[first; last)`. The iterator
5288 @a first does not need to be dereferenceable if `first == last`: erasing
5289 an empty range is a no-op.
5290
5291 If called on a primitive type other than `null`, the resulting JSON value
5292 will be `null`.
5293
5294 @param[in] first iterator to the beginning of the range to remove
5295 @param[in] last iterator past the end of the range to remove
5296 @return Iterator following the last removed element. If the iterator @a
5297 second refers to the last element, the `end()` iterator is returned.
5298
5299 @tparam IteratorType an @ref iterator or @ref const_iterator
5300
5301 @post Invalidates iterators and references at or after the point of the
5302 erase, including the `end()` iterator.
5303
5304 @throw type_error.307 if called on a `null` value; example: `"cannot use
5305 erase() with null"`
5306 @throw invalid_iterator.203 if called on iterators which does not belong
5307 to the current JSON value; example: `"iterators do not fit current value"`
5308 @throw invalid_iterator.204 if called on a primitive type with invalid
5309 iterators (i.e., if `first != begin()` and `last != end()`); example:
5310 `"iterators out of range"`
5311
5312 @complexity The complexity depends on the type:
5313 - objects: `log(size()) + std::distance(first, last)`
5314 - arrays: linear in the distance between @a first and @a last, plus linear
5315 in the distance between @a last and end of the container
5316 - strings: linear in the length of the string
5317 - other types: constant
5318
5319 @liveexample{The example shows the result of `erase()` for different JSON
5320 types.,erase__IteratorType_IteratorType}
5321
5322 @sa @ref erase(IteratorType) -- removes the element at a given position
5323 @sa @ref erase(const typename object_t::key_type&) -- removes the element
5324 from an object at the given key
5325 @sa @ref erase(const size_type) -- removes the element from an array at
5326 the given index
5327
5328 @since version 1.0.0
5329 */
5330 template<class IteratorType, typename std::enable_if<
5331 std::is_same<IteratorType, typename json_t::iterator>::value or
5332 std::is_same<IteratorType, typename json_t::const_iterator>::value, int>::type
5333 = 0>
5334 IteratorType erase(IteratorType first, IteratorType last)
5335 {
5336 // make sure iterator fits the current value
5337 if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
5338 {
5339 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
5340 }
5341
5342 IteratorType result = end();
5343
5344 switch (m_type)
5345 {
5346 case value_t::boolean:
5350 case value_t::string:
5351 {
5352 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
5353 or not last.m_it.primitive_iterator.is_end()))
5354 {
5355 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
5356 }
5357
5358 if (is_string())
5359 {
5360 std::allocator<std::string> alloc;
5361 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
5362 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
5363 m_value.string = nullptr;
5364 }
5365
5366 m_type = value_t::null;
5367 assert_invariant();
5368 break;
5369 }
5370
5371 case value_t::array:
5372 {
5373 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
5374 last.m_it.array_iterator);
5375 break;
5376 }
5377
5378 default:
5379 JSON_THROW(type_error::create(307, "cannot use erase() with", type_name()));
5380 }
5381
5382 return result;
5383 }
5384
5385 /*!
5386 @brief remove element from a JSON object given a key
5387
5388 Removes elements from a JSON object with the key value @a key.
5389
5390 @param[in] key value of the elements to remove
5391
5392 @return Number of elements removed. If @a ObjectType is the default
5393 `std::map` type, the return value will always be `0` (@a key was not
5394 found) or `1` (@a key was found).
5395
5396 @post References and iterators to the erased elements are invalidated.
5397 Other references and iterators are not affected.
5398
5399 @throw type_error.307 when called on a type other than JSON object;
5400 example: `"cannot use erase() with null"`
5401
5402 @complexity `log(size()) + count(key)`
5403
5404 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
5405
5406 @sa @ref erase(IteratorType) -- removes the element at a given position
5407 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
5408 the given range
5409 @sa @ref erase(const size_type) -- removes the element from an array at
5410 the given index
5411
5412 @since version 1.0.0
5413 */
5415
5416 /*!
5417 @brief remove element from a JSON array given an index
5418
5419 Removes element from a JSON array at the index @a idx.
5420
5421 @param[in] idx index of the element to remove
5422
5423 @throw type_error.307 when called on a type other than JSON object;
5424 example: `"cannot use erase() with null"`
5425 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
5426 is out of range"`
5427
5428 @complexity Linear in distance between @a idx and the end of the container.
5429
5430 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
5431
5432 @sa @ref erase(IteratorType) -- removes the element at a given position
5433 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
5434 the given range
5435 @sa @ref erase(const typename object_t::key_type&) -- removes the element
5436 from an object at the given key
5437
5438 @since version 1.0.0
5439 */
5440 void erase(const size_type idx);
5441
5442 /// @}
5443
5444
5445 ////////////
5446 // lookup //
5447 ////////////
5448
5449 /// @name lookup
5450 /// @{
5451
5452 /*!
5453 @brief find an element in a JSON object
5454
5455 Finds an element in a JSON object with key equivalent to @a key. If the
5456 element is not found or the JSON value is not an object, end() is
5457 returned.
5458
5459 @note This method always returns @ref end() when executed on a JSON type
5460 that is not an object.
5461
5462 @param[in] key key value of the element to search for.
5463
5464 @return Iterator to an element with key equivalent to @a key. If no such
5465 element is found or the JSON value is not an object, past-the-end (see
5466 @ref end()) iterator is returned.
5467
5468 @complexity Logarithmic in the size of the JSON object.
5469
5470 @liveexample{The example shows how `find()` is used.,find__key_type}
5471
5472 @since version 1.0.0
5473 */
5475
5476 /*!
5477 @brief find an element in a JSON object
5478 @copydoc find(KeyT&&)
5479 */
5481
5482 /*!
5483 @brief returns the number of occurrences of a key in a JSON object
5484
5485 Returns the number of elements with key @a key. If ObjectType is the
5486 default `std::map` type, the return value will always be `0` (@a key was
5487 not found) or `1` (@a key was found).
5488
5489 @note This method always returns `0` when executed on a JSON type that is
5490 not an object.
5491
5492 @param[in] key key value of the element to count
5493
5494 @return Number of elements with key @a key. If the JSON value is not an
5495 object, the return value will be `0`.
5496
5497 @complexity Logarithmic in the size of the JSON object.
5498
5499 @liveexample{The example shows how `count()` is used.,count}
5500
5501 @since version 1.0.0
5502 */
5504
5505 /// @}
5506
5507
5508 ///////////////
5509 // iterators //
5510 ///////////////
5511
5512 /// @name iterators
5513 /// @{
5514
5515 /*!
5516 @brief returns an iterator to the first element
5517
5518 Returns an iterator to the first element.
5519
5520 @image html range-begin-end.svg "Illustration from cppreference.com"
5521
5522 @return iterator to the first element
5523
5524 @complexity Constant.
5525
5526 @requirement This function helps `json` satisfying the
5527 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5528 requirements:
5529 - The complexity is constant.
5530
5531 @liveexample{The following code shows an example for `begin()`.,begin}
5532
5533 @sa @ref cbegin() -- returns a const iterator to the beginning
5534 @sa @ref end() -- returns an iterator to the end
5535 @sa @ref cend() -- returns a const iterator to the end
5536
5537 @since version 1.0.0
5538 */
5539 iterator begin() noexcept
5540 {
5541 iterator result(this);
5542 result.set_begin();
5543 return result;
5544 }
5545
5546 /*!
5547 @copydoc json::cbegin()
5548 */
5549 const_iterator begin() const noexcept
5550 {
5551 return cbegin();
5552 }
5553
5554 /*!
5555 @brief returns a const iterator to the first element
5556
5557 Returns a const iterator to the first element.
5558
5559 @image html range-begin-end.svg "Illustration from cppreference.com"
5560
5561 @return const iterator to the first element
5562
5563 @complexity Constant.
5564
5565 @requirement This function helps `json` satisfying the
5566 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5567 requirements:
5568 - The complexity is constant.
5569 - Has the semantics of `const_cast<const json&>(*this).begin()`.
5570
5571 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
5572
5573 @sa @ref begin() -- returns an iterator to the beginning
5574 @sa @ref end() -- returns an iterator to the end
5575 @sa @ref cend() -- returns a const iterator to the end
5576
5577 @since version 1.0.0
5578 */
5579 const_iterator cbegin() const noexcept
5580 {
5581 const_iterator result(this);
5582 result.set_begin();
5583 return result;
5584 }
5585
5586 /*!
5587 @brief returns an iterator to one past the last element
5588
5589 Returns an iterator to one past the last element.
5590
5591 @image html range-begin-end.svg "Illustration from cppreference.com"
5592
5593 @return iterator one past the last element
5594
5595 @complexity Constant.
5596
5597 @requirement This function helps `json` satisfying the
5598 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5599 requirements:
5600 - The complexity is constant.
5601
5602 @liveexample{The following code shows an example for `end()`.,end}
5603
5604 @sa @ref cend() -- returns a const iterator to the end
5605 @sa @ref begin() -- returns an iterator to the beginning
5606 @sa @ref cbegin() -- returns a const iterator to the beginning
5607
5608 @since version 1.0.0
5609 */
5610 iterator end() noexcept
5611 {
5612 iterator result(this);
5613 result.set_end();
5614 return result;
5615 }
5616
5617 /*!
5618 @copydoc json::cend()
5619 */
5620 const_iterator end() const noexcept
5621 {
5622 return cend();
5623 }
5624
5625 /*!
5626 @brief returns a const iterator to one past the last element
5627
5628 Returns a const iterator to one past the last element.
5629
5630 @image html range-begin-end.svg "Illustration from cppreference.com"
5631
5632 @return const iterator one past the last element
5633
5634 @complexity Constant.
5635
5636 @requirement This function helps `json` satisfying the
5637 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5638 requirements:
5639 - The complexity is constant.
5640 - Has the semantics of `const_cast<const json&>(*this).end()`.
5641
5642 @liveexample{The following code shows an example for `cend()`.,cend}
5643
5644 @sa @ref end() -- returns an iterator to the end
5645 @sa @ref begin() -- returns an iterator to the beginning
5646 @sa @ref cbegin() -- returns a const iterator to the beginning
5647
5648 @since version 1.0.0
5649 */
5650 const_iterator cend() const noexcept
5651 {
5652 const_iterator result(this);
5653 result.set_end();
5654 return result;
5655 }
5656
5657 /*!
5658 @brief returns an iterator to the reverse-beginning
5659
5660 Returns an iterator to the reverse-beginning; that is, the last element.
5661
5662 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
5663
5664 @complexity Constant.
5665
5666 @requirement This function helps `json` satisfying the
5667 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
5668 requirements:
5669 - The complexity is constant.
5670 - Has the semantics of `reverse_iterator(end())`.
5671
5672 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
5673
5674 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
5675 @sa @ref rend() -- returns a reverse iterator to the end
5676 @sa @ref crend() -- returns a const reverse iterator to the end
5677
5678 @since version 1.0.0
5679 */
5681 {
5682 return reverse_iterator(end());
5683 }
5684
5685 /*!
5686 @copydoc json::crbegin()
5687 */
5689 {
5690 return crbegin();
5691 }
5692
5693 /*!
5694 @brief returns an iterator to the reverse-end
5695
5696 Returns an iterator to the reverse-end; that is, one before the first
5697 element.
5698
5699 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
5700
5701 @complexity Constant.
5702
5703 @requirement This function helps `json` satisfying the
5704 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
5705 requirements:
5706 - The complexity is constant.
5707 - Has the semantics of `reverse_iterator(begin())`.
5708
5709 @liveexample{The following code shows an example for `rend()`.,rend}
5710
5711 @sa @ref crend() -- returns a const reverse iterator to the end
5712 @sa @ref rbegin() -- returns a reverse iterator to the beginning
5713 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
5714
5715 @since version 1.0.0
5716 */
5718 {
5719 return reverse_iterator(begin());
5720 }
5721
5722 /*!
5723 @copydoc json::crend()
5724 */
5726 {
5727 return crend();
5728 }
5729
5730 /*!
5731 @brief returns a const reverse iterator to the last element
5732
5733 Returns a const iterator to the reverse-beginning; that is, the last
5734 element.
5735
5736 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
5737
5738 @complexity Constant.
5739
5740 @requirement This function helps `json` satisfying the
5741 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
5742 requirements:
5743 - The complexity is constant.
5744 - Has the semantics of `const_cast<const json&>(*this).rbegin()`.
5745
5746 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
5747
5748 @sa @ref rbegin() -- returns a reverse iterator to the beginning
5749 @sa @ref rend() -- returns a reverse iterator to the end
5750 @sa @ref crend() -- returns a const reverse iterator to the end
5751
5752 @since version 1.0.0
5753 */
5755 {
5756 return const_reverse_iterator(cend());
5757 }
5758
5759 /*!
5760 @brief returns a const reverse iterator to one before the first
5761
5762 Returns a const reverse iterator to the reverse-end; that is, one before
5763 the first element.
5764
5765 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
5766
5767 @complexity Constant.
5768
5769 @requirement This function helps `json` satisfying the
5770 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
5771 requirements:
5772 - The complexity is constant.
5773 - Has the semantics of `const_cast<const json&>(*this).rend()`.
5774
5775 @liveexample{The following code shows an example for `crend()`.,crend}
5776
5777 @sa @ref rend() -- returns a reverse iterator to the end
5778 @sa @ref rbegin() -- returns a reverse iterator to the beginning
5779 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
5780
5781 @since version 1.0.0
5782 */
5784 {
5786 }
5787
5788 public:
5789 /*!
5790 @brief helper to access iterator member functions in range-based for
5791
5792 This function allows to access @ref iterator::key() and @ref
5793 iterator::value() during range-based for loops. In these loops, a
5794 reference to the JSON values is returned, so there is no access to the
5795 underlying iterator.
5796
5797 For loop without `items()` function:
5798
5799 @code{cpp}
5800 for (auto it = j_object.begin(); it != j_object.end(); ++it)
5801 {
5802 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
5803 }
5804 @endcode
5805
5806 Range-based for loop without `items()` function:
5807
5808 @code{cpp}
5809 for (auto it : j_object)
5810 {
5811 // "it" is of type json::reference and has no key() member
5812 std::cout << "value: " << it << '\n';
5813 }
5814 @endcode
5815
5816 Range-based for loop with `items()` function:
5817
5818 @code{cpp}
5819 for (auto it : j_object.items())
5820 {
5821 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
5822 }
5823 @endcode
5824
5825 @note When iterating over an array, `key()` will return the index of the
5826 element as string (see example). For primitive types (e.g., numbers),
5827 `key()` returns an empty string.
5828
5829 @return iteration proxy object wrapping @a ref with an interface to use in
5830 range-based for loops
5831
5832 @liveexample{The following code shows how the function is used.,items}
5833
5834 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
5835 changes in the JSON value.
5836
5837 @complexity Constant.
5838
5839 @since version 3.x.x.
5840 */
5842 {
5843 return iteration_proxy<iterator>(*this);
5844 }
5845
5846 /*!
5847 @copydoc items()
5848 */
5850 {
5851 return iteration_proxy<const_iterator>(*this);
5852 }
5853
5854 /// @}
5855
5856
5857 //////////////
5858 // capacity //
5859 //////////////
5860
5861 /// @name capacity
5862 /// @{
5863
5864 /*!
5865 @brief checks whether the container is empty.
5866
5867 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
5868
5869 @return The return value depends on the different types and is
5870 defined as follows:
5871 Value type | return value
5872 ----------- | -------------
5873 null | `true`
5874 boolean | `false`
5875 string | `false`
5876 number | `false`
5877 object | result of function `object_t::empty()`
5878 array | result of function `array_t::empty()`
5879
5880 @liveexample{The following code uses `empty()` to check if a JSON
5881 object contains any elements.,empty}
5882
5883 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
5884 the Container concept; that is, their `empty()` functions have constant
5885 complexity.
5886
5887 @iterators No changes.
5888
5889 @exceptionsafety No-throw guarantee: this function never throws exceptions.
5890
5891 @note This function does not return whether a string stored as JSON value
5892 is empty - it returns whether the JSON container itself is empty which is
5893 false in the case of a string.
5894
5895 @requirement This function helps `json` satisfying the
5896 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5897 requirements:
5898 - The complexity is constant.
5899 - Has the semantics of `begin() == end()`.
5900
5901 @sa @ref size() -- returns the number of elements
5902
5903 @since version 1.0.0
5904 */
5905 bool empty() const noexcept;
5906
5907 /*!
5908 @brief returns the number of elements
5909
5910 Returns the number of elements in a JSON value.
5911
5912 @return The return value depends on the different types and is
5913 defined as follows:
5914 Value type | return value
5915 ----------- | -------------
5916 null | `0`
5917 boolean | `1`
5918 string | `1`
5919 number | `1`
5920 object | result of function object_t::size()
5921 array | result of function array_t::size()
5922
5923 @liveexample{The following code calls `size()` on the different value
5924 types.,size}
5925
5926 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
5927 the Container concept; that is, their size() functions have constant
5928 complexity.
5929
5930 @iterators No changes.
5931
5932 @exceptionsafety No-throw guarantee: this function never throws exceptions.
5933
5934 @note This function does not return the length of a string stored as JSON
5935 value - it returns the number of elements in the JSON value which is 1 in
5936 the case of a string.
5937
5938 @requirement This function helps `json` satisfying the
5939 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5940 requirements:
5941 - The complexity is constant.
5942 - Has the semantics of `std::distance(begin(), end())`.
5943
5944 @sa @ref empty() -- checks whether the container is empty
5945 @sa @ref max_size() -- returns the maximal number of elements
5946
5947 @since version 1.0.0
5948 */
5949 size_type size() const noexcept;
5950
5951 /*!
5952 @brief returns the maximum possible number of elements
5953
5954 Returns the maximum number of elements a JSON value is able to hold due to
5955 system or library implementation limitations, i.e. `std::distance(begin(),
5956 end())` for the JSON value.
5957
5958 @return The return value depends on the different types and is
5959 defined as follows:
5960 Value type | return value
5961 ----------- | -------------
5962 null | `0` (same as `size()`)
5963 boolean | `1` (same as `size()`)
5964 string | `1` (same as `size()`)
5965 number | `1` (same as `size()`)
5966 object | result of function `object_t::max_size()`
5967 array | result of function `array_t::max_size()`
5968
5969 @liveexample{The following code calls `max_size()` on the different value
5970 types. Note the output is implementation specific.,max_size}
5971
5972 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
5973 the Container concept; that is, their `max_size()` functions have constant
5974 complexity.
5975
5976 @iterators No changes.
5977
5978 @exceptionsafety No-throw guarantee: this function never throws exceptions.
5979
5980 @requirement This function helps `json` satisfying the
5981 [Container](http://en.cppreference.com/w/cpp/concept/Container)
5982 requirements:
5983 - The complexity is constant.
5984 - Has the semantics of returning `b.size()` where `b` is the largest
5985 possible JSON value.
5986
5987 @sa @ref size() -- returns the number of elements
5988
5989 @since version 1.0.0
5990 */
5991 size_type max_size() const noexcept;
5992
5993 /// @}
5994
5995
5996 ///////////////
5997 // modifiers //
5998 ///////////////
5999
6000 /// @name modifiers
6001 /// @{
6002
6003 /*!
6004 @brief clears the contents
6005
6006 Clears the content of a JSON value and resets it to the default value as
6007 if @ref json(value_t) would have been called with the current value
6008 type from @ref type():
6009
6010 Value type | initial value
6011 ----------- | -------------
6012 null | `null`
6013 boolean | `false`
6014 string | `""`
6015 number | `0`
6016 object | `{}`
6017 array | `[]`
6018
6019 @post Has the same effect as calling
6020 @code {.cpp}
6021 *this = json(type());
6022 @endcode
6023
6024 @liveexample{The example below shows the effect of `clear()` to different
6025 JSON types.,clear}
6026
6027 @complexity Linear in the size of the JSON value.
6028
6029 @iterators All iterators, pointers and references related to this container
6030 are invalidated.
6031
6032 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6033
6034 @sa @ref json(value_t) -- constructor that creates an object with the
6035 same value than calling `clear()`
6036
6037 @since version 1.0.0
6038 */
6039 void clear() noexcept;
6040
6041 /*!
6042 @brief add an object to an array
6043
6044 Appends the given element @a val to the end of the JSON value. If the
6045 function is called on a JSON null value, an empty array is created before
6046 appending @a val.
6047
6048 @param[in] val the value to add to the JSON array
6049
6050 @throw type_error.308 when called on a type other than JSON array or
6051 null; example: `"cannot use push_back() with number"`
6052
6053 @complexity Amortized constant.
6054
6055 @liveexample{The example shows how `push_back()` and `+=` can be used to
6056 add elements to a JSON array. Note how the `null` value was silently
6057 converted to a JSON array.,push_back}
6058
6059 @since version 1.0.0
6060 */
6061 void push_back(json&& val);
6062
6063 /*!
6064 @brief add an object to an array
6065 @copydoc push_back(json&&)
6066 */
6067 reference operator+=(json&& val)
6068 {
6069 push_back(std::move(val));
6070 return *this;
6071 }
6072
6073 /*!
6074 @brief add an object to an array
6075 @copydoc push_back(json&&)
6076 */
6077 void push_back(const json& val);
6078
6079 /*!
6080 @brief add an object to an array
6081 @copydoc push_back(json&&)
6082 */
6084 {
6085 push_back(val);
6086 return *this;
6087 }
6088
6089 /*!
6090 @brief add an object to an object
6091
6092 Inserts the given element @a val to the JSON object. If the function is
6093 called on a JSON null value, an empty object is created before inserting
6094 @a val.
6095
6096 @param[in] val the value to add to the JSON object
6097
6098 @throw type_error.308 when called on a type other than JSON object or
6099 null; example: `"cannot use push_back() with number"`
6100
6101 @complexity Logarithmic in the size of the container, O(log(`size()`)).
6102
6103 @liveexample{The example shows how `push_back()` and `+=` can be used to
6104 add elements to a JSON object. Note how the `null` value was silently
6105 converted to a JSON object.,push_back__object_t__value}
6106
6107 @since version 1.0.0
6108 */
6109 template<typename T, typename U>
6110 void push_back(const std::pair<T, U>& val)
6111 {
6112 // push_back only works for null objects or objects
6113 if (JSON_UNLIKELY(not(is_null() or is_object())))
6114 {
6115 JSON_THROW(type_error::create(308, "cannot use push_back() with", type_name()));
6116 }
6117
6118 // transform null object into an object
6119 if (is_null())
6120 {
6121 m_type = value_t::object;
6122 m_value = value_t::object;
6123 assert_invariant();
6124 }
6125
6126 // add element to array
6127 m_value.object->try_emplace(val.first, std::move(val.second));
6128 }
6129
6130 /*!
6131 @brief add an object to an object
6132 @copydoc push_back(const typename object_t::value_type&)
6133 */
6134 template<typename T, typename U>
6135 reference operator+=(const std::pair<T, U>& val)
6136 {
6137 push_back(val);
6138 return *this;
6139 }
6140
6141 /*!
6142 @brief add an object to an object
6143
6144 This function allows to use `push_back` with an initializer list. In case
6145
6146 1. the current value is an object,
6147 2. the initializer list @a init contains only two elements, and
6148 3. the first element of @a init is a string,
6149
6150 @a init is converted into an object element and added using
6151 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
6152 is converted to a JSON value and added using @ref push_back(json&&).
6153
6154 @param[in] init an initializer list
6155
6156 @complexity Linear in the size of the initializer list @a init.
6157
6158 @note This function is required to resolve an ambiguous overload error,
6159 because pairs like `{"key", "value"}` can be both interpreted as
6160 `object_t::value_type` or `std::initializer_list<json>`, see
6161 https://github.com/nlohmann/json/issues/235 for more information.
6162
6163 @liveexample{The example shows how initializer lists are treated as
6164 objects when possible.,push_back__initializer_list}
6165 */
6167
6168 /*!
6169 @brief add an object to an object
6170 @copydoc push_back(initializer_list_t)
6171 */
6173 {
6174 push_back(init);
6175 return *this;
6176 }
6177
6178 /*!
6179 @brief add an object to an array
6180
6181 Creates a JSON value from the passed parameters @a args to the end of the
6182 JSON value. If the function is called on a JSON null value, an empty array
6183 is created before appending the value created from @a args.
6184
6185 @param[in] args arguments to forward to a constructor of @ref json
6186 @tparam Args compatible types to create a @ref json object
6187
6188 @throw type_error.311 when called on a type other than JSON array or
6189 null; example: `"cannot use emplace_back() with number"`
6190
6191 @complexity Amortized constant.
6192
6193 @liveexample{The example shows how `push_back()` can be used to add
6194 elements to a JSON array. Note how the `null` value was silently converted
6195 to a JSON array.,emplace_back}
6196
6197 @since version 2.0.8
6198 */
6199 template<class... Args>
6200 void emplace_back(Args&& ... args)
6201 {
6202 // emplace_back only works for null objects or arrays
6203 if (JSON_UNLIKELY(not(is_null() or is_array())))
6204 {
6205 JSON_THROW(type_error::create(311, "cannot use emplace_back() with", type_name()));
6206 }
6207
6208 // transform null object into an array
6209 if (is_null())
6210 {
6211 m_type = value_t::array;
6212 m_value = value_t::array;
6213 assert_invariant();
6214 }
6215
6216 // add element to array (perfect forwarding)
6217 m_value.array->emplace_back(std::forward<Args>(args)...);
6218 }
6219
6220 /*!
6221 @brief add an object to an object if key does not exist
6222
6223 Inserts a new element into a JSON object constructed in-place with the
6224 given @a args if there is no element with the key in the container. If the
6225 function is called on a JSON null value, an empty object is created before
6226 appending the value created from @a args.
6227
6228 @param[in] args arguments to forward to a constructor of @ref json
6229 @tparam Args compatible types to create a @ref json object
6230
6231 @return a pair consisting of an iterator to the inserted element, or the
6232 already-existing element if no insertion happened, and a bool
6233 denoting whether the insertion took place.
6234
6235 @throw type_error.311 when called on a type other than JSON object or
6236 null; example: `"cannot use emplace() with number"`
6237
6238 @complexity Logarithmic in the size of the container, O(log(`size()`)).
6239
6240 @liveexample{The example shows how `emplace()` can be used to add elements
6241 to a JSON object. Note how the `null` value was silently converted to a
6242 JSON object. Further note how no value is added if there was already one
6243 value stored with the same key.,emplace}
6244
6245 @since version 2.0.8
6246 */
6247 template<class... Args>
6248 std::pair<iterator, bool> emplace(std::string_view key, Args&& ... args)
6249 {
6250 // emplace only works for null objects or arrays
6251 if (JSON_UNLIKELY(not(is_null() or is_object())))
6252 {
6253 JSON_THROW(type_error::create(311, "cannot use emplace() with", type_name()));
6254 }
6255
6256 // transform null object into an object
6257 if (is_null())
6258 {
6259 m_type = value_t::object;
6260 m_value = value_t::object;
6261 assert_invariant();
6262 }
6263
6264 // add element to array (perfect forwarding)
6265 auto res = m_value.object->try_emplace(key, std::forward<Args>(args)...);
6266 // create result iterator and set iterator to the result of emplace
6267 auto it = begin();
6268 it.m_it.object_iterator = res.first;
6269
6270 // return pair of iterator and boolean
6271 return {it, res.second};
6272 }
6273
6274 /*!
6275 @brief inserts element
6276
6277 Inserts element @a val before iterator @a pos.
6278
6279 @param[in] pos iterator before which the content will be inserted; may be
6280 the end() iterator
6281 @param[in] val element to insert
6282 @return iterator pointing to the inserted @a val.
6283
6284 @throw type_error.309 if called on JSON values other than arrays;
6285 example: `"cannot use insert() with string"`
6286 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
6287 example: `"iterator does not fit current value"`
6288
6289 @complexity Constant plus linear in the distance between @a pos and end of
6290 the container.
6291
6292 @liveexample{The example shows how `insert()` is used.,insert}
6293
6294 @since version 1.0.0
6295 */
6297
6298 /*!
6299 @brief inserts element
6300 @copydoc insert(const_iterator, const json&)
6301 */
6303 {
6304 return insert(pos, val);
6305 }
6306
6307 /*!
6308 @brief inserts elements
6309
6310 Inserts @a cnt copies of @a val before iterator @a pos.
6311
6312 @param[in] pos iterator before which the content will be inserted; may be
6313 the end() iterator
6314 @param[in] cnt number of copies of @a val to insert
6315 @param[in] val element to insert
6316 @return iterator pointing to the first element inserted, or @a pos if
6317 `cnt==0`
6318
6319 @throw type_error.309 if called on JSON values other than arrays; example:
6320 `"cannot use insert() with string"`
6321 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
6322 example: `"iterator does not fit current value"`
6323
6324 @complexity Linear in @a cnt plus linear in the distance between @a pos
6325 and end of the container.
6326
6327 @liveexample{The example shows how `insert()` is used.,insert__count}
6328
6329 @since version 1.0.0
6330 */
6332
6333 /*!
6334 @brief inserts elements
6335
6336 Inserts elements from range `[first, last)` before iterator @a pos.
6337
6338 @param[in] pos iterator before which the content will be inserted; may be
6339 the end() iterator
6340 @param[in] first begin of the range of elements to insert
6341 @param[in] last end of the range of elements to insert
6342
6343 @throw type_error.309 if called on JSON values other than arrays; example:
6344 `"cannot use insert() with string"`
6345 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
6346 example: `"iterator does not fit current value"`
6347 @throw invalid_iterator.210 if @a first and @a last do not belong to the
6348 same JSON value; example: `"iterators do not fit"`
6349 @throw invalid_iterator.211 if @a first or @a last are iterators into
6350 container for which insert is called; example: `"passed iterators may not
6351 belong to container"`
6352
6353 @return iterator pointing to the first element inserted, or @a pos if
6354 `first==last`
6355
6356 @complexity Linear in `std::distance(first, last)` plus linear in the
6357 distance between @a pos and end of the container.
6358
6359 @liveexample{The example shows how `insert()` is used.,insert__range}
6360
6361 @since version 1.0.0
6362 */
6364
6365 /*!
6366 @brief inserts elements
6367
6368 Inserts elements from initializer list @a ilist before iterator @a pos.
6369
6370 @param[in] pos iterator before which the content will be inserted; may be
6371 the end() iterator
6372 @param[in] ilist initializer list to insert the values from
6373
6374 @throw type_error.309 if called on JSON values other than arrays; example:
6375 `"cannot use insert() with string"`
6376 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
6377 example: `"iterator does not fit current value"`
6378
6379 @return iterator pointing to the first element inserted, or @a pos if
6380 `ilist` is empty
6381
6382 @complexity Linear in `ilist.size()` plus linear in the distance between
6383 @a pos and end of the container.
6384
6385 @liveexample{The example shows how `insert()` is used.,insert__ilist}
6386
6387 @since version 1.0.0
6388 */
6390
6391 /*!
6392 @brief inserts elements
6393
6394 Inserts elements from range `[first, last)`.
6395
6396 @param[in] first begin of the range of elements to insert
6397 @param[in] last end of the range of elements to insert
6398
6399 @throw type_error.309 if called on JSON values other than objects; example:
6400 `"cannot use insert() with string"`
6401 @throw invalid_iterator.202 if iterator @a first or @a last does does not
6402 point to an object; example: `"iterators first and last must point to
6403 objects"`
6404 @throw invalid_iterator.210 if @a first and @a last do not belong to the
6405 same JSON value; example: `"iterators do not fit"`
6406
6407 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
6408 of elements to insert.
6409
6410 @liveexample{The example shows how `insert()` is used.,insert__range_object}
6411
6412 @since version 3.0.0
6413 */
6415
6416 /*!
6417 @brief updates a JSON object from another object, overwriting existing keys
6418
6419 Inserts all values from JSON object @a j and overwrites existing keys.
6420
6421 @param[in] j JSON object to read values from
6422
6423 @throw type_error.312 if called on JSON values other than objects; example:
6424 `"cannot use update() with string"`
6425
6426 @complexity O(N*log(size() + N)), where N is the number of elements to
6427 insert.
6428
6429 @liveexample{The example shows how `update()` is used.,update}
6430
6431 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
6432
6433 @since version 3.0.0
6434 */
6436
6437 /*!
6438 @brief updates a JSON object from another object, overwriting existing keys
6439
6440 Inserts all values from from range `[first, last)` and overwrites existing
6441 keys.
6442
6443 @param[in] first begin of the range of elements to insert
6444 @param[in] last end of the range of elements to insert
6445
6446 @throw type_error.312 if called on JSON values other than objects; example:
6447 `"cannot use update() with string"`
6448 @throw invalid_iterator.202 if iterator @a first or @a last does does not
6449 point to an object; example: `"iterators first and last must point to
6450 objects"`
6451 @throw invalid_iterator.210 if @a first and @a last do not belong to the
6452 same JSON value; example: `"iterators do not fit"`
6453
6454 @complexity O(N*log(size() + N)), where N is the number of elements to
6455 insert.
6456
6457 @liveexample{The example shows how `update()` is used__range.,update}
6458
6459 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
6460
6461 @since version 3.0.0
6462 */
6464
6465 /*!
6466 @brief exchanges the values
6467
6468 Exchanges the contents of the JSON value with those of @a other. Does not
6469 invoke any move, copy, or swap operations on individual elements. All
6470 iterators and references remain valid. The past-the-end iterator is
6471 invalidated.
6472
6473 @param[in,out] other JSON value to exchange the contents with
6474
6475 @complexity Constant.
6476
6477 @liveexample{The example below shows how JSON values can be swapped with
6478 `swap()`.,swap__reference}
6479
6480 @since version 1.0.0
6481 */
6482 void swap(reference other) noexcept (
6483 std::is_nothrow_move_constructible<value_t>::value and
6484 std::is_nothrow_move_assignable<value_t>::value and
6485 std::is_nothrow_move_constructible<json_value>::value and
6486 std::is_nothrow_move_assignable<json_value>::value
6487 )
6488 {
6489 std::swap(m_type, other.m_type);
6490 std::swap(m_value, other.m_value);
6491 assert_invariant();
6492 }
6493
6494 /*!
6495 @brief exchanges the values
6496
6497 Exchanges the contents of a JSON array with those of @a other. Does not
6498 invoke any move, copy, or swap operations on individual elements. All
6499 iterators and references remain valid. The past-the-end iterator is
6500 invalidated.
6501
6502 @param[in,out] other array to exchange the contents with
6503
6504 @throw type_error.310 when JSON value is not an array; example: `"cannot
6505 use swap() with string"`
6506
6507 @complexity Constant.
6508
6509 @liveexample{The example below shows how arrays can be swapped with
6510 `swap()`.,swap__std_vector_json}
6511
6512 @since version 1.0.0
6513 */
6514 void swap(array_t& other)
6515 {
6516 // swap only works for arrays
6517 if (JSON_LIKELY(is_array()))
6518 {
6519 std::swap(*(m_value.array), other);
6520 }
6521 else
6522 {
6523 JSON_THROW(type_error::create(310, "cannot use swap() with", type_name()));
6524 }
6525 }
6526
6527 /*!
6528 @brief exchanges the values
6529
6530 Exchanges the contents of a JSON object with those of @a other. Does not
6531 invoke any move, copy, or swap operations on individual elements. All
6532 iterators and references remain valid. The past-the-end iterator is
6533 invalidated.
6534
6535 @param[in,out] other object to exchange the contents with
6536
6537 @throw type_error.310 when JSON value is not an object; example:
6538 `"cannot use swap() with string"`
6539
6540 @complexity Constant.
6541
6542 @liveexample{The example below shows how objects can be swapped with
6543 `swap()`.,swap__object_t}
6544
6545 @since version 1.0.0
6546 */
6547 void swap(object_t& other)
6548 {
6549 // swap only works for objects
6550 if (JSON_LIKELY(is_object()))
6551 {
6552 std::swap(*(m_value.object), other);
6553 }
6554 else
6555 {
6556 JSON_THROW(type_error::create(310, "cannot use swap() with", type_name()));
6557 }
6558 }
6559
6560 /*!
6561 @brief exchanges the values
6562
6563 Exchanges the contents of a JSON string with those of @a other. Does not
6564 invoke any move, copy, or swap operations on individual elements. All
6565 iterators and references remain valid. The past-the-end iterator is
6566 invalidated.
6567
6568 @param[in,out] other string to exchange the contents with
6569
6570 @throw type_error.310 when JSON value is not a string; example: `"cannot
6571 use swap() with boolean"`
6572
6573 @complexity Constant.
6574
6575 @liveexample{The example below shows how strings can be swapped with
6576 `swap()`.,swap__std_string}
6577
6578 @since version 1.0.0
6579 */
6580 void swap(std::string& other)
6581 {
6582 // swap only works for strings
6583 if (JSON_LIKELY(is_string()))
6584 {
6585 std::swap(*(m_value.string), other);
6586 }
6587 else
6588 {
6589 JSON_THROW(type_error::create(310, "cannot use swap() with", type_name()));
6590 }
6591 }
6592
6593 /// @}
6594
6595 public:
6596 //////////////////////////////////////////
6597 // lexicographical comparison operators //
6598 //////////////////////////////////////////
6599
6600 /// @name lexicographical comparison operators
6601 /// @{
6602
6603 /*!
6604 @brief comparison: equal
6605
6606 Compares two JSON values for equality according to the following rules:
6607 - Two JSON values are equal if (1) they are from the same type and (2)
6608 their stored values are the same according to their respective
6609 `operator==`.
6610 - Integer and floating-point numbers are automatically converted before
6611 comparison. Note than two NaN values are always treated as unequal.
6612 - Two JSON null values are equal.
6613
6614 @note Floating-point inside JSON values numbers are compared with
6615 `double::operator==`.
6616 To compare floating-point while respecting an epsilon, an alternative
6617 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
6618 could be used, for instance
6619 @code {.cpp}
6620 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
6621 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
6622 {
6623 return std::abs(a - b) <= epsilon;
6624 }
6625 @endcode
6626
6627 @note NaN values never compare equal to themselves or to other NaN values.
6628
6629 @param[in] lhs first JSON value to consider
6630 @param[in] rhs second JSON value to consider
6631 @return whether the values @a lhs and @a rhs are equal
6632
6633 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6634
6635 @complexity Linear.
6636
6637 @liveexample{The example demonstrates comparing several JSON
6638 types.,operator__equal}
6639
6640 @since version 1.0.0
6641 */
6642 friend bool operator==(const_reference lhs, const_reference rhs) noexcept;
6643
6644 /*!
6645 @brief comparison: equal
6646 @copydoc operator==(const_reference, const_reference)
6647 */
6648 template<typename ScalarType, typename std::enable_if<
6649 std::is_scalar<ScalarType>::value, int>::type = 0>
6650 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
6651 {
6652 return (lhs == json(rhs));
6653 }
6654
6655 /*!
6656 @brief comparison: equal
6657 @copydoc operator==(const_reference, const_reference)
6658 */
6659 template<typename ScalarType, typename std::enable_if<
6660 std::is_scalar<ScalarType>::value, int>::type = 0>
6661 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
6662 {
6663 return (json(lhs) == rhs);
6664 }
6665
6666 /*!
6667 @brief comparison: not equal
6668
6669 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
6670
6671 @param[in] lhs first JSON value to consider
6672 @param[in] rhs second JSON value to consider
6673 @return whether the values @a lhs and @a rhs are not equal
6674
6675 @complexity Linear.
6676
6677 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6678
6679 @liveexample{The example demonstrates comparing several JSON
6680 types.,operator__notequal}
6681
6682 @since version 1.0.0
6683 */
6684 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
6685 {
6686 return not (lhs == rhs);
6687 }
6688
6689 /*!
6690 @brief comparison: not equal
6691 @copydoc operator!=(const_reference, const_reference)
6692 */
6693 template<typename ScalarType, typename std::enable_if<
6694 std::is_scalar<ScalarType>::value, int>::type = 0>
6695 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
6696 {
6697 return (lhs != json(rhs));
6698 }
6699
6700 /*!
6701 @brief comparison: not equal
6702 @copydoc operator!=(const_reference, const_reference)
6703 */
6704 template<typename ScalarType, typename std::enable_if<
6705 std::is_scalar<ScalarType>::value, int>::type = 0>
6706 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
6707 {
6708 return (json(lhs) != rhs);
6709 }
6710
6711 /*!
6712 @brief comparison: less than
6713
6714 Compares whether one JSON value @a lhs is less than another JSON value @a
6715 rhs according to the following rules:
6716 - If @a lhs and @a rhs have the same type, the values are compared using
6717 the default `<` operator.
6718 - Integer and floating-point numbers are automatically converted before
6719 comparison
6720 - In case @a lhs and @a rhs have different types, the values are ignored
6721 and the order of the types is considered, see
6722 @ref operator<(const value_t, const value_t).
6723
6724 @param[in] lhs first JSON value to consider
6725 @param[in] rhs second JSON value to consider
6726 @return whether @a lhs is less than @a rhs
6727
6728 @complexity Linear.
6729
6730 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6731
6732 @liveexample{The example demonstrates comparing several JSON
6733 types.,operator__less}
6734
6735 @since version 1.0.0
6736 */
6737 friend bool operator<(const_reference lhs, const_reference rhs) noexcept;
6738
6739 /*!
6740 @brief comparison: less than
6741 @copydoc operator<(const_reference, const_reference)
6742 */
6743 template<typename ScalarType, typename std::enable_if<
6744 std::is_scalar<ScalarType>::value, int>::type = 0>
6745 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
6746 {
6747 return (lhs < json(rhs));
6748 }
6749
6750 /*!
6751 @brief comparison: less than
6752 @copydoc operator<(const_reference, const_reference)
6753 */
6754 template<typename ScalarType, typename std::enable_if<
6755 std::is_scalar<ScalarType>::value, int>::type = 0>
6756 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
6757 {
6758 return (json(lhs) < rhs);
6759 }
6760
6761 /*!
6762 @brief comparison: less than or equal
6763
6764 Compares whether one JSON value @a lhs is less than or equal to another
6765 JSON value by calculating `not (rhs < lhs)`.
6766
6767 @param[in] lhs first JSON value to consider
6768 @param[in] rhs second JSON value to consider
6769 @return whether @a lhs is less than or equal to @a rhs
6770
6771 @complexity Linear.
6772
6773 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6774
6775 @liveexample{The example demonstrates comparing several JSON
6776 types.,operator__greater}
6777
6778 @since version 1.0.0
6779 */
6780 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
6781 {
6782 return not (rhs < lhs);
6783 }
6784
6785 /*!
6786 @brief comparison: less than or equal
6787 @copydoc operator<=(const_reference, const_reference)
6788 */
6789 template<typename ScalarType, typename std::enable_if<
6790 std::is_scalar<ScalarType>::value, int>::type = 0>
6791 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
6792 {
6793 return (lhs <= json(rhs));
6794 }
6795
6796 /*!
6797 @brief comparison: less than or equal
6798 @copydoc operator<=(const_reference, const_reference)
6799 */
6800 template<typename ScalarType, typename std::enable_if<
6801 std::is_scalar<ScalarType>::value, int>::type = 0>
6802 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
6803 {
6804 return (json(lhs) <= rhs);
6805 }
6806
6807 /*!
6808 @brief comparison: greater than
6809
6810 Compares whether one JSON value @a lhs is greater than another
6811 JSON value by calculating `not (lhs <= rhs)`.
6812
6813 @param[in] lhs first JSON value to consider
6814 @param[in] rhs second JSON value to consider
6815 @return whether @a lhs is greater than to @a rhs
6816
6817 @complexity Linear.
6818
6819 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6820
6821 @liveexample{The example demonstrates comparing several JSON
6822 types.,operator__lessequal}
6823
6824 @since version 1.0.0
6825 */
6826 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
6827 {
6828 return not (lhs <= rhs);
6829 }
6830
6831 /*!
6832 @brief comparison: greater than
6833 @copydoc operator>(const_reference, const_reference)
6834 */
6835 template<typename ScalarType, typename std::enable_if<
6836 std::is_scalar<ScalarType>::value, int>::type = 0>
6837 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
6838 {
6839 return (lhs > json(rhs));
6840 }
6841
6842 /*!
6843 @brief comparison: greater than
6844 @copydoc operator>(const_reference, const_reference)
6845 */
6846 template<typename ScalarType, typename std::enable_if<
6847 std::is_scalar<ScalarType>::value, int>::type = 0>
6848 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
6849 {
6850 return (json(lhs) > rhs);
6851 }
6852
6853 /*!
6854 @brief comparison: greater than or equal
6855
6856 Compares whether one JSON value @a lhs is greater than or equal to another
6857 JSON value by calculating `not (lhs < rhs)`.
6858
6859 @param[in] lhs first JSON value to consider
6860 @param[in] rhs second JSON value to consider
6861 @return whether @a lhs is greater than or equal to @a rhs
6862
6863 @complexity Linear.
6864
6865 @exceptionsafety No-throw guarantee: this function never throws exceptions.
6866
6867 @liveexample{The example demonstrates comparing several JSON
6868 types.,operator__greaterequal}
6869
6870 @since version 1.0.0
6871 */
6872 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
6873 {
6874 return not (lhs < rhs);
6875 }
6876
6877 /*!
6878 @brief comparison: greater than or equal
6879 @copydoc operator>=(const_reference, const_reference)
6880 */
6881 template<typename ScalarType, typename std::enable_if<
6882 std::is_scalar<ScalarType>::value, int>::type = 0>
6883 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
6884 {
6885 return (lhs >= json(rhs));
6886 }
6887
6888 /*!
6889 @brief comparison: greater than or equal
6890 @copydoc operator>=(const_reference, const_reference)
6891 */
6892 template<typename ScalarType, typename std::enable_if<
6893 std::is_scalar<ScalarType>::value, int>::type = 0>
6894 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
6895 {
6896 return (json(lhs) >= rhs);
6897 }
6898
6899 /// @}
6900
6901 ///////////////////
6902 // serialization //
6903 ///////////////////
6904
6905 /// @name serialization
6906 /// @{
6907
6908 /*!
6909 @brief serialize to stream
6910
6911 Serialize the given JSON value @a j to the output stream @a o. The JSON
6912 value will be serialized using the @ref dump member function.
6913
6914 - The indentation of the output can be controlled with the member variable
6915 `width` of the output stream @a o. For instance, using the manipulator
6916 `std::setw(4)` on @a o sets the indentation level to `4` and the
6917 serialization result is the same as calling `dump(4)`.
6918
6919 - The indentation character can be controlled with the member variable
6920 `fill` of the output stream @a o. For instance, the manipulator
6921 `std::setfill('\\t')` sets indentation to use a tab character rather than
6922 the default space character.
6923
6924 @param[in,out] o stream to serialize to
6925 @param[in] j JSON value to serialize
6926
6927 @return the stream @a o
6928
6929 @throw type_error.316 if a string stored inside the JSON value is not
6930 UTF-8 encoded
6931
6932 @complexity Linear.
6933
6934 @liveexample{The example below shows the serialization with different
6935 parameters to `width` to adjust the indentation level.,operator_serialize}
6936
6937 @since version 1.0.0; indentation character added in version 3.0.0
6938 */
6940
6941 /// @}
6942
6943
6944 /////////////////////
6945 // deserialization //
6946 /////////////////////
6947
6948 /// @name deserialization
6949 /// @{
6950
6951 /*!
6952 @brief deserialize from a compatible input
6953
6954 This function reads from a compatible input. Examples are:
6955 - an array of 1-byte values
6956 - strings with character/literal type with size of 1 byte
6957 - input streams
6958 - container with contiguous storage of 1-byte values. Compatible container
6959 types include `std::vector`, `std::string`, `std::array`,
6960 and `std::initializer_list`. Furthermore, C-style
6961 arrays can be used with `std::begin()`/`std::end()`. User-defined
6962 containers can be used as long as they implement random-access iterators
6963 and a contiguous storage.
6964
6965 @pre Each element of the container has a size of 1 byte. Violating this
6966 precondition yields undefined behavior. **This precondition is enforced
6967 with a static assertion.**
6968
6969 @pre The container storage is contiguous. Violating this precondition
6970 yields undefined behavior. **This precondition is enforced with an
6971 assertion.**
6972 @pre Each element of the container has a size of 1 byte. Violating this
6973 precondition yields undefined behavior. **This precondition is enforced
6974 with a static assertion.**
6975
6976 @warning There is no way to enforce all preconditions at compile-time. If
6977 the function is called with a noncompliant container and with
6978 assertions switched off, the behavior is undefined and will most
6979 likely yield segmentation violation.
6980
6981 @param[in] i input to read from
6982 @param[in] cb a parser callback function of type @ref parser_callback_t
6983 which is used to control the deserialization by filtering unwanted values
6984 (optional)
6985
6986 @return result of the deserialization
6987
6988 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
6989 of input; expected string literal""`
6990 @throw parse_error.102 if to_unicode fails or surrogate error
6991 @throw parse_error.103 if to_unicode fails
6992
6993 @complexity Linear in the length of the input. The parser is a predictive
6994 LL(1) parser. The complexity can be higher if the parser callback function
6995 @a cb has a super-linear complexity.
6996
6997 @note A UTF-8 byte order mark is silently ignored.
6998
6999 @liveexample{The example below demonstrates the `parse()` function reading
7000 from an array.,parse__array__parser_callback_t}
7001
7002 @liveexample{The example below demonstrates the `parse()` function with
7003 and without callback function.,parse__string__parser_callback_t}
7004
7005 @liveexample{The example below demonstrates the `parse()` function with
7006 and without callback function.,parse__istream__parser_callback_t}
7007
7008 @liveexample{The example below demonstrates the `parse()` function reading
7009 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
7010
7011 @since version 2.0.3 (contiguous containers)
7012 */
7014 const parser_callback_t cb = nullptr,
7015 const bool allow_exceptions = true);
7016
7017 static json parse(std::span<const uint8_t> arr,
7018 const parser_callback_t cb = nullptr,
7019 const bool allow_exceptions = true);
7020
7021 /*!
7022 @copydoc json parse(raw_istream&, const parser_callback_t)
7023 */
7025 const parser_callback_t cb = nullptr,
7026 const bool allow_exceptions = true);
7027
7028 static bool accept(std::string_view s);
7029
7030 static bool accept(std::span<const uint8_t> arr);
7031
7032 static bool accept(raw_istream& i);
7033
7034 /*!
7035 @brief deserialize from stream
7036
7037 Deserializes an input stream to a JSON value.
7038
7039 @param[in,out] i input stream to read a serialized JSON value from
7040 @param[in,out] j JSON value to write the deserialized input to
7041
7042 @throw parse_error.101 in case of an unexpected token
7043 @throw parse_error.102 if to_unicode fails or surrogate error
7044 @throw parse_error.103 if to_unicode fails
7045
7046 @complexity Linear in the length of the input. The parser is a predictive
7047 LL(1) parser.
7048
7049 @note A UTF-8 byte order mark is silently ignored.
7050
7051 @liveexample{The example below shows how a JSON value is constructed by
7052 reading a serialization from a stream.,operator_deserialize}
7053
7054 @sa parse(std::istream&, const parser_callback_t) for a variant with a
7055 parser callback function to filter values while parsing
7056
7057 @since version 1.0.0
7058 */
7060
7061 /// @}
7062
7063 ///////////////////////////
7064 // convenience functions //
7065 ///////////////////////////
7066
7067 /*!
7068 @brief return the type as string
7069
7070 Returns the type name as string to be used in error messages - usually to
7071 indicate that a function was called on a wrong JSON type.
7072
7073 @return a string representation of a the @a m_type member:
7074 Value type | return value
7075 ----------- | -------------
7076 null | `"null"`
7077 boolean | `"boolean"`
7078 string | `"string"`
7079 number | `"number"` (for all number types)
7080 object | `"object"`
7081 array | `"array"`
7082 discarded | `"discarded"`
7083
7084 @exceptionsafety No-throw guarantee: this function never throws exceptions.
7085
7086 @complexity Constant.
7087
7088 @liveexample{The following code exemplifies `type_name()` for all JSON
7089 types.,type_name}
7090
7091 @sa @ref type() -- return the type of the JSON value
7092 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
7093
7094 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
7095 since 3.0.0
7096 */
7097 const char* type_name() const noexcept;
7098
7099
7100 private:
7101 //////////////////////
7102 // member variables //
7103 //////////////////////
7104
7105 /// the type of the current element
7106 value_t m_type = value_t::null;
7107
7108 /// the value of the current element
7109 json_value m_value = {};
7110
7111 //////////////////////////////////////////
7112 // binary serialization/deserialization //
7113 //////////////////////////////////////////
7114
7115 /// @name binary serialization/deserialization support
7116 /// @{
7117
7118 public:
7119 /*!
7120 @brief create a CBOR serialization of a given JSON value
7121
7122 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
7123 Binary Object Representation) serialization format. CBOR is a binary
7124 serialization format which aims to be more compact than JSON itself, yet
7125 more efficient to parse.
7126
7127 The library uses the following mapping from JSON values types to
7128 CBOR types according to the CBOR specification (RFC 7049):
7129
7130 JSON value type | value/range | CBOR type | first byte
7131 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
7132 null | `null` | Null | 0xF6
7133 boolean | `true` | True | 0xF5
7134 boolean | `false` | False | 0xF4
7135 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
7136 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
7137 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
7138 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
7139 number_integer | -24..-1 | Negative integer | 0x20..0x37
7140 number_integer | 0..23 | Integer | 0x00..0x17
7141 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
7142 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
7143 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
7144 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
7145 number_unsigned | 0..23 | Integer | 0x00..0x17
7146 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
7147 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
7148 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
7149 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
7150 number_float | *any value* | Double-Precision Float | 0xFB
7151 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
7152 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
7153 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
7154 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
7155 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
7156 array | *size*: 0..23 | array | 0x80..0x97
7157 array | *size*: 23..255 | array (1 byte follow) | 0x98
7158 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
7159 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
7160 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
7161 object | *size*: 0..23 | map | 0xA0..0xB7
7162 object | *size*: 23..255 | map (1 byte follow) | 0xB8
7163 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
7164 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
7165 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
7166
7167 @note The mapping is **complete** in the sense that any JSON value type
7168 can be converted to a CBOR value.
7169
7170 @note If NaN or Infinity are stored inside a JSON number, they are
7171 serialized properly. This behavior differs from the @ref dump()
7172 function which serializes NaN or Infinity to `null`.
7173
7174 @note The following CBOR types are not used in the conversion:
7175 - byte strings (0x40..0x5F)
7176 - UTF-8 strings terminated by "break" (0x7F)
7177 - arrays terminated by "break" (0x9F)
7178 - maps terminated by "break" (0xBF)
7179 - date/time (0xC0..0xC1)
7180 - bignum (0xC2..0xC3)
7181 - decimal fraction (0xC4)
7182 - bigfloat (0xC5)
7183 - tagged items (0xC6..0xD4, 0xD8..0xDB)
7184 - expected conversions (0xD5..0xD7)
7185 - simple values (0xE0..0xF3, 0xF8)
7186 - undefined (0xF7)
7187 - half and single-precision floats (0xF9-0xFA)
7188 - break (0xFF)
7189
7190 @param[in] j JSON value to serialize
7191 @return MessagePack serialization as byte vector
7192
7193 @complexity Linear in the size of the JSON value @a j.
7194
7195 @liveexample{The example shows the serialization of a JSON value to a byte
7196 vector in CBOR format.,to_cbor}
7197
7198 @sa http://cbor.io
7199 @sa @ref from_cbor(raw_istream&, const bool strict) for the
7200 analogous deserialization
7201 @sa @ref to_msgpack(const json&) for the related MessagePack format
7202 @sa @ref to_ubjson(const json&, const bool, const bool) for the
7203 related UBJSON format
7204
7205 @since version 2.0.9
7206 */
7207 static std::vector<uint8_t> to_cbor(const json& j);
7208 static std::span<uint8_t> to_cbor(const json& j, std::vector<uint8_t>& buf);
7209 static std::span<uint8_t> to_cbor(const json& j, SmallVectorImpl<uint8_t>& buf);
7210 static void to_cbor(raw_ostream& os, const json& j);
7211
7212 /*!
7213 @brief create a MessagePack serialization of a given JSON value
7214
7215 Serializes a given JSON value @a j to a byte vector using the MessagePack
7216 serialization format. MessagePack is a binary serialization format which
7217 aims to be more compact than JSON itself, yet more efficient to parse.
7218
7219 The library uses the following mapping from JSON values types to
7220 MessagePack types according to the MessagePack specification:
7221
7222 JSON value type | value/range | MessagePack type | first byte
7223 --------------- | --------------------------------- | ---------------- | ----------
7224 null | `null` | nil | 0xC0
7225 boolean | `true` | true | 0xC3
7226 boolean | `false` | false | 0xC2
7227 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
7228 number_integer | -2147483648..-32769 | int32 | 0xD2
7229 number_integer | -32768..-129 | int16 | 0xD1
7230 number_integer | -128..-33 | int8 | 0xD0
7231 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
7232 number_integer | 0..127 | positive fixint | 0x00..0x7F
7233 number_integer | 128..255 | uint 8 | 0xCC
7234 number_integer | 256..65535 | uint 16 | 0xCD
7235 number_integer | 65536..4294967295 | uint 32 | 0xCE
7236 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
7237 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
7238 number_unsigned | 128..255 | uint 8 | 0xCC
7239 number_unsigned | 256..65535 | uint 16 | 0xCD
7240 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
7241 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
7242 number_float | *any value* | float 64 | 0xCB
7243 string | *length*: 0..31 | fixstr | 0xA0..0xBF
7244 string | *length*: 32..255 | str 8 | 0xD9
7245 string | *length*: 256..65535 | str 16 | 0xDA
7246 string | *length*: 65536..4294967295 | str 32 | 0xDB
7247 array | *size*: 0..15 | fixarray | 0x90..0x9F
7248 array | *size*: 16..65535 | array 16 | 0xDC
7249 array | *size*: 65536..4294967295 | array 32 | 0xDD
7250 object | *size*: 0..15 | fix map | 0x80..0x8F
7251 object | *size*: 16..65535 | map 16 | 0xDE
7252 object | *size*: 65536..4294967295 | map 32 | 0xDF
7253
7254 @note The mapping is **complete** in the sense that any JSON value type
7255 can be converted to a MessagePack value.
7256
7257 @note The following values can **not** be converted to a MessagePack value:
7258 - strings with more than 4294967295 bytes
7259 - arrays with more than 4294967295 elements
7260 - objects with more than 4294967295 elements
7261
7262 @note The following MessagePack types are not used in the conversion:
7263 - bin 8 - bin 32 (0xC4..0xC6)
7264 - ext 8 - ext 32 (0xC7..0xC9)
7265 - float 32 (0xCA)
7266 - fixext 1 - fixext 16 (0xD4..0xD8)
7267
7268 @note Any MessagePack output created @ref to_msgpack can be successfully
7269 parsed by @ref from_msgpack.
7270
7271 @note If NaN or Infinity are stored inside a JSON number, they are
7272 serialized properly. This behavior differs from the @ref dump()
7273 function which serializes NaN or Infinity to `null`.
7274
7275 @param[in] j JSON value to serialize
7276 @return MessagePack serialization as byte vector
7277
7278 @complexity Linear in the size of the JSON value @a j.
7279
7280 @liveexample{The example shows the serialization of a JSON value to a byte
7281 vector in MessagePack format.,to_msgpack}
7282
7283 @sa http://msgpack.org
7284 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
7285 analogous deserialization
7286 @sa @ref to_cbor(const json& for the related CBOR format
7287 @sa @ref to_ubjson(const json&, const bool, const bool) for the
7288 related UBJSON format
7289
7290 @since version 2.0.9
7291 */
7292 static std::vector<uint8_t> to_msgpack(const json& j);
7293 static std::span<uint8_t> to_msgpack(const json& j, std::vector<uint8_t>& buf);
7294 static std::span<uint8_t> to_msgpack(const json& j, SmallVectorImpl<uint8_t>& buf);
7295 static void to_msgpack(raw_ostream& os, const json& j);
7296
7297 /*!
7298 @brief create a UBJSON serialization of a given JSON value
7299
7300 Serializes a given JSON value @a j to a byte vector using the UBJSON
7301 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
7302 than JSON itself, yet more efficient to parse.
7303
7304 The library uses the following mapping from JSON values types to
7305 UBJSON types according to the UBJSON specification:
7306
7307 JSON value type | value/range | UBJSON type | marker
7308 --------------- | --------------------------------- | ----------- | ------
7309 null | `null` | null | `Z`
7310 boolean | `true` | true | `T`
7311 boolean | `false` | false | `F`
7312 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
7313 number_integer | -2147483648..-32769 | int32 | `l`
7314 number_integer | -32768..-129 | int16 | `I`
7315 number_integer | -128..127 | int8 | `i`
7316 number_integer | 128..255 | uint8 | `U`
7317 number_integer | 256..32767 | int16 | `I`
7318 number_integer | 32768..2147483647 | int32 | `l`
7319 number_integer | 2147483648..9223372036854775807 | int64 | `L`
7320 number_unsigned | 0..127 | int8 | `i`
7321 number_unsigned | 128..255 | uint8 | `U`
7322 number_unsigned | 256..32767 | int16 | `I`
7323 number_unsigned | 32768..2147483647 | int32 | `l`
7324 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
7325 number_float | *any value* | float64 | `D`
7326 string | *with shortest length indicator* | string | `S`
7327 array | *see notes on optimized format* | array | `[`
7328 object | *see notes on optimized format* | map | `{`
7329
7330 @note The mapping is **complete** in the sense that any JSON value type
7331 can be converted to a UBJSON value.
7332
7333 @note The following values can **not** be converted to a UBJSON value:
7334 - strings with more than 9223372036854775807 bytes (theoretical)
7335 - unsigned integer numbers above 9223372036854775807
7336
7337 @note The following markers are not used in the conversion:
7338 - `Z`: no-op values are not created.
7339 - `C`: single-byte strings are serialized with `S` markers.
7340
7341 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
7342 by @ref from_ubjson.
7343
7344 @note If NaN or Infinity are stored inside a JSON number, they are
7345 serialized properly. This behavior differs from the @ref dump()
7346 function which serializes NaN or Infinity to `null`.
7347
7348 @note The optimized formats for containers are supported: Parameter
7349 @a use_size adds size information to the beginning of a container and
7350 removes the closing marker. Parameter @a use_type further checks
7351 whether all elements of a container have the same type and adds the
7352 type marker to the beginning of the container. The @a use_type
7353 parameter must only be used together with @a use_size = true. Note
7354 that @a use_size = true alone may result in larger representations -
7355 the benefit of this parameter is that the receiving side is
7356 immediately informed on the number of elements of the container.
7357
7358 @param[in] j JSON value to serialize
7359 @param[in] use_size whether to add size annotations to container types
7360 @param[in] use_type whether to add type annotations to container types
7361 (must be combined with @a use_size = true)
7362 @return UBJSON serialization as byte vector
7363
7364 @complexity Linear in the size of the JSON value @a j.
7365
7366 @liveexample{The example shows the serialization of a JSON value to a byte
7367 vector in UBJSON format.,to_ubjson}
7368
7369 @sa http://ubjson.org
7370 @sa @ref from_ubjson(raw_istream&, const bool strict) for the
7371 analogous deserialization
7372 @sa @ref to_cbor(const json& for the related CBOR format
7373 @sa @ref to_msgpack(const json&) for the related MessagePack format
7374
7375 @since version 3.1.0
7376 */
7377 static std::vector<uint8_t> to_ubjson(const json& j,
7378 const bool use_size = false,
7379 const bool use_type = false);
7380 static std::span<uint8_t> to_ubjson(const json& j, std::vector<uint8_t>& buf,
7381 const bool use_size = false, const bool use_type = false);
7382 static std::span<uint8_t> to_ubjson(const json& j, SmallVectorImpl<uint8_t>& buf,
7383 const bool use_size = false, const bool use_type = false);
7384 static void to_ubjson(raw_ostream& os, const json& j,
7385 const bool use_size = false, const bool use_type = false);
7386
7387 /*!
7388 @brief create a JSON value from an input in CBOR format
7389
7390 Deserializes a given input @a i to a JSON value using the CBOR (Concise
7391 Binary Object Representation) serialization format.
7392
7393 The library maps CBOR types to JSON value types as follows:
7394
7395 CBOR type | JSON value type | first byte
7396 ---------------------- | --------------- | ----------
7397 Integer | number_unsigned | 0x00..0x17
7398 Unsigned integer | number_unsigned | 0x18
7399 Unsigned integer | number_unsigned | 0x19
7400 Unsigned integer | number_unsigned | 0x1A
7401 Unsigned integer | number_unsigned | 0x1B
7402 Negative integer | number_integer | 0x20..0x37
7403 Negative integer | number_integer | 0x38
7404 Negative integer | number_integer | 0x39
7405 Negative integer | number_integer | 0x3A
7406 Negative integer | number_integer | 0x3B
7407 Negative integer | number_integer | 0x40..0x57
7408 UTF-8 string | string | 0x60..0x77
7409 UTF-8 string | string | 0x78
7410 UTF-8 string | string | 0x79
7411 UTF-8 string | string | 0x7A
7412 UTF-8 string | string | 0x7B
7413 UTF-8 string | string | 0x7F
7414 array | array | 0x80..0x97
7415 array | array | 0x98
7416 array | array | 0x99
7417 array | array | 0x9A
7418 array | array | 0x9B
7419 array | array | 0x9F
7420 map | object | 0xA0..0xB7
7421 map | object | 0xB8
7422 map | object | 0xB9
7423 map | object | 0xBA
7424 map | object | 0xBB
7425 map | object | 0xBF
7426 False | `false` | 0xF4
7427 True | `true` | 0xF5
7428 Nill | `null` | 0xF6
7429 Half-Precision Float | number_float | 0xF9
7430 Single-Precision Float | number_float | 0xFA
7431 Double-Precision Float | number_float | 0xFB
7432
7433 @warning The mapping is **incomplete** in the sense that not all CBOR
7434 types can be converted to a JSON value. The following CBOR types
7435 are not supported and will yield parse errors (parse_error.112):
7436 - byte strings (0x40..0x5F)
7437 - date/time (0xC0..0xC1)
7438 - bignum (0xC2..0xC3)
7439 - decimal fraction (0xC4)
7440 - bigfloat (0xC5)
7441 - tagged items (0xC6..0xD4, 0xD8..0xDB)
7442 - expected conversions (0xD5..0xD7)
7443 - simple values (0xE0..0xF3, 0xF8)
7444 - undefined (0xF7)
7445
7446 @warning CBOR allows map keys of any type, whereas JSON only allows
7447 strings as keys in object values. Therefore, CBOR maps with keys
7448 other than UTF-8 strings are rejected (parse_error.113).
7449
7450 @note Any CBOR output created @ref to_cbor can be successfully parsed by
7451 @ref from_cbor.
7452
7453 @param[in] i an input in CBOR format convertible to an input adapter
7454 @param[in] strict whether to expect the input to be consumed until EOF
7455 (true by default)
7456 @return deserialized JSON value
7457
7458 @throw parse_error.110 if the given input ends prematurely or the end of
7459 file was not reached when @a strict was set to true
7460 @throw parse_error.112 if unsupported features from CBOR were
7461 used in the given input @a v or if the input is not valid CBOR
7462 @throw parse_error.113 if a string was expected as map key, but not found
7463
7464 @complexity Linear in the size of the input @a i.
7465
7466 @liveexample{The example shows the deserialization of a byte vector in CBOR
7467 format to a JSON value.,from_cbor}
7468
7469 @sa http://cbor.io
7470 @sa @ref to_cbor(const json&) for the analogous serialization
7471 @sa @ref from_msgpack(raw_istream&, const bool) for the
7472 related MessagePack format
7473 @sa @ref from_ubjson(raw_istream&, const bool) for the related
7474 UBJSON format
7475
7476 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
7477 consume input adapters, removed start_index parameter, and added
7478 @a strict parameter since 3.0.0
7479 */
7481 const bool strict = true);
7482
7483 /*!
7484 @copydoc from_cbor(raw_istream&, const bool)
7485 */
7486 static json from_cbor(std::span<const uint8_t> arr, const bool strict = true);
7487
7488 /*!
7489 @brief create a JSON value from an input in MessagePack format
7490
7491 Deserializes a given input @a i to a JSON value using the MessagePack
7492 serialization format.
7493
7494 The library maps MessagePack types to JSON value types as follows:
7495
7496 MessagePack type | JSON value type | first byte
7497 ---------------- | --------------- | ----------
7498 positive fixint | number_unsigned | 0x00..0x7F
7499 fixmap | object | 0x80..0x8F
7500 fixarray | array | 0x90..0x9F
7501 fixstr | string | 0xA0..0xBF
7502 nil | `null` | 0xC0
7503 false | `false` | 0xC2
7504 true | `true` | 0xC3
7505 float 32 | number_float | 0xCA
7506 float 64 | number_float | 0xCB
7507 uint 8 | number_unsigned | 0xCC
7508 uint 16 | number_unsigned | 0xCD
7509 uint 32 | number_unsigned | 0xCE
7510 uint 64 | number_unsigned | 0xCF
7511 int 8 | number_integer | 0xD0
7512 int 16 | number_integer | 0xD1
7513 int 32 | number_integer | 0xD2
7514 int 64 | number_integer | 0xD3
7515 str 8 | string | 0xD9
7516 str 16 | string | 0xDA
7517 str 32 | string | 0xDB
7518 array 16 | array | 0xDC
7519 array 32 | array | 0xDD
7520 map 16 | object | 0xDE
7521 map 32 | object | 0xDF
7522 negative fixint | number_integer | 0xE0-0xFF
7523
7524 @warning The mapping is **incomplete** in the sense that not all
7525 MessagePack types can be converted to a JSON value. The following
7526 MessagePack types are not supported and will yield parse errors:
7527 - bin 8 - bin 32 (0xC4..0xC6)
7528 - ext 8 - ext 32 (0xC7..0xC9)
7529 - fixext 1 - fixext 16 (0xD4..0xD8)
7530
7531 @note Any MessagePack output created @ref to_msgpack can be successfully
7532 parsed by @ref from_msgpack.
7533
7534 @param[in] i an input in MessagePack format convertible to an input
7535 adapter
7536 @param[in] strict whether to expect the input to be consumed until EOF
7537 (true by default)
7538
7539 @throw parse_error.110 if the given input ends prematurely or the end of
7540 file was not reached when @a strict was set to true
7541 @throw parse_error.112 if unsupported features from MessagePack were
7542 used in the given input @a i or if the input is not valid MessagePack
7543 @throw parse_error.113 if a string was expected as map key, but not found
7544
7545 @complexity Linear in the size of the input @a i.
7546
7547 @liveexample{The example shows the deserialization of a byte vector in
7548 MessagePack format to a JSON value.,from_msgpack}
7549
7550 @sa http://msgpack.org
7551 @sa @ref to_msgpack(const json&) for the analogous serialization
7552 @sa @ref from_cbor(raw_istream&, const bool) for the related CBOR
7553 format
7554 @sa @ref from_ubjson(raw_istream&, const bool) for the related
7555 UBJSON format
7556
7557 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
7558 consume input adapters, removed start_index parameter, and added
7559 @a strict parameter since 3.0.0
7560 */
7562 const bool strict = true);
7563
7564 /*!
7565 @copydoc from_msgpack(raw_istream&, const bool)
7566 */
7567 static json from_msgpack(std::span<const uint8_t> arr, const bool strict = true);
7568
7569 /*!
7570 @brief create a JSON value from an input in UBJSON format
7571
7572 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
7573 Binary JSON) serialization format.
7574
7575 The library maps UBJSON types to JSON value types as follows:
7576
7577 UBJSON type | JSON value type | marker
7578 ----------- | --------------------------------------- | ------
7579 no-op | *no value, next value is read* | `N`
7580 null | `null` | `Z`
7581 false | `false` | `F`
7582 true | `true` | `T`
7583 float32 | number_float | `d`
7584 float64 | number_float | `D`
7585 uint8 | number_unsigned | `U`
7586 int8 | number_integer | `i`
7587 int16 | number_integer | `I`
7588 int32 | number_integer | `l`
7589 int64 | number_integer | `L`
7590 string | string | `S`
7591 char | string | `C`
7592 array | array (optimized values are supported) | `[`
7593 object | object (optimized values are supported) | `{`
7594
7595 @note The mapping is **complete** in the sense that any UBJSON value can
7596 be converted to a JSON value.
7597
7598 @param[in] i an input in UBJSON format convertible to an input adapter
7599 @param[in] strict whether to expect the input to be consumed until EOF
7600 (true by default)
7601
7602 @throw parse_error.110 if the given input ends prematurely or the end of
7603 file was not reached when @a strict was set to true
7604 @throw parse_error.112 if a parse error occurs
7605 @throw parse_error.113 if a string could not be parsed successfully
7606
7607 @complexity Linear in the size of the input @a i.
7608
7609 @liveexample{The example shows the deserialization of a byte vector in
7610 UBJSON format to a JSON value.,from_ubjson}
7611
7612 @sa http://ubjson.org
7613 @sa @ref to_ubjson(const json&, const bool, const bool) for the
7614 analogous serialization
7615 @sa @ref from_cbor(raw_istream&, const bool) for the related CBOR
7616 format
7617 @sa @ref from_msgpack(raw_istream&, const bool) for the related
7618 MessagePack format
7619
7620 @since version 3.1.0
7621 */
7623 const bool strict = true);
7624
7625 static json from_ubjson(std::span<const uint8_t> arr, const bool strict = true);
7626
7627 /// @}
7628
7629 //////////////////////////
7630 // JSON Pointer support //
7631 //////////////////////////
7632
7633 /// @name JSON Pointer functions
7634 /// @{
7635
7636 /*!
7637 @brief access specified element via JSON Pointer
7638
7639 Uses a JSON pointer to retrieve a reference to the respective JSON value.
7640 No bound checking is performed. Similar to @ref operator[](const typename
7641 object_t::key_type&), `null` values are created in arrays and objects if
7642 necessary.
7643
7644 In particular:
7645 - If the JSON pointer points to an object key that does not exist, it
7646 is created an filled with a `null` value before a reference to it
7647 is returned.
7648 - If the JSON pointer points to an array index that does not exist, it
7649 is created an filled with a `null` value before a reference to it
7650 is returned. All indices between the current maximum and the given
7651 index are also filled with `null`.
7652 - The special value `-` is treated as a synonym for the index past the
7653 end.
7654
7655 @param[in] ptr a JSON pointer
7656
7657 @return reference to the element pointed to by @a ptr
7658
7659 @complexity Constant.
7660
7661 @throw parse_error.106 if an array index begins with '0'
7662 @throw parse_error.109 if an array index was not a number
7663 @throw out_of_range.404 if the JSON pointer can not be resolved
7664
7665 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
7666
7667 @since version 2.0.0
7668 */
7670 {
7671 return ptr.get_unchecked(this);
7672 }
7673
7674 /*!
7675 @brief access specified element via JSON Pointer
7676
7677 Uses a JSON pointer to retrieve a reference to the respective JSON value.
7678 No bound checking is performed. The function does not change the JSON
7679 value; no `null` values are created. In particular, the the special value
7680 `-` yields an exception.
7681
7682 @param[in] ptr JSON pointer to the desired element
7683
7684 @return const reference to the element pointed to by @a ptr
7685
7686 @complexity Constant.
7687
7688 @throw parse_error.106 if an array index begins with '0'
7689 @throw parse_error.109 if an array index was not a number
7690 @throw out_of_range.402 if the array index '-' is used
7691 @throw out_of_range.404 if the JSON pointer can not be resolved
7692
7693 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
7694
7695 @since version 2.0.0
7696 */
7698 {
7699 return ptr.get_unchecked(this);
7700 }
7701
7702 /*!
7703 @brief access specified element via JSON Pointer
7704
7705 Returns a reference to the element at with specified JSON pointer @a ptr,
7706 with bounds checking.
7707
7708 @param[in] ptr JSON pointer to the desired element
7709
7710 @return reference to the element pointed to by @a ptr
7711
7712 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
7713 begins with '0'. See example below.
7714
7715 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
7716 is not a number. See example below.
7717
7718 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
7719 is out of range. See example below.
7720
7721 @throw out_of_range.402 if the array index '-' is used in the passed JSON
7722 pointer @a ptr. As `at` provides checked access (and no elements are
7723 implicitly inserted), the index '-' is always invalid. See example below.
7724
7725 @throw out_of_range.403 if the JSON pointer describes a key of an object
7726 which cannot be found. See example below.
7727
7728 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
7729 See example below.
7730
7731 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
7732 changes in the JSON value.
7733
7734 @complexity Constant.
7735
7736 @since version 2.0.0
7737
7738 @liveexample{The behavior is shown in the example.,at_json_pointer}
7739 */
7741 {
7742 return ptr.get_checked(this);
7743 }
7744
7745 /*!
7746 @brief access specified element via JSON Pointer
7747
7748 Returns a const reference to the element at with specified JSON pointer @a
7749 ptr, with bounds checking.
7750
7751 @param[in] ptr JSON pointer to the desired element
7752
7753 @return reference to the element pointed to by @a ptr
7754
7755 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
7756 begins with '0'. See example below.
7757
7758 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
7759 is not a number. See example below.
7760
7761 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
7762 is out of range. See example below.
7763
7764 @throw out_of_range.402 if the array index '-' is used in the passed JSON
7765 pointer @a ptr. As `at` provides checked access (and no elements are
7766 implicitly inserted), the index '-' is always invalid. See example below.
7767
7768 @throw out_of_range.403 if the JSON pointer describes a key of an object
7769 which cannot be found. See example below.
7770
7771 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
7772 See example below.
7773
7774 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
7775 changes in the JSON value.
7776
7777 @complexity Constant.
7778
7779 @since version 2.0.0
7780
7781 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
7782 */
7784 {
7785 return ptr.get_checked(this);
7786 }
7787
7788 /*!
7789 @brief return flattened JSON value
7790
7791 The function creates a JSON object whose keys are JSON pointers (see [RFC
7792 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
7793 primitive. The original JSON value can be restored using the @ref
7794 unflatten() function.
7795
7796 @return an object that maps JSON pointers to primitive values
7797
7798 @note Empty objects and arrays are flattened to `null` and will not be
7799 reconstructed correctly by the @ref unflatten() function.
7800
7801 @complexity Linear in the size the JSON value.
7802
7803 @liveexample{The following code shows how a JSON object is flattened to an
7804 object whose keys consist of JSON pointers.,flatten}
7805
7806 @sa @ref unflatten() for the reverse function
7807
7808 @since version 2.0.0
7809 */
7811 {
7813 json_pointer::flatten("", *this, result);
7814 return result;
7815 }
7816
7817 /*!
7818 @brief unflatten a previously flattened JSON value
7819
7820 The function restores the arbitrary nesting of a JSON value that has been
7821 flattened before using the @ref flatten() function. The JSON value must
7822 meet certain constraints:
7823 1. The value must be an object.
7824 2. The keys must be JSON pointers (see
7825 [RFC 6901](https://tools.ietf.org/html/rfc6901))
7826 3. The mapped values must be primitive JSON types.
7827
7828 @return the original JSON from a flattened version
7829
7830 @note Empty objects and arrays are flattened by @ref flatten() to `null`
7831 values and can not unflattened to their original type. Apart from
7832 this example, for a JSON value `j`, the following is always true:
7833 `j == j.flatten().unflatten()`.
7834
7835 @complexity Linear in the size the JSON value.
7836
7837 @throw type_error.314 if value is not an object
7838 @throw type_error.315 if object values are not primitive
7839
7840 @liveexample{The following code shows how a flattened JSON object is
7841 unflattened into the original nested JSON object.,unflatten}
7842
7843 @sa @ref flatten() for the reverse function
7844
7845 @since version 2.0.0
7846 */
7848 {
7849 return json_pointer::unflatten(*this);
7850 }
7851
7852 /// @}
7853
7854 //////////////////////////
7855 // JSON Patch functions //
7856 //////////////////////////
7857
7858 /// @name JSON Patch functions
7859 /// @{
7860
7861 /*!
7862 @brief applies a JSON patch
7863
7864 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
7865 expressing a sequence of operations to apply to a JSON) document. With
7866 this function, a JSON Patch is applied to the current JSON value by
7867 executing all operations from the patch.
7868
7869 @param[in] json_patch JSON patch document
7870 @return patched document
7871
7872 @note The application of a patch is atomic: Either all operations succeed
7873 and the patched document is returned or an exception is thrown. In
7874 any case, the original value is not changed: the patch is applied
7875 to a copy of the value.
7876
7877 @throw parse_error.104 if the JSON patch does not consist of an array of
7878 objects
7879
7880 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
7881 attributes are missing); example: `"operation add must have member path"`
7882
7883 @throw out_of_range.401 if an array index is out of range.
7884
7885 @throw out_of_range.403 if a JSON pointer inside the patch could not be
7886 resolved successfully in the current JSON value; example: `"key baz not
7887 found"`
7888
7889 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
7890 "move")
7891
7892 @throw other_error.501 if "test" operation was unsuccessful
7893
7894 @complexity Linear in the size of the JSON value and the length of the
7895 JSON patch. As usually only a fraction of the JSON value is affected by
7896 the patch, the complexity can usually be neglected.
7897
7898 @liveexample{The following code shows how a JSON patch is applied to a
7899 value.,patch}
7900
7901 @sa @ref diff -- create a JSON patch by comparing two JSON values
7902
7903 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
7904 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
7905
7906 @since version 2.0.0
7907 */
7908 json patch(const json& json_patch) const;
7909
7910 /*!
7911 @brief creates a diff as a JSON patch
7912
7913 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
7914 be changed into the value @a target by calling @ref patch function.
7915
7916 @invariant For two JSON values @a source and @a target, the following code
7917 yields always `true`:
7918 @code {.cpp}
7919 source.patch(diff(source, target)) == target;
7920 @endcode
7921
7922 @note Currently, only `remove`, `add`, and `replace` operations are
7923 generated.
7924
7925 @param[in] source JSON value to compare from
7926 @param[in] target JSON value to compare against
7927 @param[in] path helper value to create JSON pointers
7928
7929 @return a JSON patch to convert the @a source to @a target
7930
7931 @complexity Linear in the lengths of @a source and @a target.
7932
7933 @liveexample{The following code shows how a JSON patch is created as a
7934 diff for two JSON values.,diff}
7935
7936 @sa @ref patch -- apply a JSON patch
7937 @sa @ref merge_patch -- apply a JSON Merge Patch
7938
7939 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
7940
7941 @since version 2.0.0
7942 */
7943 static json diff(const json& source, const json& target,
7944 const std::string& path = "");
7945
7946 /// @}
7947
7948 ////////////////////////////////
7949 // JSON Merge Patch functions //
7950 ////////////////////////////////
7951
7952 /// @name JSON Merge Patch functions
7953 /// @{
7954
7955 /*!
7956 @brief applies a JSON Merge Patch
7957
7958 The merge patch format is primarily intended for use with the HTTP PATCH
7959 method as a means of describing a set of modifications to a target
7960 resource's content. This function applies a merge patch to the current
7961 JSON value.
7962
7963 The function implements the following algorithm from Section 2 of
7964 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
7965
7966 ```
7967 define MergePatch(Target, Patch):
7968 if Patch is an Object:
7969 if Target is not an Object:
7970 Target = {} // Ignore the contents and set it to an empty Object
7971 for each Name/Value pair in Patch:
7972 if Value is null:
7973 if Name exists in Target:
7974 remove the Name/Value pair from Target
7975 else:
7976 Target[Name] = MergePatch(Target[Name], Value)
7977 return Target
7978 else:
7979 return Patch
7980 ```
7981
7982 Thereby, `Target` is the current object; that is, the patch is applied to
7983 the current value.
7984
7985 @param[in] patch the patch to apply
7986
7987 @complexity Linear in the lengths of @a patch.
7988
7989 @liveexample{The following code shows how a JSON Merge Patch is applied to
7990 a JSON document.,merge_patch}
7991
7992 @sa @ref patch -- apply a JSON patch
7993 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
7994
7995 @since version 3.0.0
7996 */
7997 void merge_patch(const json& patch);
7998
7999 /// @}
8000};
8001} // namespace wpi
8002
8003///////////////////////
8004// nonmember support //
8005///////////////////////
8006
8007// specialization of std::swap, and std::hash
8008namespace std
8009{
8010/*!
8011@brief exchanges the values of two JSON objects
8012
8013@since version 1.0.0
8014*/
8015template<>
8016inline void swap<wpi::json>(wpi::json& j1,
8017 wpi::json& j2) noexcept(
8018 is_nothrow_move_constructible<wpi::json>::value and
8019 is_nothrow_move_assignable<wpi::json>::value
8020 )
8021{
8022 j1.swap(j2);
8023}
8024
8025/// hash value for JSON objects
8026template<>
8027struct hash<wpi::json>
8028{
8029 /*!
8030 @brief return a hash value for a JSON object
8031
8032 @since version 1.0.0
8033 */
8034 std::size_t operator()(const wpi::json& j) const
8035 {
8036 // a naive hashing via the string representation
8037 const auto& h = hash<std::string>();
8038 return h(j.dump());
8039 }
8040};
8041
8042/// specialization for std::less<value_t>
8043/// @note: do not remove the space after '<',
8044/// see https://github.com/nlohmann/json/pull/679
8045template<>
8047{
8048 /*!
8049 @brief compare two value_t enum values
8050 @since version 3.0.0
8051 */
8053 wpi::detail::value_t rhs) const noexcept
8054 {
8055 return wpi::detail::operator<(lhs, rhs);
8056 }
8057};
8058
8059} // namespace std
8060
8061/*!
8062@brief user-defined string literal for JSON values
8063
8064This operator implements a user-defined string literal for JSON objects. It
8065can be used by adding `"_json"` to a string literal and returns a JSON object
8066if no parse error occurred.
8067
8068@param[in] s a string representation of a JSON object
8069@param[in] n the length of string @a s
8070@return a JSON object
8071
8072@since version 1.0.0
8073*/
8074inline wpi::json operator "" _json(const char* s, std::size_t n)
8075{
8076 return wpi::json::parse(std::string_view(s, n));
8077}
8078
8079/*!
8080@brief user-defined string literal for JSON pointer
8081
8082This operator implements a user-defined string literal for JSON Pointers. It
8083can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
8084object if no parse error occurred.
8085
8086@param[in] s a string representation of a JSON Pointer
8087@param[in] n the length of string @a s
8088@return a JSON pointer object
8089
8090@since version 2.0.0
8091*/
8092inline wpi::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
8093{
8095}
8096
8097#ifndef WPI_JSON_IMPLEMENTATION
8098
8099// restore GCC/clang diagnostic settings
8100#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
8101 #pragma GCC diagnostic pop
8102#endif
8103#if defined(__clang__)
8104 #pragma GCC diagnostic pop
8105#endif
8106
8107// clean up
8108#undef JSON_CATCH
8109#undef JSON_THROW
8110#undef JSON_TRY
8111#undef JSON_LIKELY
8112#undef JSON_UNLIKELY
8113#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
8114#undef NLOHMANN_BASIC_JSON_TPL
8115#undef NLOHMANN_JSON_HAS_HELPER
8116
8117#endif // WPI_JSON_IMPLEMENTATION
8118
8119#endif
EIGEN_DEVICE_FUNC const NegativeReturnType operator-() const
Definition: CommonCwiseUnaryOps.h:45
This file defines the StringMap class.
and(b) You must cause any modified files to carry prominent notices stating that You changed the files
or
Definition: ThirdPartyNotices.txt:199
you may not use this file except in compliance with the License You may obtain a copy of the License at software distributed under the License is distributed on an AS IS WITHOUT WARRANTIES OR CONDITIONS OF ANY either express or implied See the License for the specific language governing permissions and limitations under the License LLVM Exceptions to the Apache License As an exception
Definition: ThirdPartyNotices.txt:292
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation source
Definition: ThirdPartyNotices.txt:114
Definition: core.h:1240
constexpr FMT_INLINE value()
Definition: core.h:1263
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:114
This class is a wrapper around std::array that does compile time size checking.
Definition: array.h:25
general exception of the json class
Definition: json.h:412
exception(int id_, std::string_view what_arg)
const char * what() const noexcept override
returns the explanatory string
Definition: json.h:415
const int id
the id of the exception
Definition: json.h:421
exception indicating errors with iterators
Definition: json.h:541
static invalid_iterator create(int id_, std::string_view what_arg)
static invalid_iterator create(int id_, std::string_view what_arg, std::string_view type_info)
a template for a bidirectional iterator for the json class
Definition: json.h:1502
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.h:1527
std::string_view key() const
return the key of an object iterator
Definition: json.h:2046
iter_impl()=default
default constructor
Definition: json.h:1504
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.h:1596
reference operator[](difference_type n) const
access to successor
Definition: json.h:2015
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.h:1896
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.h:1676
iter_impl & operator++()
pre-increment (++it)
Definition: json.h:1758
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.h:1587
iter_impl const operator++(int)
post-increment (it++)
Definition: json.h:1747
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.h:1790
iter_impl & operator--()
pre-decrement (–it)
Definition: json.h:1801
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.h:1525
pointer operator->() const
dereference the iterator
Definition: json.h:1713
iter_impl(pointer object) noexcept
constructor for a given JSON instance
Definition: json.h:1547
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.h:1914
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.h:1536
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.h:1972
reference value() const
return the value of an iterator
Definition: json.h:2062
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.h:1983
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.h:1905
bool operator==(const iter_impl &other) const
comparison: equal
Definition: json.h:1833
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.h:1869
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.h:1994
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.h:1961
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.h:1923
std::bidirectional_iterator_tag iterator_category
The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
Definition: json.h:1522
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.h:1952
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.h:1531
bool operator!=(const iter_impl &other) const
comparison: not equal
Definition: json.h:1860
proxy class for the items() function
Definition: json.h:2076
iteration_proxy_internal begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.h:2148
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.h:2144
iteration_proxy_internal end() noexcept
return iterator end (needed for range-based for)
Definition: json.h:2154
Definition: json.h:2270
value_type const & operator*() const
Definition: json.h:2305
json_ref(Args &&... args)
Definition: json.h:2287
json_ref(std::initializer_list< json_ref > init)
Definition: json.h:2282
json_ref & operator=(const json_ref &)=delete
json_ref(value_type &&value)
Definition: json.h:2274
value_type moved_or_copied() const
Definition: json.h:2296
value_type const * operator->() const
Definition: json.h:2310
json_ref(const value_type &value)
Definition: json.h:2278
BasicJsonType value_type
Definition: json.h:2272
json_ref(const json_ref &)=delete
json_ref(json_ref &&)=default
a template for a reverse iterator class
Definition: json.h:2184
reference operator[](difference_type n) const
access to successor
Definition: json.h:2248
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.h:2206
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.h:2200
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.h:2230
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.h:2254
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.h:2188
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.h:2236
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.h:2242
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.h:2218
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.h:2193
reference value() const
return the value of an iterator
Definition: json.h:2261
std::ptrdiff_t difference_type
Definition: json.h:2186
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.h:2212
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.h:2197
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.h:2190
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.h:2224
exception indicating other library errors
Definition: json.h:665
static other_error create(int id_, std::string_view what_arg)
exception indicating access out of the defined range
Definition: json.h:632
static out_of_range create(int id_, std::string_view what_arg)
exception indicating a parse error
Definition: json.h:475
static parse_error create(int id_, std::size_t byte_, std::string_view what_arg)
create a parse error exception
const std::size_t byte
byte index of the parse error
Definition: json.h:496
Definition: json.h:1361
primitive_iterator_t & operator--() noexcept
Definition: json.h:1435
constexpr difference_type get_value() const noexcept
Definition: json.h:1371
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.h:1377
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.h:1410
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.h:1448
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.h:1395
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.h:1389
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:1405
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.h:1454
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:1400
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:1417
primitive_iterator_t const operator++(int) noexcept
Definition: json.h:1428
primitive_iterator_t const operator--(int) noexcept
Definition: json.h:1441
primitive_iterator_t & operator++() noexcept
Definition: json.h:1422
void set_end() noexcept
set iterator to a defined past the end
Definition: json.h:1383
exception indicating executing a member function with a wrong type
Definition: json.h:590
static type_error create(int id_, std::string_view what_arg)
static type_error create(int id_, std::string_view what_arg, std::string_view type_info)
Definition: json_serializer.h:45
Definition: json.h:2323
static int array_index(std::string_view s)
std::string to_string() const noexcept
return a string representation of the JSON pointer
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.h:2540
friend class JsonTest
Definition: json.h:2326
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
Definition: json.h:2546
friend class json
Definition: json.h:2325
json_pointer(std::string_view s={})
create JSON pointer
Definition: json.h:2350
a class to store JSON values
Definition: json.h:2655
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.h:4557
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.h:5841
const_reference operator[](size_type idx) const
access specified array element
std::allocator< json > allocator_type
the allocator type
Definition: json.h:2739
PointerType get() noexcept
get a pointer value (explicit)
Definition: json.h:4435
iterator insert(const_iterator pos, const json &val)
inserts element
static json from_cbor(std::span< const uint8_t > arr, const bool strict=true)
create a JSON value from an input in CBOR format
bool is_number() const noexcept
return whether value is a number
Definition: json.h:3940
void swap(object_t &other)
exchanges the values
Definition: json.h:6547
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.h:4570
std::vector< json > array_t
a type for an array
Definition: json.h:2890
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.h:6848
bool empty() const noexcept
checks whether the container is empty.
void push_back(initializer_list_t init)
add an object to an object
json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.h:3184
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
size_type size() const noexcept
returns the number of elements
const_reference operator[](T *key) const
read-only access specified object element
Definition: json.h:4939
static json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.h:3374
iterator begin() noexcept
returns an iterator to the first element
Definition: json.h:5539
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.h:7697
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.h:5549
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.h:5650
json(size_type cnt, const json &val)
construct an array with count copies of given value
reference front()
access the first element
Definition: json.h:5124
json get() const
get special-case overload
Definition: json.h:4298
ValueType get() const noexcept(noexcept(adl_serializer< ValueType, void >::from_json(std::declval< const json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.h:4348
static std::vector< uint8_t > to_cbor(const json &j)
create a CBOR serialization of a given JSON value
json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
void push_back(json &&val)
add an object to an array
bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.h:3969
reference at(std::string_view key)
access specified object element with bounds checking
reference operator[](std::string_view key)
access specified object element
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.h:5725
detail::value_t value_t
Definition: json.h:2684
friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than
Definition: json.h:6837
static bool accept(std::string_view s)
static std::span< uint8_t > to_msgpack(const json &j, std::vector< uint8_t > &buf)
iterator insert(const_iterator pos, json &&val)
inserts element
Definition: json.h:6302
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.h:5849
json(const value_t v)
create an empty value with a given type
Definition: json.h:3160
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.h:7740
friend class JsonTest
Definition: json.h:2661
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.h:5071
const_reference front() const
access the first element
Definition: json.h:5132
static std::vector< uint8_t > to_msgpack(const json &j)
create a MessagePack serialization of a given JSON value
void push_back(const std::pair< T, U > &val)
add an object to an object
Definition: json.h:6110
static json parse(std::string_view s, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
json(CompatibleType &&val) noexcept(noexcept(adl_serializer< U, void >::to_json(std::declval< json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.h:3251
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.h:5680
size_type erase(std::string_view key)
remove element from a JSON object given a key
bool is_primitive() const noexcept
return whether type is primitive
Definition: json.h:3839
value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.h:3809
void push_back(const json &val)
add an object to an array
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
void merge_patch(const json &patch)
applies a JSON Merge Patch
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.h:6780
reference back()
access the last element
Definition: json.h:5168
friend raw_ostream & operator<<(raw_ostream &o, const json &j)
serialize to stream
StringMap< json > object_t
a type for an object
Definition: json.h:2863
friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.h:6894
iterator insert(const_iterator pos, size_type cnt, const json &val)
inserts elements
std::string dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false) const
serialization
static json from_ubjson(std::span< const uint8_t > arr, const bool strict=true)
void swap(std::string &other)
exchanges the values
Definition: json.h:6580
json patch(const json &json_patch) const
applies a JSON patch
void emplace_back(Args &&... args)
add an object to an array
Definition: json.h:6200
bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.h:4025
std::initializer_list< detail::json_ref< json > > initializer_list_t
helper type for initializer lists of json values
Definition: json.h:2690
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.h:6883
const_reference at(size_type idx) const
access specified array element with bounds checking
PointerType get_ptr() noexcept
get a pointer value (implicit)
Definition: json.h:4480
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.h:6684
static std::span< uint8_t > to_cbor(const json &j, std::vector< uint8_t > &buf)
bool is_structured() const noexcept
return whether type is structured
Definition: json.h:3866
const char * type_name() const noexcept
return the type as string
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.h:6872
std::less<> object_comparator_t
Definition: json.h:2806
bool is_discarded() const noexcept
return whether value is discarded
Definition: json.h:4118
friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than
Definition: json.h:6745
static json diff(const json &source, const json &target, const std::string &path="")
creates a diff as a JSON patch
static std::vector< uint8_t > to_ubjson(const json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
reference operator+=(const json &val)
add an object to an array
Definition: json.h:6083
friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.h:6791
static std::span< uint8_t > to_ubjson(const json &j, SmallVectorImpl< uint8_t > &buf, const bool use_size=false, const bool use_type=false)
static std::span< uint8_t > to_ubjson(const json &j, std::vector< uint8_t > &buf, const bool use_size=false, const bool use_type=false)
void clear() noexcept
clears the contents
reference operator+=(const std::pair< T, U > &val)
add an object to an object
Definition: json.h:6135
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.h:5620
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.h:5610
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.h:6826
void swap(array_t &other)
exchanges the values
Definition: json.h:6514
void erase(IteratorType pos)
remove element given an iterator
Definition: json.h:5233
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.h:5783
size_type count(std::string_view key) const
returns the number of occurrences of a key in a JSON object
parse_event_t
parser event types
Definition: json.h:3054
reference & operator=(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.h:3685
static bool accept(raw_istream &i)
json unflatten() const
unflatten a previously flattened JSON value
Definition: json.h:7847
static void to_cbor(raw_ostream &os, const json &j)
json(json &&other) noexcept
move constructor
Definition: json.h:3648
reference at(size_type idx)
access specified array element with bounds checking
static void to_msgpack(raw_ostream &os, const json &j)
const_reference back() const
access the last element
Definition: json.h:5178
json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.h:3504
reference operator[](T *key)
access specified object element
Definition: json.h:4889
friend raw_istream & operator>>(raw_istream &i, json &j)
deserialize from stream
bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.h:3910
const_iterator find(std::string_view key) const
find an element in a JSON object
void insert(const_iterator first, const_iterator last)
inserts elements
static json parse(std::span< const uint8_t > arr, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
void erase(const size_type idx)
remove element from a JSON array given an index
std::size_t size_type
a type to represent container sizes
Definition: json.h:2736
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
size_type max_size() const noexcept
returns the maximum possible number of elements
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.h:2761
friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.h:6706
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.h:7783
std::string value(std::string_view key, const char *default_value) const
overload for a default value of type const char*
Definition: json.h:5023
static std::span< uint8_t > to_msgpack(const json &j, SmallVectorImpl< uint8_t > &buf)
json_reverse_iterator< typename json::iterator > reverse_iterator
a reverse iterator for a json container
Definition: json.h:2751
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.h:7669
iterator find(std::string_view key)
find an element in a JSON object
static std::span< uint8_t > to_cbor(const json &j, SmallVectorImpl< uint8_t > &buf)
static json from_msgpack(std::span< const uint8_t > arr, const bool strict=true)
create a JSON value from an input in MessagePack format
friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
comparison: equal
Definition: json.h:6650
const_reference at(std::string_view key) const
access specified object element with bounds checking
friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.h:6756
~json() noexcept
destructor
Definition: json.h:3718
static json from_msgpack(raw_istream &is, const bool strict=true)
create a JSON value from an input in MessagePack format
const PointerType get_ptr() const noexcept
get a pointer value (implicit)
Definition: json.h:4508
static json from_ubjson(raw_istream &is, const bool strict=true)
create a JSON value from an input in UBJSON format
json flatten() const
return flattened JSON value
Definition: json.h:7810
bool is_array() const noexcept
return whether value is an array
Definition: json.h:4069
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.h:2734
static json from_cbor(raw_istream &is, const bool strict=true)
create a JSON value from an input in CBOR format
const PointerType get() const noexcept
get a pointer value (explicit)
Definition: json.h:4447
void dump(raw_ostream &os, int indent=-1, const char indent_char=' ', const bool ensure_ascii=false) const
static bool accept(std::span< const uint8_t > arr)
static json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.h:3417
std::function< bool(int depth, parse_event_t event, json &parsed)> parser_callback_t
per-element parser callback type
Definition: json.h:3119
bool is_null() const noexcept
return whether value is null
Definition: json.h:3888
static json parse(raw_istream &i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
create an empty value with a given type parse(raw_istream&, const parser_callback_t)
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.h:5579
const_reference operator[](std::string_view key) const
read-only access specified object element
friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.h:6802
ValueType get() const noexcept(noexcept(adl_serializer< ValueTypeCV, void >::from_json(std::declval< const json_t & >())))
get a value (explicit); special case
Definition: json.h:4399
bool is_object() const noexcept
return whether value is an object
Definition: json.h:4047
bool is_string() const noexcept
return whether value is a string
Definition: json.h:4091
std::string value(const json_pointer &ptr, const char *default_value) const
overload for a default value of type const char*
Definition: json.h:5094
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.h:6172
::wpi::json_pointer json_pointer
Definition: json.h:2686
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.h:5754
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.h:6482
std::pair< iterator, bool > emplace(std::string_view key, Args &&... args)
add an object to an object if key does not exist
Definition: json.h:6248
bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.h:3997
reference operator[](size_type idx)
access specified array element
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.h:5717
json_reverse_iterator< typename json::const_iterator > const_reverse_iterator
a const reverse iterator for a json container
Definition: json.h:2753
static void to_ubjson(raw_ostream &os, const json &j, const bool use_size=false, const bool use_type=false)
json(const json &other)
copy constructor
friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.h:6661
ValueType value(std::string_view key, const ValueType &default_value) const
access specified object element with default value
Definition: json.h:5001
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.h:5334
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.h:5688
friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
comparison: not equal
Definition: json.h:6695
static json meta()
returns version information on the library
Definition: raw_istream.h:22
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:44
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:298
basic_string_view< char > string_view
Definition: core.h:520
type
Definition: core.h:575
bool_constant< is_integral< T >::value &&!std::is_same< T, bool >::value &&!std::is_same< T, char >::value &&!std::is_same< T, wchar_t >::value > is_integer
Definition: format.h:3418
FMT_CONSTEXPR fp operator*(fp x, fp y)
Definition: format.h:1474
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_opt >::value > is_signed
Definition: format.h:996
auto ptr(T p) -> const void *
\rst Converts p to const void* for pointer formatting.
Definition: format.h:3808
static const symbolic::SymbolExpr< internal::symbolic_last_tag > last
Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last...
Definition: IndexedViewHelper.h:38
#define JSON_LIKELY(x)
Definition: json.h:160
#define JSON_CATCH(exception)
Definition: json.h:138
#define JSON_THROW(exception)
Definition: json.h:136
#define JSON_TRY
Definition: json.h:137
#define JSON_UNLIKELY(x)
Definition: json.h:161
constexpr common_t< T1, T2 > min(const T1 x, const T2 y) noexcept
Compile-time pairwise minimum function.
Definition: min.hpp:35
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
Definition: IndexedViewHelper.h:81
::uint64_t uint64_t
Definition: Meta.h:58
::int64_t int64_t
Definition: Meta.h:59
::uint8_t uint8_t
Definition: Meta.h:52
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
Definition: chrono.h:303
result
Definition: format.h:2556
GHC_FS_API directory_iterator begin(directory_iterator iter) noexcept
Definition: filesystem.hpp:5746
Definition: StdDeque.h:50
void swap(wpi::SmallVectorImpl< T > &LHS, wpi::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: SmallVector.h:1299
static constexpr const unit_t< compound_unit< energy::joule, time::seconds > > h(6.626070040e-34)
Planck constant.
static constexpr const charge::coulomb_t e(1.6021766208e-19)
elementary charge.
std::string to_string(const T &t)
Definition: base.h:93
unit_t< Units, T, NonLinearScale > & operator+=(unit_t< Units, T, NonLinearScale > &lhs, const RhsType &rhs) noexcept
Definition: base.h:2281
b
Definition: data.h:44
unit_t< Units, T, NonLinearScale > & operator++(unit_t< Units, T, NonLinearScale > &u) noexcept
Definition: base.h:2335
unit_t< Units, T, NonLinearScale > & operator--(unit_t< Units, T, NonLinearScale > &u) noexcept
Definition: base.h:2359
constexpr unit_t< Units, T, NonLinearScale > operator+(const unit_t< Units, T, NonLinearScale > &u) noexcept
Definition: base.h:2328
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.h:1202
value_t
the JSON type enumeration
Definition: json.h:702
@ number_integer
number value (signed integer)
@ boolean
boolean value
@ discarded
discarded by the the parser callback function
@ object
object (unordered set of name/value pairs)
@ string
string value
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.h:742
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, std::index_sequence< Idx... >)
Definition: json.h:1298
NLOHMANN_JSON_HAS_HELPER(mapped_type)
void from_json_array_impl(const BasicJsonType &j, CompatibleArrayType &arr, priority_tag< 0 >)
Definition: json.h:825
void from_json(const BasicJsonType &j, bool &b)
Definition: json.h:768
void to_json(BasicJsonType &j, const std::tuple< Args... > &t)
Definition: json.h:1304
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.h:210
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.h:724
void from_json(const BasicJsonType &j, std::tuple< Args... > &t)
Definition: json.h:984
void from_json_tuple_impl(const BasicJsonType &j, Tuple &t, std::index_sequence< Idx... >)
Definition: json.h:978
typename std::enable_if< B, T >::type enable_if_t
Definition: json.h:207
/file This file defines the SmallVector class.
Definition: AprilTagFieldLayout.h:18
bool operator!=(PointerUnion< PTs... > lhs, PointerUnion< PTs... > rhs)
Definition: PointerUnion.h:244
constexpr std::pair< std::string_view, std::string_view > split(std::string_view str, char separator) noexcept
Splits str into two substrings around the first occurrence of a separator character.
Definition: StringExtras.h:438
std::size_t operator()(const wpi::json &j) const
return a hash value for a JSON object
Definition: json.h:8034
bool operator()(wpi::detail::value_t lhs, wpi::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.h:8052
default JSONSerializer template argument
Definition: json.h:2558
static void to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::wpi::to_json(j, std::forward< ValueType >(val))))
convert any value type to a JSON value
Definition: json.h:2585
static void from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::wpi::from_json(std::forward< BasicJsonType >(j), val)))
convert a JSON value to any value type
Definition: json.h:2569
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.h:1120
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.h:1140
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.h:1150
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.h:1112
static void construct(BasicJsonType &j, std::span< T > arr)
Definition: json.h:1128
static void construct(BasicJsonType &j, bool b) noexcept
Definition: json.h:1043
static void construct(BasicJsonType &j, double val) noexcept
Definition: json.h:1076
static void construct(BasicJsonType &j, int64_t val) noexcept
Definition: json.h:1100
static void construct(BasicJsonType &j, uint64_t val) noexcept
Definition: json.h:1088
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.h:1167
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.h:1175
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.h:1184
static void construct(BasicJsonType &j, std::string_view s)
Definition: json.h:1055
static void construct(BasicJsonType &j, T &&s)
Definition: json.h:1064
Definition: json.h:1037
Definition: json.h:990
void operator()(const BasicJsonType &j, T &val) const noexcept(noexcept(std::declval< from_json_fn >().call(j, val, priority_tag< 1 > {})))
Definition: json.h:1015
Definition: json.h:306
Definition: json.h:340
an iterator value
Definition: json.h:1468
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.h:1474
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.h:1472
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.h:1470
static auto constexpr value
Definition: json.h:266
std::numeric_limits< CompatibleNumberIntegerType > CompatibleLimits
Definition: json.h:285
static constexpr auto value
Definition: json.h:296
static auto constexpr value
Definition: json.h:247
Definition: json.h:366
Definition: json.h:223
Definition: json.h:256
Definition: json.h:201
Definition: json.h:214
Definition: json.h:213
Definition: json.h:372
static constexpr T value
Definition: json.h:373
Definition: json.h:1310
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.h:1335
constexpr T & get(wpi::array< T, N > &arr) noexcept
Definition: array.h:66