1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++
4 |  |  |__   |  |  | | | |  version 2.1.1
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
7 Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
8 Permission is hereby  granted, free of charge, to any  person obtaining a copy
9 of this software and associated  documentation files (the "Software"), to deal
10 in the Software  without restriction, including without  limitation the rights
11 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
12 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
13 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
17 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
18 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
19 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
20 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 
25 #ifndef NLOHMANN_JSON_HPP
26 #define NLOHMANN_JSON_HPP
27 
28 #include <algorithm> // all_of, copy, fill, find, for_each, generate_n, none_of, remove, reverse, transform
29 #include <array> // array
30 #include <cassert> // assert
31 #include <ciso646> // and, not, or
32 #include <clocale> // lconv, localeconv
33 #include <cmath> // isfinite, labs, ldexp, signbit
34 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
35 #include <cstdint> // int64_t, uint64_t
36 #include <cstdlib> // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull
37 #include <cstring> // memcpy, strlen
38 #include <forward_list> // forward_list
39 #include <functional> // function, hash, less
40 #include <initializer_list> // initializer_list
41 #include <iomanip> // hex
42 #include <iosfwd>   // istream, ostream
43 #include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
44 #include <limits> // numeric_limits
45 #include <locale> // locale
46 #include <map> // map
47 #include <memory> // addressof, allocator, allocator_traits, unique_ptr
48 #include <numeric> // accumulate
49 #include <sstream> // stringstream
50 #include <string> // getline, stoi, string, to_string
51 #include <type_traits> // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type
52 #include <utility> // declval, forward, make_pair, move, pair, swap
53 #include <valarray> // valarray
54 #include <vector> // vector
55 
56 // exclude unsupported compilers
57 #if defined(__clang__)
58     #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
59         #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
60     #endif
61 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
62     #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
63         #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
64     #endif
65 #endif
66 
67 // disable float-equal warnings on GCC/clang
68 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
69     #pragma GCC diagnostic push
70     #pragma GCC diagnostic ignored "-Wfloat-equal"
71 #endif
72 
73 // disable documentation warnings on clang
74 #if defined(__clang__)
75     #pragma GCC diagnostic push
76     #pragma GCC diagnostic ignored "-Wdocumentation"
77 #endif
78 
79 // allow for portable deprecation warnings
80 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
81     #define JSON_DEPRECATED __attribute__((deprecated))
82 #elif defined(_MSC_VER)
83     #define JSON_DEPRECATED __declspec(deprecated)
84 #else
85     #define JSON_DEPRECATED
86 #endif
87 
88 // allow to disable exceptions
89 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION)
90     #define JSON_THROW(exception) throw exception
91     #define JSON_TRY try
92     #define JSON_CATCH(exception) catch(exception)
93 #else
94     #define JSON_THROW(exception) std::abort()
95     #define JSON_TRY if(true)
96     #define JSON_CATCH(exception) if(false)
97 #endif
98 
99 // manual branch prediction
100 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
101     #define JSON_LIKELY(x)      __builtin_expect(!!(x), 1)
102     #define JSON_UNLIKELY(x)    __builtin_expect(!!(x), 0)
103 #else
104     #define JSON_LIKELY(x)      x
105     #define JSON_UNLIKELY(x)    x
106 #endif
107 
108 // cpp language standard detection
109 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
110     #define JSON_HAS_CPP_17
111     #define JSON_HAS_CPP_14
112 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
113     #define JSON_HAS_CPP_14
114 #endif
115 
116 /*!
117 @brief namespace for Niels Lohmann
118 @see https://github.com/nlohmann
119 @since version 1.0.0
120 */
121 namespace nlohmann
122 {
123 template<typename = void, typename = void>
124 struct adl_serializer;
125 
126 // forward declaration of basic_json (required to split the class)
127 template<template<typename U, typename V, typename... Args> class ObjectType =
128          std::map,
129          template<typename U, typename... Args> class ArrayType = std::vector,
130          class StringType = std::string, class BooleanType = bool,
131          class NumberIntegerType = std::int64_t,
132          class NumberUnsignedType = std::uint64_t,
133          class NumberFloatType = double,
134          template<typename U> class AllocatorType = std::allocator,
135          template<typename T, typename SFINAE = void> class JSONSerializer =
136          adl_serializer>
137 class basic_json;
138 
139 // Ugly macros to avoid uglier copy-paste when specializing basic_json
140 // This is only temporary and will be removed in 3.0
141 
142 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
143     template<template<typename, typename, typename...> class ObjectType,   \
144              template<typename, typename...> class ArrayType,              \
145              class StringType, class BooleanType, class NumberIntegerType, \
146              class NumberUnsignedType, class NumberFloatType,              \
147              template<typename> class AllocatorType,                       \
148              template<typename, typename = void> class JSONSerializer>
149 
150 #define NLOHMANN_BASIC_JSON_TPL                                            \
151     basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
152     NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
153     AllocatorType, JSONSerializer>
154 
155 
156 /*!
157 @brief unnamed namespace with internal helper functions
158 This namespace collects some functions that could not be defined inside the
159 @ref basic_json class.
160 @since version 2.1.0
161 */
162 namespace detail
163 {
164 ////////////////
165 // exceptions //
166 ////////////////
167 
168 /*!
169 @brief general exception of the @ref basic_json class
170 This class is an extension of `std::exception` objects with a member @a id for
171 exception ids. It is used as the base class for all exceptions thrown by the
172 @ref basic_json class. This class can hence be used as "wildcard" to catch
173 exceptions.
174 Subclasses:
175 - @ref parse_error for exceptions indicating a parse error
176 - @ref invalid_iterator for exceptions indicating errors with iterators
177 - @ref type_error for exceptions indicating executing a member function with
178                   a wrong type
179 - @ref out_of_range for exceptions indicating access out of the defined range
180 - @ref other_error for exceptions indicating other library errors
181 @internal
182 @note To have nothrow-copy-constructible exceptions, we internally use
183       `std::runtime_error` which can cope with arbitrary-length error messages.
184       Intermediate strings are built with static functions and then passed to
185       the actual constructor.
186 @endinternal
187 @liveexample{The following code shows how arbitrary library exceptions can be
188 caught.,exception}
189 @since version 3.0.0
190 */
191 class exception : public std::exception
192 {
193   public:
194     /// returns the explanatory string
what() const195     const char* what() const noexcept override
196     {
197         return m.what();
198     }
199 
200     /// the id of the exception
201     const int id;
202 
203   protected:
exception(int id_,const char * what_arg)204     exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
205 
name(const std::string & ename,int id_)206     static std::string name(const std::string& ename, int id_)
207     {
208         return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
209     }
210 
211   private:
212     /// an exception object as storage for error messages
213     std::runtime_error m;
214 };
215 
216 /*!
217 @brief exception indicating a parse error
218 This excpetion is thrown by the library when a parse error occurs. Parse errors
219 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
220 as when using JSON Patch.
221 Member @a byte holds the byte index of the last read character in the input
222 file.
223 Exceptions have ids 1xx.
224 name / id                      | example message | description
225 ------------------------------ | --------------- | -------------------------
226 json.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.
227 json.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.
228 json.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.
229 json.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.
230 json.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.
231 json.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 wihtout a leading `0`.
232 json.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.
233 json.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.
234 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
235 json.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.
236 json.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.
237 json.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.
238 @note For an input with n bytes, 1 is the index of the first character and n+1
239       is the index of the terminating null byte or the end of file. This also
240       holds true when reading a byte vector (CBOR or MessagePack).
241 @liveexample{The following code shows how a `parse_error` exception can be
242 caught.,parse_error}
243 @sa @ref exception for the base class of the library exceptions
244 @sa @ref invalid_iterator for exceptions indicating errors with iterators
245 @sa @ref type_error for exceptions indicating executing a member function with
246                     a wrong type
247 @sa @ref out_of_range for exceptions indicating access out of the defined range
248 @sa @ref other_error for exceptions indicating other library errors
249 @since version 3.0.0
250 */
251 class parse_error : public exception
252 {
253   public:
254     /*!
255     @brief create a parse error exception
256     @param[in] id_       the id of the exception
257     @param[in] byte_     the byte index where the error occurred (or 0 if the
258                          position cannot be determined)
259     @param[in] what_arg  the explanatory string
260     @return parse_error object
261     */
create(int id_,std::size_t byte_,const std::string & what_arg)262     static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
263     {
264         std::string w = exception::name("parse_error", id_) + "parse error" +
265                         (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
266                         ": " + what_arg;
267         return parse_error(id_, byte_, w.c_str());
268     }
269 
270     /*!
271     @brief byte index of the parse error
272     The byte index of the last read character in the input file.
273     @note For an input with n bytes, 1 is the index of the first character and
274           n+1 is the index of the terminating null byte or the end of file.
275           This also holds true when reading a byte vector (CBOR or MessagePack).
276     */
277     const std::size_t byte;
278 
279   private:
parse_error(int id_,std::size_t byte_,const char * what_arg)280     parse_error(int id_, std::size_t byte_, const char* what_arg)
281         : exception(id_, what_arg), byte(byte_) {}
282 };
283 
284 /*!
285 @brief exception indicating errors with iterators
286 This exception is thrown if iterators passed to a library function do not match
287 the expected semantics.
288 Exceptions have ids 2xx.
289 name / id                           | example message | description
290 ----------------------------------- | --------------- | -------------------------
291 json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_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.
292 json.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.
293 json.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.
294 json.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.
295 json.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.
296 json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
297 json.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.
298 json.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.
299 json.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.
300 json.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.
301 json.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.
302 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
303 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
304 json.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().
305 @liveexample{The following code shows how an `invalid_iterator` exception can be
306 caught.,invalid_iterator}
307 @sa @ref exception for the base class of the library exceptions
308 @sa @ref parse_error for exceptions indicating a parse error
309 @sa @ref type_error for exceptions indicating executing a member function with
310                     a wrong type
311 @sa @ref out_of_range for exceptions indicating access out of the defined range
312 @sa @ref other_error for exceptions indicating other library errors
313 @since version 3.0.0
314 */
315 class invalid_iterator : public exception
316 {
317   public:
create(int id_,const std::string & what_arg)318     static invalid_iterator create(int id_, const std::string& what_arg)
319     {
320         std::string w = exception::name("invalid_iterator", id_) + what_arg;
321         return invalid_iterator(id_, w.c_str());
322     }
323 
324   private:
invalid_iterator(int id_,const char * what_arg)325     invalid_iterator(int id_, const char* what_arg)
326         : exception(id_, what_arg) {}
327 };
328 
329 /*!
330 @brief exception indicating executing a member function with a wrong type
331 This exception is thrown in case of a type error; that is, a library function is
332 executed on a JSON value whose type does not match the expected semantics.
333 Exceptions have ids 3xx.
334 name / id                     | example message | description
335 ----------------------------- | --------------- | -------------------------
336 json.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.
337 json.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.
338 json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_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&.
339 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
340 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
341 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
342 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
343 json.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.
344 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
345 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
346 json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
347 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
348 json.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.
349 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
350 json.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.
351 @liveexample{The following code shows how a `type_error` exception can be
352 caught.,type_error}
353 @sa @ref exception for the base class of the library exceptions
354 @sa @ref parse_error for exceptions indicating a parse error
355 @sa @ref invalid_iterator for exceptions indicating errors with iterators
356 @sa @ref out_of_range for exceptions indicating access out of the defined range
357 @sa @ref other_error for exceptions indicating other library errors
358 @since version 3.0.0
359 */
360 class type_error : public exception
361 {
362   public:
create(int id_,const std::string & what_arg)363     static type_error create(int id_, const std::string& what_arg)
364     {
365         std::string w = exception::name("type_error", id_) + what_arg;
366         return type_error(id_, w.c_str());
367     }
368 
369   private:
type_error(int id_,const char * what_arg)370     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
371 };
372 
373 /*!
374 @brief exception indicating access out of the defined range
375 This exception is thrown in case a library function is called on an input
376 parameter that exceeds the expected range, for instance in case of array
377 indices or nonexisting object keys.
378 Exceptions have ids 4xx.
379 name / id                       | example message | description
380 ------------------------------- | --------------- | -------------------------
381 json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
382 json.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.
383 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
384 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
385 json.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.
386 json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
387 @liveexample{The following code shows how an `out_of_range` exception can be
388 caught.,out_of_range}
389 @sa @ref exception for the base class of the library exceptions
390 @sa @ref parse_error for exceptions indicating a parse error
391 @sa @ref invalid_iterator for exceptions indicating errors with iterators
392 @sa @ref type_error for exceptions indicating executing a member function with
393                     a wrong type
394 @sa @ref other_error for exceptions indicating other library errors
395 @since version 3.0.0
396 */
397 class out_of_range : public exception
398 {
399   public:
create(int id_,const std::string & what_arg)400     static out_of_range create(int id_, const std::string& what_arg)
401     {
402         std::string w = exception::name("out_of_range", id_) + what_arg;
403         return out_of_range(id_, w.c_str());
404     }
405 
406   private:
out_of_range(int id_,const char * what_arg)407     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
408 };
409 
410 /*!
411 @brief exception indicating other library errors
412 This exception is thrown in case of errors that cannot be classified with the
413 other exception types.
414 Exceptions have ids 5xx.
415 name / id                      | example message | description
416 ------------------------------ | --------------- | -------------------------
417 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
418 json.exception.other_error.502 | invalid object size for conversion | Some conversions to user-defined types impose constraints on the object size (e.g. std::pair)
419 @sa @ref exception for the base class of the library exceptions
420 @sa @ref parse_error for exceptions indicating a parse error
421 @sa @ref invalid_iterator for exceptions indicating errors with iterators
422 @sa @ref type_error for exceptions indicating executing a member function with
423                     a wrong type
424 @sa @ref out_of_range for exceptions indicating access out of the defined range
425 @liveexample{The following code shows how an `other_error` exception can be
426 caught.,other_error}
427 @since version 3.0.0
428 */
429 class other_error : public exception
430 {
431   public:
create(int id_,const std::string & what_arg)432     static other_error create(int id_, const std::string& what_arg)
433     {
434         std::string w = exception::name("other_error", id_) + what_arg;
435         return other_error(id_, w.c_str());
436     }
437 
438   private:
other_error(int id_,const char * what_arg)439     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
440 };
441 
442 
443 
444 ///////////////////////////
445 // JSON type enumeration //
446 ///////////////////////////
447 
448 /*!
449 @brief the JSON type enumeration
450 This enumeration collects the different JSON types. It is internally used to
451 distinguish the stored values, and the functions @ref basic_json::is_null(),
452 @ref basic_json::is_object(), @ref basic_json::is_array(),
453 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
454 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
455 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
456 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
457 @ref basic_json::is_structured() rely on it.
458 @note There are three enumeration entries (number_integer, number_unsigned, and
459 number_float), because the library distinguishes these three types for numbers:
460 @ref basic_json::number_unsigned_t is used for unsigned integers,
461 @ref basic_json::number_integer_t is used for signed integers, and
462 @ref basic_json::number_float_t is used for floating-point numbers or to
463 approximate integers which do not fit in the limits of their respective type.
464 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
465 value with the default value for a given type
466 @since version 1.0.0
467 */
468 enum class value_t : uint8_t
469 {
470     null,             ///< null value
471     object,           ///< object (unordered set of name/value pairs)
472     array,            ///< array (ordered collection of values)
473     string,           ///< string value
474     boolean,          ///< boolean value
475     number_integer,   ///< number value (signed integer)
476     number_unsigned,  ///< number value (unsigned integer)
477     number_float,     ///< number value (floating-point)
478     discarded         ///< discarded by the the parser callback function
479 };
480 
481 /*!
482 @brief comparison operator for JSON types
483 Returns an ordering that is similar to Python:
484 - order: null < boolean < number < object < array < string
485 - furthermore, each type is not smaller than itself
486 @since version 1.0.0
487 */
operator <(const value_t lhs,const value_t rhs)488 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
489 {
490     static constexpr std::array<uint8_t, 8> order = {{
491             0, // null
492             3, // object
493             4, // array
494             5, // string
495             1, // boolean
496             2, // integer
497             2, // unsigned
498             2, // float
499         }
500     };
501 
502     // discarded values are not comparable
503     return lhs != value_t::discarded and rhs != value_t::discarded and
504            order[static_cast<std::size_t>(lhs)] < order[static_cast<std::size_t>(rhs)];
505 }
506 
507 
508 /////////////
509 // helpers //
510 /////////////
511 
512 template<typename> struct is_basic_json : std::false_type {};
513 
514 NLOHMANN_BASIC_JSON_TPL_DECLARATION
515 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
516 
517 // alias templates to reduce boilerplate
518 template<bool B, typename T = void>
519 using enable_if_t = typename std::enable_if<B, T>::type;
520 
521 template<typename T>
522 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
523 
524 // implementation of C++14 index_sequence and affiliates
525 // source: https://stackoverflow.com/a/32223343
526 template<std::size_t... Ints>
527 struct index_sequence
528 {
529     using type = index_sequence;
530     using value_type = std::size_t;
sizenlohmann::detail::index_sequence531     static constexpr std::size_t size() noexcept
532     {
533         return sizeof...(Ints);
534     }
535 };
536 
537 template<class Sequence1, class Sequence2>
538 struct merge_and_renumber;
539 
540 template<std::size_t... I1, std::size_t... I2>
541 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
542         : index_sequence < I1..., (sizeof...(I1) + I2)... >
543           {};
544 
545 template<std::size_t N>
546 struct make_index_sequence
547     : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
548       typename make_index_sequence < N - N / 2 >::type >
549 {};
550 
551 template<> struct make_index_sequence<0> : index_sequence<> { };
552 template<> struct make_index_sequence<1> : index_sequence<0> { };
553 
554 template<typename... Ts>
555 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
556 
557 /*
558 Implementation of two C++17 constructs: conjunction, negation. This is needed
559 to avoid evaluating all the traits in a condition
560 For example: not std::is_same<void, T>::value and has_value_type<T>::value
561 will not compile when T = void (on MSVC at least). Whereas
562 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
563 stop evaluating if negation<...>::value == false
564 Please note that those constructs must be used with caution, since symbols can
565 become very long quickly (which can slow down compilation and cause MSVC
566 internal compiler errors). Only use it when you have to (see example ahead).
567 */
568 template<class...> struct conjunction : std::true_type {};
569 template<class B1> struct conjunction<B1> : B1 {};
570 template<class B1, class... Bn>
571 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
572 
573 template<class B> struct negation : std::integral_constant < bool, !B::value > {};
574 
575 // dispatch utility (taken from ranges-v3)
576 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
577 template<> struct priority_tag<0> {};
578 
579 
580 //////////////////
581 // constructors //
582 //////////////////
583 
584 template<value_t> struct external_constructor;
585 
586 template<>
587 struct external_constructor<value_t::boolean>
588 {
589     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor590     static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
591     {
592         j.m_type = value_t::boolean;
593         j.m_value = b;
594         j.assert_invariant();
595     }
596 };
597 
598 template<>
599 struct external_constructor<value_t::string>
600 {
601     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor602     static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
603     {
604         j.m_type = value_t::string;
605         j.m_value = s;
606         j.assert_invariant();
607     }
608 
609     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor610     static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
611     {
612         j.m_type = value_t::string;
613         j.m_value = std::move(s);
614         j.assert_invariant();
615     }
616 };
617 
618 template<>
619 struct external_constructor<value_t::number_float>
620 {
621     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor622     static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
623     {
624         j.m_type = value_t::number_float;
625         j.m_value = val;
626         j.assert_invariant();
627     }
628 };
629 
630 template<>
631 struct external_constructor<value_t::number_unsigned>
632 {
633     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor634     static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
635     {
636         j.m_type = value_t::number_unsigned;
637         j.m_value = val;
638         j.assert_invariant();
639     }
640 };
641 
642 template<>
643 struct external_constructor<value_t::number_integer>
644 {
645     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor646     static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
647     {
648         j.m_type = value_t::number_integer;
649         j.m_value = val;
650         j.assert_invariant();
651     }
652 };
653 
654 template<>
655 struct external_constructor<value_t::array>
656 {
657     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor658     static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
659     {
660         j.m_type = value_t::array;
661         j.m_value = arr;
662         j.assert_invariant();
663     }
664 
665     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor666     static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
667     {
668         j.m_type = value_t::array;
669         j.m_value = std::move(arr);
670         j.assert_invariant();
671     }
672 
673     template<typename BasicJsonType, typename CompatibleArrayType,
674              enable_if_t<not std::is_same<CompatibleArrayType,
675                                           typename BasicJsonType::array_t>::value,
676                          int> = 0>
constructnlohmann::detail::external_constructor677     static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
678     {
679         using std::begin;
680         using std::end;
681         j.m_type = value_t::array;
682         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
683         j.assert_invariant();
684     }
685 
686     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor687     static void construct(BasicJsonType& j, const std::vector<bool>& arr)
688     {
689         j.m_type = value_t::array;
690         j.m_value = value_t::array;
691         j.m_value.array->reserve(arr.size());
692         for (bool x : arr)
693         {
694             j.m_value.array->push_back(x);
695         }
696         j.assert_invariant();
697     }
698 
699     template<typename BasicJsonType, typename T,
700              enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor701     static void construct(BasicJsonType& j, const std::valarray<T>& arr)
702     {
703         j.m_type = value_t::array;
704         j.m_value = value_t::array;
705         j.m_value.array->resize(arr.size());
706         std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
707         j.assert_invariant();
708     }
709 };
710 
711 template<>
712 struct external_constructor<value_t::object>
713 {
714     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor715     static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
716     {
717         j.m_type = value_t::object;
718         j.m_value = obj;
719         j.assert_invariant();
720     }
721 
722     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor723     static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
724     {
725         j.m_type = value_t::object;
726         j.m_value = std::move(obj);
727         j.assert_invariant();
728     }
729 
730     template<typename BasicJsonType, typename CompatibleObjectType,
731              enable_if_t<not std::is_same<CompatibleObjectType,
732                                           typename BasicJsonType::object_t>::value, int> = 0>
constructnlohmann::detail::external_constructor733     static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
734     {
735         using std::begin;
736         using std::end;
737 
738         j.m_type = value_t::object;
739         j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
740         j.assert_invariant();
741     }
742 };
743 
744 
745 ////////////////////////
746 // has_/is_ functions //
747 ////////////////////////
748 
749 /*!
750 @brief Helper to determine whether there's a key_type for T.
751 This helper is used to tell associative containers apart from other containers
752 such as sequence containers. For instance, `std::map` passes the test as it
753 contains a `mapped_type`, whereas `std::vector` fails the test.
754 @sa http://stackoverflow.com/a/7728728/266378
755 @since version 1.0.0, overworked in version 2.0.6
756 */
757 #define NLOHMANN_JSON_HAS_HELPER(type)                                        \
758     template<typename T> struct has_##type {                                  \
759     private:                                                                  \
760         template<typename U, typename = typename U::type>                     \
761         static int detect(U &&);                                              \
762         static void detect(...);                                              \
763     public:                                                                   \
764         static constexpr bool value =                                         \
765                 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
766     }
767 
768 NLOHMANN_JSON_HAS_HELPER(mapped_type);
769 NLOHMANN_JSON_HAS_HELPER(key_type);
770 NLOHMANN_JSON_HAS_HELPER(value_type);
771 NLOHMANN_JSON_HAS_HELPER(iterator);
772 
773 #undef NLOHMANN_JSON_HAS_HELPER
774 
775 
776 template<bool B, class RealType, class CompatibleObjectType>
777 struct is_compatible_object_type_impl : std::false_type {};
778 
779 template<class RealType, class CompatibleObjectType>
780 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
781 {
782     static constexpr auto value =
783         std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
784         std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
785 };
786 
787 template<class BasicJsonType, class CompatibleObjectType>
788 struct is_compatible_object_type
789 {
790     static auto constexpr value = is_compatible_object_type_impl <
791                                   conjunction<negation<std::is_same<void, CompatibleObjectType>>,
792                                   has_mapped_type<CompatibleObjectType>,
793                                   has_key_type<CompatibleObjectType>>::value,
794                                   typename BasicJsonType::object_t, CompatibleObjectType >::value;
795 };
796 
797 template<typename BasicJsonType, typename T>
798 struct is_basic_json_nested_type
799 {
800     static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
801                                   std::is_same<T, typename BasicJsonType::const_iterator>::value or
802                                   std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
803                                   std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
804 };
805 
806 template<class BasicJsonType, class CompatibleArrayType>
807 struct is_compatible_array_type
808 {
809     static auto constexpr value =
810         conjunction<negation<std::is_same<void, CompatibleArrayType>>,
811         negation<is_compatible_object_type<
812         BasicJsonType, CompatibleArrayType>>,
813         negation<std::is_constructible<typename BasicJsonType::string_t,
814         CompatibleArrayType>>,
815         negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
816         has_value_type<CompatibleArrayType>,
817         has_iterator<CompatibleArrayType>>::value;
818 };
819 
820 template<bool, typename, typename>
821 struct is_compatible_integer_type_impl : std::false_type {};
822 
823 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
824 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
825 {
826     // is there an assert somewhere on overflows?
827     using RealLimits = std::numeric_limits<RealIntegerType>;
828     using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
829 
830     static constexpr auto value =
831         std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
832         CompatibleLimits::is_integer and
833         RealLimits::is_signed == CompatibleLimits::is_signed;
834 };
835 
836 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
837 struct is_compatible_integer_type
838 {
839     static constexpr auto value =
840         is_compatible_integer_type_impl <
841         std::is_integral<CompatibleNumberIntegerType>::value and
842         not std::is_same<bool, CompatibleNumberIntegerType>::value,
843         RealIntegerType, CompatibleNumberIntegerType > ::value;
844 };
845 
846 
847 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
848 template<typename BasicJsonType, typename T>
849 struct has_from_json
850 {
851   private:
852     // also check the return type of from_json
853     template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
854                  std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
855     static int detect(U&&);
856     static void detect(...);
857 
858   public:
859     static constexpr bool value = std::is_integral<decltype(
860                                       detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
861 };
862 
863 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
864 // this overload is used for non-default-constructible user-defined-types
865 template<typename BasicJsonType, typename T>
866 struct has_non_default_from_json
867 {
868   private:
869     template <
870         typename U,
871         typename = enable_if_t<std::is_same<
872                                    T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
873     static int detect(U&&);
874     static void detect(...);
875 
876   public:
877     static constexpr bool value = std::is_integral<decltype(detect(
878                                       std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
879 };
880 
881 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
882 template<typename BasicJsonType, typename T>
883 struct has_to_json
884 {
885   private:
886     template<typename U, typename = decltype(uncvref_t<U>::to_json(
887                  std::declval<BasicJsonType&>(), std::declval<T>()))>
888     static int detect(U&&);
889     static void detect(...);
890 
891   public:
892     static constexpr bool value = std::is_integral<decltype(detect(
893                                       std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
894 };
895 
896 
897 /////////////
898 // to_json //
899 /////////////
900 
901 template<typename BasicJsonType, typename T, enable_if_t<
902              std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)903 void to_json(BasicJsonType& j, T b) noexcept
904 {
905     external_constructor<value_t::boolean>::construct(j, b);
906 }
907 
908 template<typename BasicJsonType, typename CompatibleString,
909          enable_if_t<std::is_constructible<typename BasicJsonType::string_t,
910                      CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)911 void to_json(BasicJsonType& j, const CompatibleString& s)
912 {
913     external_constructor<value_t::string>::construct(j, s);
914 }
915 
916 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)917 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
918 {
919     external_constructor<value_t::string>::construct(j, std::move(s));
920 }
921 
922 template<typename BasicJsonType, typename FloatType,
923          enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)924 void to_json(BasicJsonType& j, FloatType val) noexcept
925 {
926     external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
927 }
928 
929 template <
930     typename BasicJsonType, typename CompatibleNumberUnsignedType,
931     enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
932                 CompatibleNumberUnsignedType>::value, int> = 0 >
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)933 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
934 {
935     external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
936 }
937 
938 template <
939     typename BasicJsonType, typename CompatibleNumberIntegerType,
940     enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
941                 CompatibleNumberIntegerType>::value, int> = 0 >
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)942 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
943 {
944     external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
945 }
946 
947 template<typename BasicJsonType, typename EnumType,
948          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)949 void to_json(BasicJsonType& j, EnumType e) noexcept
950 {
951     using underlying_type = typename std::underlying_type<EnumType>::type;
952     external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
953 }
954 
955 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)956 void to_json(BasicJsonType& j, const std::vector<bool>& e)
957 {
958     external_constructor<value_t::array>::construct(j, e);
959 }
960 
961 template <
962     typename BasicJsonType, typename CompatibleArrayType,
963     enable_if_t <
964         is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
965         std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
966         int > = 0 >
to_json(BasicJsonType & j,const CompatibleArrayType & arr)967 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
968 {
969     external_constructor<value_t::array>::construct(j, arr);
970 }
971 
972 template <typename BasicJsonType, typename T,
973           enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,std::valarray<T> arr)974 void to_json(BasicJsonType& j, std::valarray<T> arr)
975 {
976     external_constructor<value_t::array>::construct(j, std::move(arr));
977 }
978 
979 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)980 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
981 {
982     external_constructor<value_t::array>::construct(j, std::move(arr));
983 }
984 
985 template <
986     typename BasicJsonType, typename CompatibleObjectType,
987     enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
988                 int> = 0 >
to_json(BasicJsonType & j,const CompatibleObjectType & obj)989 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
990 {
991     external_constructor<value_t::object>::construct(j, obj);
992 }
993 
994 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)995 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
996 {
997     external_constructor<value_t::object>::construct(j, std::move(obj));
998 }
999 
1000 template<typename BasicJsonType, typename T, std::size_t N,
1001          enable_if_t<not std::is_constructible<
1002                          typename BasicJsonType::string_t, T (&)[N]>::value,
1003                      int> = 0>
to_json(BasicJsonType & j,T (& arr)[N])1004 void to_json(BasicJsonType& j, T (&arr)[N])
1005 {
1006     external_constructor<value_t::array>::construct(j, arr);
1007 }
1008 
1009 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::pair<Args...> & p)1010 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1011 {
1012     j = {p.first, p.second};
1013 }
1014 
1015 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)1016 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
1017 {
1018     j = {std::get<Idx>(t)...};
1019 }
1020 
1021 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::tuple<Args...> & t)1022 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1023 {
1024     to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1025 }
1026 
1027 ///////////////
1028 // from_json //
1029 ///////////////
1030 
1031 // overloads for basic_json template parameters
1032 template<typename BasicJsonType, typename ArithmeticType,
1033          enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1034                      not std::is_same<ArithmeticType,
1035                                       typename BasicJsonType::boolean_t>::value,
1036                      int> = 0>
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)1037 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1038 {
1039     switch (static_cast<value_t>(j))
1040     {
1041         case value_t::number_unsigned:
1042         {
1043             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1044             break;
1045         }
1046         case value_t::number_integer:
1047         {
1048             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1049             break;
1050         }
1051         case value_t::number_float:
1052         {
1053             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1054             break;
1055         }
1056 
1057         default:
1058             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1059     }
1060 }
1061 
1062 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)1063 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1064 {
1065     if (JSON_UNLIKELY(not j.is_boolean()))
1066     {
1067         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1068     }
1069     b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1070 }
1071 
1072 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)1073 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1074 {
1075     if (JSON_UNLIKELY(not j.is_string()))
1076     {
1077         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1078     }
1079     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1080 }
1081 
1082 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)1083 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1084 {
1085     get_arithmetic_value(j, val);
1086 }
1087 
1088 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)1089 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1090 {
1091     get_arithmetic_value(j, val);
1092 }
1093 
1094 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)1095 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1096 {
1097     get_arithmetic_value(j, val);
1098 }
1099 
1100 template<typename BasicJsonType, typename EnumType,
1101          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)1102 void from_json(const BasicJsonType& j, EnumType& e)
1103 {
1104     typename std::underlying_type<EnumType>::type val;
1105     get_arithmetic_value(j, val);
1106     e = static_cast<EnumType>(val);
1107 }
1108 
1109 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::array_t & arr)1110 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
1111 {
1112     if (JSON_UNLIKELY(not j.is_array()))
1113     {
1114         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1115     }
1116     arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1117 }
1118 
1119 // forward_list doesn't have an insert method
1120 template<typename BasicJsonType, typename T, typename Allocator,
1121          enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)1122 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1123 {
1124     if (JSON_UNLIKELY(not j.is_array()))
1125     {
1126         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1127     }
1128     std::transform(j.rbegin(), j.rend(),
1129                    std::front_inserter(l), [](const BasicJsonType & i)
1130     {
1131         return i.template get<T>();
1132     });
1133 }
1134 
1135 // valarray doesn't have an insert method
1136 template<typename BasicJsonType, typename T,
1137          enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)1138 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1139 {
1140     if (JSON_UNLIKELY(not j.is_array()))
1141     {
1142         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1143     }
1144     l.resize(j.size());
1145     std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1146 }
1147 
1148 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<0>)1149 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/)
1150 {
1151     using std::end;
1152 
1153     std::transform(j.begin(), j.end(),
1154                    std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1155     {
1156         // get<BasicJsonType>() returns *this, this won't call a from_json
1157         // method when value_type is BasicJsonType
1158         return i.template get<typename CompatibleArrayType::value_type>();
1159     });
1160 }
1161 
1162 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<1>)1163 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
1164 -> decltype(
1165     arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1166     void())
1167 {
1168     using std::end;
1169 
1170     arr.reserve(j.size());
1171     std::transform(j.begin(), j.end(),
1172                    std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1173     {
1174         // get<BasicJsonType>() returns *this, this won't call a from_json
1175         // method when value_type is BasicJsonType
1176         return i.template get<typename CompatibleArrayType::value_type>();
1177     });
1178 }
1179 
1180 template<typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)1181 void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
1182 {
1183     for (std::size_t i = 0; i < N; ++i)
1184     {
1185         arr[i] = j.at(i).template get<T>();
1186     }
1187 }
1188 
1189 template<typename BasicJsonType, typename CompatibleArrayType,
1190          enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1191                      std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
1192                      not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
from_json(const BasicJsonType & j,CompatibleArrayType & arr)1193 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1194 {
1195     if (JSON_UNLIKELY(not j.is_array()))
1196     {
1197         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1198     }
1199 
1200     from_json_array_impl(j, arr, priority_tag<2> {});
1201 }
1202 
1203 template<typename BasicJsonType, typename CompatibleObjectType,
1204          enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,CompatibleObjectType & obj)1205 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1206 {
1207     if (JSON_UNLIKELY(not j.is_object()))
1208     {
1209         JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1210     }
1211 
1212     auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1213     using value_type = typename CompatibleObjectType::value_type;
1214     std::transform(
1215         inner_object->begin(), inner_object->end(),
1216         std::inserter(obj, obj.begin()),
1217         [](typename BasicJsonType::object_t::value_type const & p)
1218     {
1219         return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1220     });
1221 }
1222 
1223 // overload for arithmetic types, not chosen for basic_json template arguments
1224 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1225 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1226 // an arithmetic type?
1227 template<typename BasicJsonType, typename ArithmeticType,
1228          enable_if_t <
1229              std::is_arithmetic<ArithmeticType>::value and
1230              not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1231              not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1232              not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1233              not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1234              int> = 0>
from_json(const BasicJsonType & j,ArithmeticType & val)1235 void from_json(const BasicJsonType& j, ArithmeticType& val)
1236 {
1237     switch (static_cast<value_t>(j))
1238     {
1239         case value_t::number_unsigned:
1240         {
1241             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1242             break;
1243         }
1244         case value_t::number_integer:
1245         {
1246             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1247             break;
1248         }
1249         case value_t::number_float:
1250         {
1251             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1252             break;
1253         }
1254         case value_t::boolean:
1255         {
1256             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1257             break;
1258         }
1259 
1260         default:
1261             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1262     }
1263 }
1264 
1265 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)1266 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1267 {
1268     p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1269 }
1270 
1271 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)1272 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1273 {
1274     t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1275 }
1276 
1277 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)1278 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1279 {
1280     from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1281 }
1282 
1283 struct to_json_fn
1284 {
1285   private:
1286     template<typename BasicJsonType, typename T>
callnlohmann::detail::to_json_fn1287     auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1288     -> decltype(to_json(j, std::forward<T>(val)), void())
1289     {
1290         return to_json(j, std::forward<T>(val));
1291     }
1292 
1293     template<typename BasicJsonType, typename T>
callnlohmann::detail::to_json_fn1294     void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1295     {
1296         static_assert(sizeof(BasicJsonType) == 0,
1297                       "could not find to_json() method in T's namespace");
1298     }
1299 
1300   public:
1301     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn1302     void operator()(BasicJsonType& j, T&& val) const
1303     noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1304     {
1305         return call(j, std::forward<T>(val), priority_tag<1> {});
1306     }
1307 };
1308 
1309 struct from_json_fn
1310 {
1311   private:
1312     template<typename BasicJsonType, typename T>
callnlohmann::detail::from_json_fn1313     auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const
1314     noexcept(noexcept(from_json(j, val)))
1315     -> decltype(from_json(j, val), void())
1316     {
1317         return from_json(j, val);
1318     }
1319 
1320     template<typename BasicJsonType, typename T>
callnlohmann::detail::from_json_fn1321     void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1322     {
1323         static_assert(sizeof(BasicJsonType) == 0,
1324                       "could not find from_json() method in T's namespace");
1325     }
1326 
1327   public:
1328     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn1329     void operator()(const BasicJsonType& j, T& val) const
1330     noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1331     {
1332         return call(j, val, priority_tag<1> {});
1333     }
1334 };
1335 
1336 // taken from ranges-v3
1337 template<typename T>
1338 struct static_const
1339 {
1340     static constexpr T value{};
1341 };
1342 
1343 template<typename T>
1344 constexpr T static_const<T>::value;
1345 
1346 ////////////////////
1347 // input adapters //
1348 ////////////////////
1349 
1350 /*!
1351 @brief abstract input adapter interface
1352 Produces a stream of std::char_traits<char>::int_type characters from a
1353 std::istream, a buffer, or some other input type.  Accepts the return of exactly
1354 one non-EOF character for future input.  The int_type characters returned
1355 consist of all valid char values as positive values (typically unsigned char),
1356 plus an EOF value outside that range, specified by the value of the function
1357 std::char_traits<char>::eof().  This value is typically -1, but could be any
1358 arbitrary value which is not a valid char value.
1359 */
1360 struct input_adapter_protocol
1361 {
1362     /// get a character [0,255] or std::char_traits<char>::eof().
1363     virtual std::char_traits<char>::int_type get_character() = 0;
1364     /// restore the last non-eof() character to input
1365     virtual void unget_character() = 0;
1366     virtual ~input_adapter_protocol() = default;
1367 };
1368 
1369 /// a type to simplify interfaces
1370 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1371 
1372 /*!
1373 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
1374 beginning of input. Does not support changing the underlying std::streambuf
1375 in mid-input. Maintains underlying std::istream and std::streambuf to support
1376 subsequent use of standard std::istream operations to process any input
1377 characters following those used in parsing the JSON input.  Clears the
1378 std::istream flags; any input errors (e.g., EOF) will be detected by the first
1379 subsequent call for input from the std::istream.
1380 */
1381 class input_stream_adapter : public input_adapter_protocol
1382 {
1383   public:
~input_stream_adapter()1384     ~input_stream_adapter() override
1385     {
1386         // clear stream flags; we use underlying streambuf I/O, do not
1387         // maintain ifstream flags
1388         is.clear();
1389     }
1390 
input_stream_adapter(std::istream & i)1391     explicit input_stream_adapter(std::istream& i)
1392         : is(i), sb(*i.rdbuf())
1393     {
1394         // ignore Byte Order Mark at start of input
1395         std::char_traits<char>::int_type c;
1396         if ((c = get_character()) == 0xEF)
1397         {
1398             if ((c = get_character()) == 0xBB)
1399             {
1400                 if ((c = get_character()) == 0xBF)
1401                 {
1402                     return; // Ignore BOM
1403                 }
1404                 else if (c != std::char_traits<char>::eof())
1405                 {
1406                     is.unget();
1407                 }
1408                 is.putback('\xBB');
1409             }
1410             else if (c != std::char_traits<char>::eof())
1411             {
1412                 is.unget();
1413             }
1414             is.putback('\xEF');
1415         }
1416         else if (c != std::char_traits<char>::eof())
1417         {
1418             is.unget(); // Not BOM. Process as usual.
1419         }
1420     }
1421 
1422     // delete because of pointer members
1423     input_stream_adapter(const input_stream_adapter&) = delete;
1424     input_stream_adapter& operator=(input_stream_adapter&) = delete;
1425 
1426     // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1427     // ensure that std::char_traits<char>::eof() and the character 0xff do not
1428     // end up as the same value, eg. 0xffffffff.
get_character()1429     std::char_traits<char>::int_type get_character() override
1430     {
1431         return sb.sbumpc();
1432     }
1433 
unget_character()1434     void unget_character() override
1435     {
1436         sb.sungetc();  // is.unget() avoided for performance
1437     }
1438 
1439   private:
1440     /// the associated input stream
1441     std::istream& is;
1442     std::streambuf& sb;
1443 };
1444 
1445 /// input adapter for buffer input
1446 class input_buffer_adapter : public input_adapter_protocol
1447 {
1448   public:
input_buffer_adapter(const char * b,const std::size_t l)1449     input_buffer_adapter(const char* b, const std::size_t l)
1450         : cursor(b), limit(b + l), start(b)
1451     {
1452         // skip byte order mark
1453         if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF')
1454         {
1455             cursor += 3;
1456         }
1457     }
1458 
1459     // delete because of pointer members
1460     input_buffer_adapter(const input_buffer_adapter&) = delete;
1461     input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
1462 
get_character()1463     std::char_traits<char>::int_type get_character() noexcept override
1464     {
1465         if (JSON_LIKELY(cursor < limit))
1466         {
1467             return std::char_traits<char>::to_int_type(*(cursor++));
1468         }
1469 
1470         return std::char_traits<char>::eof();
1471     }
1472 
unget_character()1473     void unget_character() noexcept override
1474     {
1475         if (JSON_LIKELY(cursor > start))
1476         {
1477             --cursor;
1478         }
1479     }
1480 
1481   private:
1482     /// pointer to the current character
1483     const char* cursor;
1484     /// pointer past the last character
1485     const char* limit;
1486     /// pointer to the first character
1487     const char* start;
1488 };
1489 
1490 class input_adapter
1491 {
1492   public:
1493     // native support
1494 
1495     /// input adapter for input stream
input_adapter(std::istream & i)1496     input_adapter(std::istream& i)
1497         : ia(std::make_shared<input_stream_adapter>(i)) {}
1498 
1499     /// input adapter for input stream
input_adapter(std::istream && i)1500     input_adapter(std::istream&& i)
1501         : ia(std::make_shared<input_stream_adapter>(i)) {}
1502 
1503     /// input adapter for buffer
1504     template<typename CharT,
1505              typename std::enable_if<
1506                  std::is_pointer<CharT>::value and
1507                  std::is_integral<
1508                      typename std::remove_pointer<CharT>::type>::value and
1509                  sizeof(typename std::remove_pointer<CharT>::type) == 1,
1510                  int>::type = 0>
input_adapter(CharT b,std::size_t l)1511     input_adapter(CharT b, std::size_t l)
1512         : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
1513 
1514     // derived support
1515 
1516     /// input adapter for string literal
1517     template<typename CharT,
1518              typename std::enable_if<
1519                  std::is_pointer<CharT>::value and
1520                  std::is_integral<
1521                      typename std::remove_pointer<CharT>::type>::value and
1522                  sizeof(typename std::remove_pointer<CharT>::type) == 1,
1523                  int>::type = 0>
input_adapter(CharT b)1524     input_adapter(CharT b)
1525         : input_adapter(reinterpret_cast<const char*>(b),
1526                         std::strlen(reinterpret_cast<const char*>(b))) {}
1527 
1528     /// input adapter for iterator range with contiguous storage
1529     template<class IteratorType,
1530              typename std::enable_if<
1531                  std::is_same<typename std::iterator_traits<IteratorType>::iterator_category,
1532                               std::random_access_iterator_tag>::value,
1533                  int>::type = 0>
input_adapter(IteratorType first,IteratorType last)1534     input_adapter(IteratorType first, IteratorType last)
1535     {
1536         // assertion to check that the iterator range is indeed contiguous,
1537         // see http://stackoverflow.com/a/35008842/266378 for more discussion
1538         assert(std::accumulate(
1539                    first, last, std::pair<bool, int>(true, 0),
1540                    [&first](std::pair<bool, int> res, decltype(*first) val)
1541         {
1542             res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1543             return res;
1544         }).first);
1545 
1546         // assertion to check that each element is 1 byte long
1547         static_assert(
1548             sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
1549             "each element in the iterator range must have the size of 1 byte");
1550 
1551         const auto len = static_cast<size_t>(std::distance(first, last));
1552         if (JSON_LIKELY(len > 0))
1553         {
1554             // there is at least one element: use the address of first
1555             ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
1556         }
1557         else
1558         {
1559             // the address of first cannot be used: use nullptr
1560             ia = std::make_shared<input_buffer_adapter>(nullptr, len);
1561         }
1562     }
1563 
1564     /// input adapter for array
1565     template<class T, std::size_t N>
input_adapter(T (& array)[N])1566     input_adapter(T (&array)[N])
1567         : input_adapter(std::begin(array), std::end(array)) {}
1568 
1569     /// input adapter for contiguous container
1570     template <
1571         class ContiguousContainer,
1572         typename std::enable_if <
1573             not std::is_pointer<ContiguousContainer>::value and
1574             std::is_base_of<std::random_access_iterator_tag,
1575                             typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1576             int >::type = 0 >
input_adapter(const ContiguousContainer & c)1577     input_adapter(const ContiguousContainer& c)
1578         : input_adapter(std::begin(c), std::end(c)) {}
1579 
operator input_adapter_t()1580     operator input_adapter_t()
1581     {
1582         return ia;
1583     }
1584 
1585   private:
1586     /// the actual adapter
1587     input_adapter_t ia = nullptr;
1588 };
1589 
1590 //////////////////////
1591 // lexer and parser //
1592 //////////////////////
1593 
1594 /*!
1595 @brief lexical analysis
1596 This class organizes the lexical analysis during JSON deserialization.
1597 */
1598 template<typename BasicJsonType>
1599 class lexer
1600 {
1601     using number_integer_t = typename BasicJsonType::number_integer_t;
1602     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
1603     using number_float_t = typename BasicJsonType::number_float_t;
1604 
1605   public:
1606     /// token types for the parser
1607     enum class token_type
1608     {
1609         uninitialized,    ///< indicating the scanner is uninitialized
1610         literal_true,     ///< the `true` literal
1611         literal_false,    ///< the `false` literal
1612         literal_null,     ///< the `null` literal
1613         value_string,     ///< a string -- use get_string() for actual value
1614         value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
1615         value_integer,    ///< a signed integer -- use get_number_integer() for actual value
1616         value_float,      ///< an floating point number -- use get_number_float() for actual value
1617         begin_array,      ///< the character for array begin `[`
1618         begin_object,     ///< the character for object begin `{`
1619         end_array,        ///< the character for array end `]`
1620         end_object,       ///< the character for object end `}`
1621         name_separator,   ///< the name separator `:`
1622         value_separator,  ///< the value separator `,`
1623         parse_error,      ///< indicating a parse error
1624         end_of_input,     ///< indicating the end of the input buffer
1625         literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
1626     };
1627 
1628     /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)1629     static const char* token_type_name(const token_type t) noexcept
1630     {
1631         switch (t)
1632         {
1633             case token_type::uninitialized:
1634                 return "<uninitialized>";
1635             case token_type::literal_true:
1636                 return "true literal";
1637             case token_type::literal_false:
1638                 return "false literal";
1639             case token_type::literal_null:
1640                 return "null literal";
1641             case token_type::value_string:
1642                 return "string literal";
1643             case lexer::token_type::value_unsigned:
1644             case lexer::token_type::value_integer:
1645             case lexer::token_type::value_float:
1646                 return "number literal";
1647             case token_type::begin_array:
1648                 return "'['";
1649             case token_type::begin_object:
1650                 return "'{'";
1651             case token_type::end_array:
1652                 return "']'";
1653             case token_type::end_object:
1654                 return "'}'";
1655             case token_type::name_separator:
1656                 return "':'";
1657             case token_type::value_separator:
1658                 return "','";
1659             case token_type::parse_error:
1660                 return "<parse error>";
1661             case token_type::end_of_input:
1662                 return "end of input";
1663             case token_type::literal_or_value:
1664                 return "'[', '{', or a literal";
1665             default: // catch non-enum values
1666                 return "unknown token"; // LCOV_EXCL_LINE
1667         }
1668     }
1669 
lexer(detail::input_adapter_t adapter)1670     explicit lexer(detail::input_adapter_t adapter)
1671         : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1672 
1673     // delete because of pointer members
1674     lexer(const lexer&) = delete;
1675     lexer& operator=(lexer&) = delete;
1676 
1677   private:
1678     /////////////////////
1679     // locales
1680     /////////////////////
1681 
1682     /// return the locale-dependent decimal point
get_decimal_point()1683     static char get_decimal_point() noexcept
1684     {
1685         const auto loc = localeconv();
1686         assert(loc != nullptr);
1687         return (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
1688     }
1689 
1690     /////////////////////
1691     // scan functions
1692     /////////////////////
1693 
1694     /*!
1695     @brief get codepoint from 4 hex characters following `\u`
1696     For input "\u c1 c2 c3 c4" the codepoint is:
1697       (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
1698     = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
1699     Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
1700     must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
1701     conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
1702     between the ASCII value of the character and the desired integer value.
1703     @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
1704             non-hex character)
1705     */
get_codepoint()1706     int get_codepoint()
1707     {
1708         // this function only makes sense after reading `\u`
1709         assert(current == 'u');
1710         int codepoint = 0;
1711 
1712         const auto factors = { 12, 8, 4, 0 };
1713         for (const auto factor : factors)
1714         {
1715             get();
1716 
1717             if (current >= '0' and current <= '9')
1718             {
1719                 codepoint += ((current - 0x30) << factor);
1720             }
1721             else if (current >= 'A' and current <= 'F')
1722             {
1723                 codepoint += ((current - 0x37) << factor);
1724             }
1725             else if (current >= 'a' and current <= 'f')
1726             {
1727                 codepoint += ((current - 0x57) << factor);
1728             }
1729             else
1730             {
1731                 return -1;
1732             }
1733         }
1734 
1735         assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
1736         return codepoint;
1737     }
1738 
1739     /*!
1740     @brief check if the next byte(s) are inside a given range
1741     Adds the current byte and, for each passed range, reads a new byte and
1742     checks if it is inside the range. If a violation was detected, set up an
1743     error message and return false. Otherwise, return true.
1744     @return true if and only if no range violation was detected
1745     */
next_byte_in_range(std::initializer_list<int> ranges)1746     bool next_byte_in_range(std::initializer_list<int> ranges)
1747     {
1748         assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
1749         add(current);
1750 
1751         for (auto range = ranges.begin(); range != ranges.end(); ++range)
1752         {
1753             get();
1754             if (JSON_LIKELY(*range <= current and current <= *(++range)))
1755             {
1756                 add(current);
1757             }
1758             else
1759             {
1760                 error_message = "invalid string: ill-formed UTF-8 byte";
1761                 return false;
1762             }
1763         }
1764 
1765         return true;
1766     }
1767 
1768     /*!
1769     @brief scan a string literal
1770     This function scans a string according to Sect. 7 of RFC 7159. While
1771     scanning, bytes are escaped and copied into buffer yytext. Then the function
1772     returns successfully, yytext is *not* null-terminated (as it may contain \0
1773     bytes), and yytext.size() is the number of bytes in the string.
1774     @return token_type::value_string if string could be successfully scanned,
1775             token_type::parse_error otherwise
1776     @note In case of errors, variable error_message contains a textual
1777           description.
1778     */
scan_string()1779     token_type scan_string()
1780     {
1781         // reset yytext (ignore opening quote)
1782         reset();
1783 
1784         // we entered the function by reading an open quote
1785         assert(current == '\"');
1786 
1787         while (true)
1788         {
1789             // get next character
1790             switch (get())
1791             {
1792                 // end of file while parsing string
1793                 case std::char_traits<char>::eof():
1794                 {
1795                     error_message = "invalid string: missing closing quote";
1796                     return token_type::parse_error;
1797                 }
1798 
1799                 // closing quote
1800                 case '\"':
1801                 {
1802                     return token_type::value_string;
1803                 }
1804 
1805                 // escapes
1806                 case '\\':
1807                 {
1808                     switch (get())
1809                     {
1810                         // quotation mark
1811                         case '\"':
1812                             add('\"');
1813                             break;
1814                         // reverse solidus
1815                         case '\\':
1816                             add('\\');
1817                             break;
1818                         // solidus
1819                         case '/':
1820                             add('/');
1821                             break;
1822                         // backspace
1823                         case 'b':
1824                             add('\b');
1825                             break;
1826                         // form feed
1827                         case 'f':
1828                             add('\f');
1829                             break;
1830                         // line feed
1831                         case 'n':
1832                             add('\n');
1833                             break;
1834                         // carriage return
1835                         case 'r':
1836                             add('\r');
1837                             break;
1838                         // tab
1839                         case 't':
1840                             add('\t');
1841                             break;
1842 
1843                         // unicode escapes
1844                         case 'u':
1845                         {
1846                             int codepoint;
1847                             const int codepoint1 = get_codepoint();
1848 
1849                             if (JSON_UNLIKELY(codepoint1 == -1))
1850                             {
1851                                 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
1852                                 return token_type::parse_error;
1853                             }
1854 
1855                             // check if code point is a high surrogate
1856                             if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
1857                             {
1858                                 // expect next \uxxxx entry
1859                                 if (JSON_LIKELY(get() == '\\' and get() == 'u'))
1860                                 {
1861                                     const int codepoint2 = get_codepoint();
1862 
1863                                     if (JSON_UNLIKELY(codepoint2 == -1))
1864                                     {
1865                                         error_message = "invalid string: '\\u' must be followed by 4 hex digits";
1866                                         return token_type::parse_error;
1867                                     }
1868 
1869                                     // check if codepoint2 is a low surrogate
1870                                     if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
1871                                     {
1872                                         codepoint =
1873                                             // high surrogate occupies the most significant 22 bits
1874                                             (codepoint1 << 10)
1875                                             // low surrogate occupies the least significant 15 bits
1876                                             + codepoint2
1877                                             // there is still the 0xD800, 0xDC00 and 0x10000 noise
1878                                             // in the result so we have to subtract with:
1879                                             // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
1880                                             - 0x35FDC00;
1881                                     }
1882                                     else
1883                                     {
1884                                         error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1885                                         return token_type::parse_error;
1886                                     }
1887                                 }
1888                                 else
1889                                 {
1890                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1891                                     return token_type::parse_error;
1892                                 }
1893                             }
1894                             else
1895                             {
1896                                 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
1897                                 {
1898                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
1899                                     return token_type::parse_error;
1900                                 }
1901 
1902                                 // only work with first code point
1903                                 codepoint = codepoint1;
1904                             }
1905 
1906                             // result of the above calculation yields a proper codepoint
1907                             assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
1908 
1909                             // translate code point to bytes
1910                             if (codepoint < 0x80)
1911                             {
1912                                 // 1-byte characters: 0xxxxxxx (ASCII)
1913                                 add(codepoint);
1914                             }
1915                             else if (codepoint <= 0x7ff)
1916                             {
1917                                 // 2-byte characters: 110xxxxx 10xxxxxx
1918                                 add(0xC0 | (codepoint >> 6));
1919                                 add(0x80 | (codepoint & 0x3F));
1920                             }
1921                             else if (codepoint <= 0xffff)
1922                             {
1923                                 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
1924                                 add(0xE0 | (codepoint >> 12));
1925                                 add(0x80 | ((codepoint >> 6) & 0x3F));
1926                                 add(0x80 | (codepoint & 0x3F));
1927                             }
1928                             else
1929                             {
1930                                 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1931                                 add(0xF0 | (codepoint >> 18));
1932                                 add(0x80 | ((codepoint >> 12) & 0x3F));
1933                                 add(0x80 | ((codepoint >> 6) & 0x3F));
1934                                 add(0x80 | (codepoint & 0x3F));
1935                             }
1936 
1937                             break;
1938                         }
1939 
1940                         // other characters after escape
1941                         default:
1942                             error_message = "invalid string: forbidden character after backslash";
1943                             return token_type::parse_error;
1944                     }
1945 
1946                     break;
1947                 }
1948 
1949                 // invalid control characters
1950                 case 0x00:
1951                 case 0x01:
1952                 case 0x02:
1953                 case 0x03:
1954                 case 0x04:
1955                 case 0x05:
1956                 case 0x06:
1957                 case 0x07:
1958                 case 0x08:
1959                 case 0x09:
1960                 case 0x0a:
1961                 case 0x0b:
1962                 case 0x0c:
1963                 case 0x0d:
1964                 case 0x0e:
1965                 case 0x0f:
1966                 case 0x10:
1967                 case 0x11:
1968                 case 0x12:
1969                 case 0x13:
1970                 case 0x14:
1971                 case 0x15:
1972                 case 0x16:
1973                 case 0x17:
1974                 case 0x18:
1975                 case 0x19:
1976                 case 0x1a:
1977                 case 0x1b:
1978                 case 0x1c:
1979                 case 0x1d:
1980                 case 0x1e:
1981                 case 0x1f:
1982                 {
1983                     error_message = "invalid string: control character must be escaped";
1984                     return token_type::parse_error;
1985                 }
1986 
1987                 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
1988                 case 0x20:
1989                 case 0x21:
1990                 case 0x23:
1991                 case 0x24:
1992                 case 0x25:
1993                 case 0x26:
1994                 case 0x27:
1995                 case 0x28:
1996                 case 0x29:
1997                 case 0x2a:
1998                 case 0x2b:
1999                 case 0x2c:
2000                 case 0x2d:
2001                 case 0x2e:
2002                 case 0x2f:
2003                 case 0x30:
2004                 case 0x31:
2005                 case 0x32:
2006                 case 0x33:
2007                 case 0x34:
2008                 case 0x35:
2009                 case 0x36:
2010                 case 0x37:
2011                 case 0x38:
2012                 case 0x39:
2013                 case 0x3a:
2014                 case 0x3b:
2015                 case 0x3c:
2016                 case 0x3d:
2017                 case 0x3e:
2018                 case 0x3f:
2019                 case 0x40:
2020                 case 0x41:
2021                 case 0x42:
2022                 case 0x43:
2023                 case 0x44:
2024                 case 0x45:
2025                 case 0x46:
2026                 case 0x47:
2027                 case 0x48:
2028                 case 0x49:
2029                 case 0x4a:
2030                 case 0x4b:
2031                 case 0x4c:
2032                 case 0x4d:
2033                 case 0x4e:
2034                 case 0x4f:
2035                 case 0x50:
2036                 case 0x51:
2037                 case 0x52:
2038                 case 0x53:
2039                 case 0x54:
2040                 case 0x55:
2041                 case 0x56:
2042                 case 0x57:
2043                 case 0x58:
2044                 case 0x59:
2045                 case 0x5a:
2046                 case 0x5b:
2047                 case 0x5d:
2048                 case 0x5e:
2049                 case 0x5f:
2050                 case 0x60:
2051                 case 0x61:
2052                 case 0x62:
2053                 case 0x63:
2054                 case 0x64:
2055                 case 0x65:
2056                 case 0x66:
2057                 case 0x67:
2058                 case 0x68:
2059                 case 0x69:
2060                 case 0x6a:
2061                 case 0x6b:
2062                 case 0x6c:
2063                 case 0x6d:
2064                 case 0x6e:
2065                 case 0x6f:
2066                 case 0x70:
2067                 case 0x71:
2068                 case 0x72:
2069                 case 0x73:
2070                 case 0x74:
2071                 case 0x75:
2072                 case 0x76:
2073                 case 0x77:
2074                 case 0x78:
2075                 case 0x79:
2076                 case 0x7a:
2077                 case 0x7b:
2078                 case 0x7c:
2079                 case 0x7d:
2080                 case 0x7e:
2081                 case 0x7f:
2082                 {
2083                     add(current);
2084                     break;
2085                 }
2086 
2087                 // U+0080..U+07FF: bytes C2..DF 80..BF
2088                 case 0xc2:
2089                 case 0xc3:
2090                 case 0xc4:
2091                 case 0xc5:
2092                 case 0xc6:
2093                 case 0xc7:
2094                 case 0xc8:
2095                 case 0xc9:
2096                 case 0xca:
2097                 case 0xcb:
2098                 case 0xcc:
2099                 case 0xcd:
2100                 case 0xce:
2101                 case 0xcf:
2102                 case 0xd0:
2103                 case 0xd1:
2104                 case 0xd2:
2105                 case 0xd3:
2106                 case 0xd4:
2107                 case 0xd5:
2108                 case 0xd6:
2109                 case 0xd7:
2110                 case 0xd8:
2111                 case 0xd9:
2112                 case 0xda:
2113                 case 0xdb:
2114                 case 0xdc:
2115                 case 0xdd:
2116                 case 0xde:
2117                 case 0xdf:
2118                 {
2119                     if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2120                     {
2121                         return token_type::parse_error;
2122                     }
2123                     break;
2124                 }
2125 
2126                 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2127                 case 0xe0:
2128                 {
2129                     if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2130                     {
2131                         return token_type::parse_error;
2132                     }
2133                     break;
2134                 }
2135 
2136                 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2137                 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2138                 case 0xe1:
2139                 case 0xe2:
2140                 case 0xe3:
2141                 case 0xe4:
2142                 case 0xe5:
2143                 case 0xe6:
2144                 case 0xe7:
2145                 case 0xe8:
2146                 case 0xe9:
2147                 case 0xea:
2148                 case 0xeb:
2149                 case 0xec:
2150                 case 0xee:
2151                 case 0xef:
2152                 {
2153                     if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2154                     {
2155                         return token_type::parse_error;
2156                     }
2157                     break;
2158                 }
2159 
2160                 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2161                 case 0xed:
2162                 {
2163                     if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2164                     {
2165                         return token_type::parse_error;
2166                     }
2167                     break;
2168                 }
2169 
2170                 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2171                 case 0xf0:
2172                 {
2173                     if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2174                     {
2175                         return token_type::parse_error;
2176                     }
2177                     break;
2178                 }
2179 
2180                 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2181                 case 0xf1:
2182                 case 0xf2:
2183                 case 0xf3:
2184                 {
2185                     if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2186                     {
2187                         return token_type::parse_error;
2188                     }
2189                     break;
2190                 }
2191 
2192                 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2193                 case 0xf4:
2194                 {
2195                     if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2196                     {
2197                         return token_type::parse_error;
2198                     }
2199                     break;
2200                 }
2201 
2202                 // remaining bytes (80..C1 and F5..FF) are ill-formed
2203                 default:
2204                 {
2205                     error_message = "invalid string: ill-formed UTF-8 byte";
2206                     return token_type::parse_error;
2207                 }
2208             }
2209         }
2210     }
2211 
strtof(float & f,const char * str,char ** endptr)2212     static void strtof(float& f, const char* str, char** endptr) noexcept
2213     {
2214         f = std::strtof(str, endptr);
2215     }
2216 
strtof(double & f,const char * str,char ** endptr)2217     static void strtof(double& f, const char* str, char** endptr) noexcept
2218     {
2219         f = std::strtod(str, endptr);
2220     }
2221 
strtof(long double & f,const char * str,char ** endptr)2222     static void strtof(long double& f, const char* str, char** endptr) noexcept
2223     {
2224         f = std::strtold(str, endptr);
2225     }
2226 
2227     /*!
2228     @brief scan a number literal
2229     This function scans a string according to Sect. 6 of RFC 7159.
2230     The function is realized with a deterministic finite state machine derived
2231     from the grammar described in RFC 7159. Starting in state "init", the
2232     input is read and used to determined the next state. Only state "done"
2233     accepts the number. State "error" is a trap state to model errors. In the
2234     table below, "anything" means any character but the ones listed before.
2235     state    | 0        | 1-9      | e E      | +       | -       | .        | anything
2236     ---------|----------|----------|----------|---------|---------|----------|-----------
2237     init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
2238     minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
2239     zero     | done     | done     | exponent | done    | done    | decimal1 | done
2240     any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
2241     decimal1 | decimal2 | [error]  | [error]  | [error] | [error] | [error]  | [error]
2242     decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
2243     exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
2244     sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
2245     any2     | any2     | any2     | done     | done    | done    | done     | done
2246     The state machine is realized with one label per state (prefixed with
2247     "scan_number_") and `goto` statements between them. The state machine
2248     contains cycles, but any cycle can be left when EOF is read. Therefore,
2249     the function is guaranteed to terminate.
2250     During scanning, the read bytes are stored in yytext. This string is
2251     then converted to a signed integer, an unsigned integer, or a
2252     floating-point number.
2253     @return token_type::value_unsigned, token_type::value_integer, or
2254             token_type::value_float if number could be successfully scanned,
2255             token_type::parse_error otherwise
2256     @note The scanner is independent of the current locale. Internally, the
2257           locale's decimal point is used instead of `.` to work with the
2258           locale-dependent converters.
2259     */
scan_number()2260     token_type scan_number()
2261     {
2262         // reset yytext to store the number's bytes
2263         reset();
2264 
2265         // the type of the parsed number; initially set to unsigned; will be
2266         // changed if minus sign, decimal point or exponent is read
2267         token_type number_type = token_type::value_unsigned;
2268 
2269         // state (init): we just found out we need to scan a number
2270         switch (current)
2271         {
2272             case '-':
2273             {
2274                 add(current);
2275                 goto scan_number_minus;
2276             }
2277 
2278             case '0':
2279             {
2280                 add(current);
2281                 goto scan_number_zero;
2282             }
2283 
2284             case '1':
2285             case '2':
2286             case '3':
2287             case '4':
2288             case '5':
2289             case '6':
2290             case '7':
2291             case '8':
2292             case '9':
2293             {
2294                 add(current);
2295                 goto scan_number_any1;
2296             }
2297 
2298             default:
2299             {
2300                 // all other characters are rejected outside scan_number()
2301                 assert(false); // LCOV_EXCL_LINE
2302             }
2303         }
2304 
2305 scan_number_minus:
2306         // state: we just parsed a leading minus sign
2307         number_type = token_type::value_integer;
2308         switch (get())
2309         {
2310             case '0':
2311             {
2312                 add(current);
2313                 goto scan_number_zero;
2314             }
2315 
2316             case '1':
2317             case '2':
2318             case '3':
2319             case '4':
2320             case '5':
2321             case '6':
2322             case '7':
2323             case '8':
2324             case '9':
2325             {
2326                 add(current);
2327                 goto scan_number_any1;
2328             }
2329 
2330             default:
2331             {
2332                 error_message = "invalid number; expected digit after '-'";
2333                 return token_type::parse_error;
2334             }
2335         }
2336 
2337 scan_number_zero:
2338         // state: we just parse a zero (maybe with a leading minus sign)
2339         switch (get())
2340         {
2341             case '.':
2342             {
2343                 add(decimal_point_char);
2344                 goto scan_number_decimal1;
2345             }
2346 
2347             case 'e':
2348             case 'E':
2349             {
2350                 add(current);
2351                 goto scan_number_exponent;
2352             }
2353 
2354             default:
2355                 goto scan_number_done;
2356         }
2357 
2358 scan_number_any1:
2359         // state: we just parsed a number 0-9 (maybe with a leading minus sign)
2360         switch (get())
2361         {
2362             case '0':
2363             case '1':
2364             case '2':
2365             case '3':
2366             case '4':
2367             case '5':
2368             case '6':
2369             case '7':
2370             case '8':
2371             case '9':
2372             {
2373                 add(current);
2374                 goto scan_number_any1;
2375             }
2376 
2377             case '.':
2378             {
2379                 add(decimal_point_char);
2380                 goto scan_number_decimal1;
2381             }
2382 
2383             case 'e':
2384             case 'E':
2385             {
2386                 add(current);
2387                 goto scan_number_exponent;
2388             }
2389 
2390             default:
2391                 goto scan_number_done;
2392         }
2393 
2394 scan_number_decimal1:
2395         // state: we just parsed a decimal point
2396         number_type = token_type::value_float;
2397         switch (get())
2398         {
2399             case '0':
2400             case '1':
2401             case '2':
2402             case '3':
2403             case '4':
2404             case '5':
2405             case '6':
2406             case '7':
2407             case '8':
2408             case '9':
2409             {
2410                 add(current);
2411                 goto scan_number_decimal2;
2412             }
2413 
2414             default:
2415             {
2416                 error_message = "invalid number; expected digit after '.'";
2417                 return token_type::parse_error;
2418             }
2419         }
2420 
2421 scan_number_decimal2:
2422         // we just parsed at least one number after a decimal point
2423         switch (get())
2424         {
2425             case '0':
2426             case '1':
2427             case '2':
2428             case '3':
2429             case '4':
2430             case '5':
2431             case '6':
2432             case '7':
2433             case '8':
2434             case '9':
2435             {
2436                 add(current);
2437                 goto scan_number_decimal2;
2438             }
2439 
2440             case 'e':
2441             case 'E':
2442             {
2443                 add(current);
2444                 goto scan_number_exponent;
2445             }
2446 
2447             default:
2448                 goto scan_number_done;
2449         }
2450 
2451 scan_number_exponent:
2452         // we just parsed an exponent
2453         number_type = token_type::value_float;
2454         switch (get())
2455         {
2456             case '+':
2457             case '-':
2458             {
2459                 add(current);
2460                 goto scan_number_sign;
2461             }
2462 
2463             case '0':
2464             case '1':
2465             case '2':
2466             case '3':
2467             case '4':
2468             case '5':
2469             case '6':
2470             case '7':
2471             case '8':
2472             case '9':
2473             {
2474                 add(current);
2475                 goto scan_number_any2;
2476             }
2477 
2478             default:
2479             {
2480                 error_message =
2481                     "invalid number; expected '+', '-', or digit after exponent";
2482                 return token_type::parse_error;
2483             }
2484         }
2485 
2486 scan_number_sign:
2487         // we just parsed an exponent sign
2488         switch (get())
2489         {
2490             case '0':
2491             case '1':
2492             case '2':
2493             case '3':
2494             case '4':
2495             case '5':
2496             case '6':
2497             case '7':
2498             case '8':
2499             case '9':
2500             {
2501                 add(current);
2502                 goto scan_number_any2;
2503             }
2504 
2505             default:
2506             {
2507                 error_message = "invalid number; expected digit after exponent sign";
2508                 return token_type::parse_error;
2509             }
2510         }
2511 
2512 scan_number_any2:
2513         // we just parsed a number after the exponent or exponent sign
2514         switch (get())
2515         {
2516             case '0':
2517             case '1':
2518             case '2':
2519             case '3':
2520             case '4':
2521             case '5':
2522             case '6':
2523             case '7':
2524             case '8':
2525             case '9':
2526             {
2527                 add(current);
2528                 goto scan_number_any2;
2529             }
2530 
2531             default:
2532                 goto scan_number_done;
2533         }
2534 
2535 scan_number_done:
2536         // unget the character after the number (we only read it to know that
2537         // we are done scanning a number)
2538         unget();
2539 
2540         char* endptr = nullptr;
2541         errno = 0;
2542 
2543         // try to parse integers first and fall back to floats
2544         if (number_type == token_type::value_unsigned)
2545         {
2546             const auto x = std::strtoull(yytext.data(), &endptr, 10);
2547 
2548             // we checked the number format before
2549             assert(endptr == yytext.data() + yytext.size());
2550 
2551             if (errno == 0)
2552             {
2553                 value_unsigned = static_cast<number_unsigned_t>(x);
2554                 if (value_unsigned == x)
2555                 {
2556                     return token_type::value_unsigned;
2557                 }
2558             }
2559         }
2560         else if (number_type == token_type::value_integer)
2561         {
2562             const auto x = std::strtoll(yytext.data(), &endptr, 10);
2563 
2564             // we checked the number format before
2565             assert(endptr == yytext.data() + yytext.size());
2566 
2567             if (errno == 0)
2568             {
2569                 value_integer = static_cast<number_integer_t>(x);
2570                 if (value_integer == x)
2571                 {
2572                     return token_type::value_integer;
2573                 }
2574             }
2575         }
2576 
2577         // this code is reached if we parse a floating-point number or if an
2578         // integer conversion above failed
2579         strtof(value_float, yytext.data(), &endptr);
2580 
2581         // we checked the number format before
2582         assert(endptr == yytext.data() + yytext.size());
2583 
2584         return token_type::value_float;
2585     }
2586 
2587     /*!
2588     @param[in] literal_text  the literal text to expect
2589     @param[in] length        the length of the passed literal text
2590     @param[in] return_type   the token type to return on success
2591     */
scan_literal(const char * literal_text,const std::size_t length,token_type return_type)2592     token_type scan_literal(const char* literal_text, const std::size_t length,
2593                             token_type return_type)
2594     {
2595         assert(current == literal_text[0]);
2596         for (std::size_t i = 1; i < length; ++i)
2597         {
2598             if (JSON_UNLIKELY(get() != literal_text[i]))
2599             {
2600                 error_message = "invalid literal";
2601                 return token_type::parse_error;
2602             }
2603         }
2604         return return_type;
2605     }
2606 
2607     /////////////////////
2608     // input management
2609     /////////////////////
2610 
2611     /// reset yytext; current character is beginning of token
reset()2612     void reset() noexcept
2613     {
2614         yytext.clear();
2615         token_string.clear();
2616         token_string.push_back(std::char_traits<char>::to_char_type(current));
2617     }
2618 
2619     /*
2620     @brief get next character from the input
2621     This function provides the interface to the used input adapter. It does
2622     not throw in case the input reached EOF, but returns a
2623     `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
2624     for use in error messages.
2625     @return character read from the input
2626     */
get()2627     std::char_traits<char>::int_type get()
2628     {
2629         ++chars_read;
2630         current = ia->get_character();
2631         if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2632         {
2633             token_string.push_back(std::char_traits<char>::to_char_type(current));
2634         }
2635         return current;
2636     }
2637 
2638     /// unget current character (return it again on next get)
unget()2639     void unget()
2640     {
2641         --chars_read;
2642         if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2643         {
2644             ia->unget_character();
2645             assert(token_string.size() != 0);
2646             token_string.pop_back();
2647         }
2648     }
2649 
2650     /// add a character to yytext
add(int c)2651     void add(int c)
2652     {
2653         yytext.push_back(std::char_traits<char>::to_char_type(c));
2654     }
2655 
2656   public:
2657     /////////////////////
2658     // value getters
2659     /////////////////////
2660 
2661     /// return integer value
get_number_integer() const2662     constexpr number_integer_t get_number_integer() const noexcept
2663     {
2664         return value_integer;
2665     }
2666 
2667     /// return unsigned integer value
get_number_unsigned() const2668     constexpr number_unsigned_t get_number_unsigned() const noexcept
2669     {
2670         return value_unsigned;
2671     }
2672 
2673     /// return floating-point value
get_number_float() const2674     constexpr number_float_t get_number_float() const noexcept
2675     {
2676         return value_float;
2677     }
2678 
2679     /// return current string value (implicitly resets the token; useful only once)
move_string()2680     std::string move_string()
2681     {
2682         return std::move(yytext);
2683     }
2684 
2685     /////////////////////
2686     // diagnostics
2687     /////////////////////
2688 
2689     /// return position of last read token
get_position() const2690     constexpr std::size_t get_position() const noexcept
2691     {
2692         return chars_read;
2693     }
2694 
2695     /// return the last read token (for errors only).  Will never contain EOF
2696     /// (an arbitrary value that is not a valid char value, often -1), because
2697     /// 255 may legitimately occur.  May contain NUL, which should be escaped.
get_token_string() const2698     std::string get_token_string() const
2699     {
2700         // escape control characters
2701         std::string result;
2702         for (auto c : token_string)
2703         {
2704             if ('\x00' <= c and c <= '\x1f')
2705             {
2706                 // escape control characters
2707                 std::stringstream ss;
2708                 ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
2709                    << std::hex << static_cast<int>(c) << ">";
2710                 result += ss.str();
2711             }
2712             else
2713             {
2714                 // add character as is
2715                 result.push_back(c);
2716             }
2717         }
2718 
2719         return result;
2720     }
2721 
2722     /// return syntax error message
get_error_message() const2723     constexpr const char* get_error_message() const noexcept
2724     {
2725         return error_message;
2726     }
2727 
2728     /////////////////////
2729     // actual scanner
2730     /////////////////////
2731 
scan()2732     token_type scan()
2733     {
2734         // read next character and ignore whitespace
2735         do
2736         {
2737             get();
2738         }
2739         while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
2740 
2741         switch (current)
2742         {
2743             // structural characters
2744             case '[':
2745                 return token_type::begin_array;
2746             case ']':
2747                 return token_type::end_array;
2748             case '{':
2749                 return token_type::begin_object;
2750             case '}':
2751                 return token_type::end_object;
2752             case ':':
2753                 return token_type::name_separator;
2754             case ',':
2755                 return token_type::value_separator;
2756 
2757             // literals
2758             case 't':
2759                 return scan_literal("true", 4, token_type::literal_true);
2760             case 'f':
2761                 return scan_literal("false", 5, token_type::literal_false);
2762             case 'n':
2763                 return scan_literal("null", 4, token_type::literal_null);
2764 
2765             // string
2766             case '\"':
2767                 return scan_string();
2768 
2769             // number
2770             case '-':
2771             case '0':
2772             case '1':
2773             case '2':
2774             case '3':
2775             case '4':
2776             case '5':
2777             case '6':
2778             case '7':
2779             case '8':
2780             case '9':
2781                 return scan_number();
2782 
2783             // end of input (the null byte is needed when parsing from
2784             // string literals)
2785             case '\0':
2786             case std::char_traits<char>::eof():
2787                 return token_type::end_of_input;
2788 
2789             // error
2790             default:
2791                 error_message = "invalid literal";
2792                 return token_type::parse_error;
2793         }
2794     }
2795 
2796   private:
2797     /// input adapter
2798     detail::input_adapter_t ia = nullptr;
2799 
2800     /// the current character
2801     std::char_traits<char>::int_type current = std::char_traits<char>::eof();
2802 
2803     /// the number of characters read
2804     std::size_t chars_read = 0;
2805 
2806     /// raw input token string (for error messages)
2807     std::vector<char> token_string { };
2808 
2809     /// buffer for variable-length tokens (numbers, strings)
2810     std::string yytext { };
2811 
2812     /// a description of occurred lexer errors
2813     const char* error_message = "";
2814 
2815     // number values
2816     number_integer_t value_integer = 0;
2817     number_unsigned_t value_unsigned = 0;
2818     number_float_t value_float = 0;
2819 
2820     /// the decimal point
2821     const char decimal_point_char = '.';
2822 };
2823 
2824 /*!
2825 @brief syntax analysis
2826 This class implements a recursive decent parser.
2827 */
2828 template<typename BasicJsonType>
2829 class parser
2830 {
2831     using number_integer_t = typename BasicJsonType::number_integer_t;
2832     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2833     using number_float_t = typename BasicJsonType::number_float_t;
2834     using lexer_t = lexer<BasicJsonType>;
2835     using token_type = typename lexer_t::token_type;
2836 
2837   public:
2838     enum class parse_event_t : uint8_t
2839     {
2840         /// the parser read `{` and started to process a JSON object
2841         object_start,
2842         /// the parser read `}` and finished processing a JSON object
2843         object_end,
2844         /// the parser read `[` and started to process a JSON array
2845         array_start,
2846         /// the parser read `]` and finished processing a JSON array
2847         array_end,
2848         /// the parser read a key of a value in an object
2849         key,
2850         /// the parser finished reading a JSON value
2851         value
2852     };
2853 
2854     using parser_callback_t =
2855         std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
2856 
2857     /// a parser reading from an input adapter
parser(detail::input_adapter_t adapter,const parser_callback_t cb=nullptr,const bool allow_exceptions_=true)2858     explicit parser(detail::input_adapter_t adapter,
2859                     const parser_callback_t cb = nullptr,
2860                     const bool allow_exceptions_ = true)
2861         : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
2862     {}
2863 
2864     /*!
2865     @brief public parser interface
2866     @param[in] strict      whether to expect the last token to be EOF
2867     @param[in,out] result  parsed JSON value
2868     @throw parse_error.101 in case of an unexpected token
2869     @throw parse_error.102 if to_unicode fails or surrogate error
2870     @throw parse_error.103 if to_unicode fails
2871     */
parse(const bool strict,BasicJsonType & result)2872     void parse(const bool strict, BasicJsonType& result)
2873     {
2874         // read first token
2875         get_token();
2876 
2877         parse_internal(true, result);
2878         result.assert_invariant();
2879 
2880         // in strict mode, input must be completely read
2881         if (strict)
2882         {
2883             get_token();
2884             expect(token_type::end_of_input);
2885         }
2886 
2887         // in case of an error, return discarded value
2888         if (errored)
2889         {
2890             result = value_t::discarded;
2891             return;
2892         }
2893 
2894         // set top-level value to null if it was discarded by the callback
2895         // function
2896         if (result.is_discarded())
2897         {
2898             result = nullptr;
2899         }
2900     }
2901 
2902     /*!
2903     @brief public accept interface
2904     @param[in] strict  whether to expect the last token to be EOF
2905     @return whether the input is a proper JSON text
2906     */
accept(const bool strict=true)2907     bool accept(const bool strict = true)
2908     {
2909         // read first token
2910         get_token();
2911 
2912         if (not accept_internal())
2913         {
2914             return false;
2915         }
2916 
2917         // strict => last token must be EOF
2918         return not strict or (get_token() == token_type::end_of_input);
2919     }
2920 
2921   private:
2922     /*!
2923     @brief the actual parser
2924     @throw parse_error.101 in case of an unexpected token
2925     @throw parse_error.102 if to_unicode fails or surrogate error
2926     @throw parse_error.103 if to_unicode fails
2927     */
parse_internal(bool keep,BasicJsonType & result)2928     void parse_internal(bool keep, BasicJsonType& result)
2929     {
2930         // never parse after a parse error was detected
2931         assert(not errored);
2932 
2933         // start with a discarded value
2934         if (not result.is_discarded())
2935         {
2936             result.m_value.destroy(result.m_type);
2937             result.m_type = value_t::discarded;
2938         }
2939 
2940         switch (last_token)
2941         {
2942             case token_type::begin_object:
2943             {
2944                 if (keep)
2945                 {
2946                     if (callback)
2947                     {
2948                         keep = callback(depth++, parse_event_t::object_start, result);
2949                     }
2950 
2951                     if (not callback or keep)
2952                     {
2953                         // explicitly set result to object to cope with {}
2954                         result.m_type = value_t::object;
2955                         result.m_value = value_t::object;
2956                     }
2957                 }
2958 
2959                 // read next token
2960                 get_token();
2961 
2962                 // closing } -> we are done
2963                 if (last_token == token_type::end_object)
2964                 {
2965                     if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
2966                     {
2967                         result.m_value.destroy(result.m_type);
2968                         result.m_type = value_t::discarded;
2969                     }
2970                     break;
2971                 }
2972 
2973                 // parse values
2974                 std::string key;
2975                 BasicJsonType value;
2976                 while (true)
2977                 {
2978                     // store key
2979                     if (not expect(token_type::value_string))
2980                     {
2981                         return;
2982                     }
2983                     key = m_lexer.move_string();
2984 
2985                     bool keep_tag = false;
2986                     if (keep)
2987                     {
2988                         if (callback)
2989                         {
2990                             BasicJsonType k(key);
2991                             keep_tag = callback(depth, parse_event_t::key, k);
2992                         }
2993                         else
2994                         {
2995                             keep_tag = true;
2996                         }
2997                     }
2998 
2999                     // parse separator (:)
3000                     get_token();
3001                     if (not expect(token_type::name_separator))
3002                     {
3003                         return;
3004                     }
3005 
3006                     // parse and add value
3007                     get_token();
3008                     value.m_value.destroy(value.m_type);
3009                     value.m_type = value_t::discarded;
3010                     parse_internal(keep, value);
3011 
3012                     if (JSON_UNLIKELY(errored))
3013                     {
3014                         return;
3015                     }
3016 
3017                     if (keep and keep_tag and not value.is_discarded())
3018                     {
3019                         result.m_value.object->emplace(std::move(key), std::move(value));
3020                     }
3021 
3022                     // comma -> next value
3023                     get_token();
3024                     if (last_token == token_type::value_separator)
3025                     {
3026                         get_token();
3027                         continue;
3028                     }
3029 
3030                     // closing }
3031                     if (not expect(token_type::end_object))
3032                     {
3033                         return;
3034                     }
3035                     break;
3036                 }
3037 
3038                 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3039                 {
3040                     result.m_value.destroy(result.m_type);
3041                     result.m_type = value_t::discarded;
3042                 }
3043                 break;
3044             }
3045 
3046             case token_type::begin_array:
3047             {
3048                 if (keep)
3049                 {
3050                     if (callback)
3051                     {
3052                         keep = callback(depth++, parse_event_t::array_start, result);
3053                     }
3054 
3055                     if (not callback or keep)
3056                     {
3057                         // explicitly set result to array to cope with []
3058                         result.m_type = value_t::array;
3059                         result.m_value = value_t::array;
3060                     }
3061                 }
3062 
3063                 // read next token
3064                 get_token();
3065 
3066                 // closing ] -> we are done
3067                 if (last_token == token_type::end_array)
3068                 {
3069                     if (callback and not callback(--depth, parse_event_t::array_end, result))
3070                     {
3071                         result.m_value.destroy(result.m_type);
3072                         result.m_type = value_t::discarded;
3073                     }
3074                     break;
3075                 }
3076 
3077                 // parse values
3078                 BasicJsonType value;
3079                 while (true)
3080                 {
3081                     // parse value
3082                     value.m_value.destroy(value.m_type);
3083                     value.m_type = value_t::discarded;
3084                     parse_internal(keep, value);
3085 
3086                     if (JSON_UNLIKELY(errored))
3087                     {
3088                         return;
3089                     }
3090 
3091                     if (keep and not value.is_discarded())
3092                     {
3093                         result.m_value.array->push_back(std::move(value));
3094                     }
3095 
3096                     // comma -> next value
3097                     get_token();
3098                     if (last_token == token_type::value_separator)
3099                     {
3100                         get_token();
3101                         continue;
3102                     }
3103 
3104                     // closing ]
3105                     if (not expect(token_type::end_array))
3106                     {
3107                         return;
3108                     }
3109                     break;
3110                 }
3111 
3112                 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
3113                 {
3114                     result.m_value.destroy(result.m_type);
3115                     result.m_type = value_t::discarded;
3116                 }
3117                 break;
3118             }
3119 
3120             case token_type::literal_null:
3121             {
3122                 result.m_type = value_t::null;
3123                 break;
3124             }
3125 
3126             case token_type::value_string:
3127             {
3128                 result.m_type = value_t::string;
3129                 result.m_value = m_lexer.move_string();
3130                 break;
3131             }
3132 
3133             case token_type::literal_true:
3134             {
3135                 result.m_type = value_t::boolean;
3136                 result.m_value = true;
3137                 break;
3138             }
3139 
3140             case token_type::literal_false:
3141             {
3142                 result.m_type = value_t::boolean;
3143                 result.m_value = false;
3144                 break;
3145             }
3146 
3147             case token_type::value_unsigned:
3148             {
3149                 result.m_type = value_t::number_unsigned;
3150                 result.m_value = m_lexer.get_number_unsigned();
3151                 break;
3152             }
3153 
3154             case token_type::value_integer:
3155             {
3156                 result.m_type = value_t::number_integer;
3157                 result.m_value = m_lexer.get_number_integer();
3158                 break;
3159             }
3160 
3161             case token_type::value_float:
3162             {
3163                 result.m_type = value_t::number_float;
3164                 result.m_value = m_lexer.get_number_float();
3165 
3166                 // throw in case of infinity or NAN
3167                 if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
3168                 {
3169                     if (allow_exceptions)
3170                     {
3171                         JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
3172                                                         m_lexer.get_token_string() + "'"));
3173                     }
3174                     expect(token_type::uninitialized);
3175                 }
3176                 break;
3177             }
3178 
3179             case token_type::parse_error:
3180             {
3181                 // using "uninitialized" to avoid "expected" message
3182                 if (not expect(token_type::uninitialized))
3183                 {
3184                     return;
3185                 }
3186                 break; // LCOV_EXCL_LINE
3187             }
3188 
3189             default:
3190             {
3191                 // the last token was unexpected; we expected a value
3192                 if (not expect(token_type::literal_or_value))
3193                 {
3194                     return;
3195                 }
3196                 break; // LCOV_EXCL_LINE
3197             }
3198         }
3199 
3200         if (keep and callback and not callback(depth, parse_event_t::value, result))
3201         {
3202             result.m_type = value_t::discarded;
3203         }
3204     }
3205 
3206     /*!
3207     @brief the acutal acceptor
3208     @invariant 1. The last token is not yet processed. Therefore, the caller
3209                   of this function must make sure a token has been read.
3210                2. When this function returns, the last token is processed.
3211                   That is, the last read character was already considered.
3212     This invariant makes sure that no token needs to be "unput".
3213     */
accept_internal()3214     bool accept_internal()
3215     {
3216         switch (last_token)
3217         {
3218             case token_type::begin_object:
3219             {
3220                 // read next token
3221                 get_token();
3222 
3223                 // closing } -> we are done
3224                 if (last_token == token_type::end_object)
3225                 {
3226                     return true;
3227                 }
3228 
3229                 // parse values
3230                 while (true)
3231                 {
3232                     // parse key
3233                     if (last_token != token_type::value_string)
3234                     {
3235                         return false;
3236                     }
3237 
3238                     // parse separator (:)
3239                     get_token();
3240                     if (last_token != token_type::name_separator)
3241                     {
3242                         return false;
3243                     }
3244 
3245                     // parse value
3246                     get_token();
3247                     if (not accept_internal())
3248                     {
3249                         return false;
3250                     }
3251 
3252                     // comma -> next value
3253                     get_token();
3254                     if (last_token == token_type::value_separator)
3255                     {
3256                         get_token();
3257                         continue;
3258                     }
3259 
3260                     // closing }
3261                     return (last_token == token_type::end_object);
3262                 }
3263             }
3264 
3265             case token_type::begin_array:
3266             {
3267                 // read next token
3268                 get_token();
3269 
3270                 // closing ] -> we are done
3271                 if (last_token == token_type::end_array)
3272                 {
3273                     return true;
3274                 }
3275 
3276                 // parse values
3277                 while (true)
3278                 {
3279                     // parse value
3280                     if (not accept_internal())
3281                     {
3282                         return false;
3283                     }
3284 
3285                     // comma -> next value
3286                     get_token();
3287                     if (last_token == token_type::value_separator)
3288                     {
3289                         get_token();
3290                         continue;
3291                     }
3292 
3293                     // closing ]
3294                     return (last_token == token_type::end_array);
3295                 }
3296             }
3297 
3298             case token_type::value_float:
3299             {
3300                 // reject infinity or NAN
3301                 return std::isfinite(m_lexer.get_number_float());
3302             }
3303 
3304             case token_type::literal_false:
3305             case token_type::literal_null:
3306             case token_type::literal_true:
3307             case token_type::value_integer:
3308             case token_type::value_string:
3309             case token_type::value_unsigned:
3310                 return true;
3311 
3312             default: // the last token was unexpected
3313                 return false;
3314         }
3315     }
3316 
3317     /// get next token from lexer
get_token()3318     token_type get_token()
3319     {
3320         return (last_token = m_lexer.scan());
3321     }
3322 
3323     /*!
3324     @throw parse_error.101 if expected token did not occur
3325     */
expect(token_type t)3326     bool expect(token_type t)
3327     {
3328         if (JSON_UNLIKELY(t != last_token))
3329         {
3330             errored = true;
3331             expected = t;
3332             if (allow_exceptions)
3333             {
3334                 throw_exception();
3335             }
3336             else
3337             {
3338                 return false;
3339             }
3340         }
3341 
3342         return true;
3343     }
3344 
throw_exception() const3345     [[noreturn]] void throw_exception() const
3346     {
3347         std::string error_msg = "syntax error - ";
3348         if (last_token == token_type::parse_error)
3349         {
3350             error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
3351                          m_lexer.get_token_string() + "'";
3352         }
3353         else
3354         {
3355             error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
3356         }
3357 
3358         if (expected != token_type::uninitialized)
3359         {
3360             error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
3361         }
3362 
3363         JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3364     }
3365 
3366   private:
3367     /// current level of recursion
3368     int depth = 0;
3369     /// callback function
3370     const parser_callback_t callback = nullptr;
3371     /// the type of the last read token
3372     token_type last_token = token_type::uninitialized;
3373     /// the lexer
3374     lexer_t m_lexer;
3375     /// whether a syntax error occurred
3376     bool errored = false;
3377     /// possible reason for the syntax error
3378     token_type expected = token_type::uninitialized;
3379     /// whether to throw exceptions in case of errors
3380     const bool allow_exceptions = true;
3381 };
3382 
3383 ///////////////
3384 // iterators //
3385 ///////////////
3386 
3387 /*!
3388 @brief an iterator for primitive JSON types
3389 This class models an iterator for primitive JSON types (boolean, number,
3390 string). It's only purpose is to allow the iterator/const_iterator classes
3391 to "iterate" over primitive values. Internally, the iterator is modeled by
3392 a `difference_type` variable. Value begin_value (`0`) models the begin,
3393 end_value (`1`) models past the end.
3394 */
3395 class primitive_iterator_t
3396 {
3397   public:
3398     using difference_type = std::ptrdiff_t;
3399 
get_value() const3400     constexpr difference_type get_value() const noexcept
3401     {
3402         return m_it;
3403     }
3404 
3405     /// set iterator to a defined beginning
set_begin()3406     void set_begin() noexcept
3407     {
3408         m_it = begin_value;
3409     }
3410 
3411     /// set iterator to a defined past the end
set_end()3412     void set_end() noexcept
3413     {
3414         m_it = end_value;
3415     }
3416 
3417     /// return whether the iterator can be dereferenced
is_begin() const3418     constexpr bool is_begin() const noexcept
3419     {
3420         return m_it == begin_value;
3421     }
3422 
3423     /// return whether the iterator is at end
is_end() const3424     constexpr bool is_end() const noexcept
3425     {
3426         return m_it == end_value;
3427     }
3428 
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)3429     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3430     {
3431         return lhs.m_it == rhs.m_it;
3432     }
3433 
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)3434     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3435     {
3436         return lhs.m_it < rhs.m_it;
3437     }
3438 
operator +(difference_type i)3439     primitive_iterator_t operator+(difference_type i)
3440     {
3441         auto result = *this;
3442         result += i;
3443         return result;
3444     }
3445 
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)3446     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3447     {
3448         return lhs.m_it - rhs.m_it;
3449     }
3450 
operator <<(std::ostream & os,primitive_iterator_t it)3451     friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
3452     {
3453         return os << it.m_it;
3454     }
3455 
operator ++()3456     primitive_iterator_t& operator++()
3457     {
3458         ++m_it;
3459         return *this;
3460     }
3461 
operator ++(int)3462     primitive_iterator_t operator++(int)
3463     {
3464         auto result = *this;
3465         m_it++;
3466         return result;
3467     }
3468 
operator --()3469     primitive_iterator_t& operator--()
3470     {
3471         --m_it;
3472         return *this;
3473     }
3474 
operator --(int)3475     primitive_iterator_t operator--(int)
3476     {
3477         auto result = *this;
3478         m_it--;
3479         return result;
3480     }
3481 
operator +=(difference_type n)3482     primitive_iterator_t& operator+=(difference_type n)
3483     {
3484         m_it += n;
3485         return *this;
3486     }
3487 
operator -=(difference_type n)3488     primitive_iterator_t& operator-=(difference_type n)
3489     {
3490         m_it -= n;
3491         return *this;
3492     }
3493 
3494   private:
3495     static constexpr difference_type begin_value = 0;
3496     static constexpr difference_type end_value = begin_value + 1;
3497 
3498     /// iterator as signed integer type
3499     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3500 };
3501 
3502 /*!
3503 @brief an iterator value
3504 @note This structure could easily be a union, but MSVC currently does not allow
3505 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
3506 */
3507 template<typename BasicJsonType> struct internal_iterator
3508 {
3509     /// iterator for JSON objects
3510     typename BasicJsonType::object_t::iterator object_iterator {};
3511     /// iterator for JSON arrays
3512     typename BasicJsonType::array_t::iterator array_iterator {};
3513     /// generic iterator for all other types
3514     primitive_iterator_t primitive_iterator {};
3515 };
3516 
3517 template<typename IteratorType> class iteration_proxy;
3518 
3519 /*!
3520 @brief a template for a random access iterator for the @ref basic_json class
3521 This class implements a both iterators (iterator and const_iterator) for the
3522 @ref basic_json class.
3523 @note An iterator is called *initialized* when a pointer to a JSON value has
3524       been set (e.g., by a constructor or a copy assignment). If the iterator is
3525       default-constructed, it is *uninitialized* and most methods are undefined.
3526       **The library uses assertions to detect calls on uninitialized iterators.**
3527 @requirement The class satisfies the following concept requirements:
3528 -
3529 [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
3530   The iterator that can be moved to point (forward and backward) to any
3531   element in constant time.
3532 @since version 1.0.0, simplified in version 2.0.9
3533 */
3534 template<typename BasicJsonType>
3535 class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJsonType>
3536 {
3537     /// allow basic_json to access private members
3538     friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
3539     friend BasicJsonType;
3540     friend iteration_proxy<iter_impl>;
3541 
3542     using object_t = typename BasicJsonType::object_t;
3543     using array_t = typename BasicJsonType::array_t;
3544     // make sure BasicJsonType is basic_json or const basic_json
3545     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
3546                   "iter_impl only accepts (const) basic_json");
3547 
3548   public:
3549     /// the type of the values when the iterator is dereferenced
3550     using value_type = typename BasicJsonType::value_type;
3551     /// a type to represent differences between iterators
3552     using difference_type = typename BasicJsonType::difference_type;
3553     /// defines a pointer to the type iterated over (value_type)
3554     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
3555           typename BasicJsonType::const_pointer,
3556           typename BasicJsonType::pointer>::type;
3557     /// defines a reference to the type iterated over (value_type)
3558     using reference =
3559         typename std::conditional<std::is_const<BasicJsonType>::value,
3560         typename BasicJsonType::const_reference,
3561         typename BasicJsonType::reference>::type;
3562     /// the category of the iterator
3563     using iterator_category = std::bidirectional_iterator_tag;
3564 
3565     /// default constructor
3566     iter_impl() = default;
3567 
3568     /*!
3569     @brief constructor for a given JSON instance
3570     @param[in] object  pointer to a JSON object for this iterator
3571     @pre object != nullptr
3572     @post The iterator is initialized; i.e. `m_object != nullptr`.
3573     */
iter_impl(pointer object)3574     explicit iter_impl(pointer object) noexcept : m_object(object)
3575     {
3576         assert(m_object != nullptr);
3577 
3578         switch (m_object->m_type)
3579         {
3580             case value_t::object:
3581             {
3582                 m_it.object_iterator = typename object_t::iterator();
3583                 break;
3584             }
3585 
3586             case value_t::array:
3587             {
3588                 m_it.array_iterator = typename array_t::iterator();
3589                 break;
3590             }
3591 
3592             default:
3593             {
3594                 m_it.primitive_iterator = primitive_iterator_t();
3595                 break;
3596             }
3597         }
3598     }
3599 
3600     /*!
3601     @note The conventional copy constructor and copy assignment are implicitly
3602           defined. Combined with the following converting constructor and
3603           assignment, they support: (1) copy from iterator to iterator, (2)
3604           copy from const iterator to const iterator, and (3) conversion from
3605           iterator to const iterator. However conversion from const iterator
3606           to iterator is not defined.
3607     */
3608 
3609     /*!
3610     @brief converting constructor
3611     @param[in] other  non-const iterator to copy from
3612     @note It is not checked whether @a other is initialized.
3613     */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)3614     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
3615         : m_object(other.m_object), m_it(other.m_it) {}
3616 
3617     /*!
3618     @brief converting assignment
3619     @param[in,out] other  non-const iterator to copy from
3620     @return const/non-const iterator
3621     @note It is not checked whether @a other is initialized.
3622     */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)3623     iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
3624     {
3625         m_object = other.m_object;
3626         m_it = other.m_it;
3627         return *this;
3628     }
3629 
3630   private:
3631     /*!
3632     @brief set the iterator to the first value
3633     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3634     */
set_begin()3635     void set_begin() noexcept
3636     {
3637         assert(m_object != nullptr);
3638 
3639         switch (m_object->m_type)
3640         {
3641             case value_t::object:
3642             {
3643                 m_it.object_iterator = m_object->m_value.object->begin();
3644                 break;
3645             }
3646 
3647             case value_t::array:
3648             {
3649                 m_it.array_iterator = m_object->m_value.array->begin();
3650                 break;
3651             }
3652 
3653             case value_t::null:
3654             {
3655                 // set to end so begin()==end() is true: null is empty
3656                 m_it.primitive_iterator.set_end();
3657                 break;
3658             }
3659 
3660             default:
3661             {
3662                 m_it.primitive_iterator.set_begin();
3663                 break;
3664             }
3665         }
3666     }
3667 
3668     /*!
3669     @brief set the iterator past the last value
3670     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3671     */
set_end()3672     void set_end() noexcept
3673     {
3674         assert(m_object != nullptr);
3675 
3676         switch (m_object->m_type)
3677         {
3678             case value_t::object:
3679             {
3680                 m_it.object_iterator = m_object->m_value.object->end();
3681                 break;
3682             }
3683 
3684             case value_t::array:
3685             {
3686                 m_it.array_iterator = m_object->m_value.array->end();
3687                 break;
3688             }
3689 
3690             default:
3691             {
3692                 m_it.primitive_iterator.set_end();
3693                 break;
3694             }
3695         }
3696     }
3697 
3698   public:
3699     /*!
3700     @brief return a reference to the value pointed to by the iterator
3701     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3702     */
operator *() const3703     reference operator*() const
3704     {
3705         assert(m_object != nullptr);
3706 
3707         switch (m_object->m_type)
3708         {
3709             case value_t::object:
3710             {
3711                 assert(m_it.object_iterator != m_object->m_value.object->end());
3712                 return m_it.object_iterator->second;
3713             }
3714 
3715             case value_t::array:
3716             {
3717                 assert(m_it.array_iterator != m_object->m_value.array->end());
3718                 return *m_it.array_iterator;
3719             }
3720 
3721             case value_t::null:
3722                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3723 
3724             default:
3725             {
3726                 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3727                 {
3728                     return *m_object;
3729                 }
3730 
3731                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3732             }
3733         }
3734     }
3735 
3736     /*!
3737     @brief dereference the iterator
3738     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3739     */
operator ->() const3740     pointer operator->() const
3741     {
3742         assert(m_object != nullptr);
3743 
3744         switch (m_object->m_type)
3745         {
3746             case value_t::object:
3747             {
3748                 assert(m_it.object_iterator != m_object->m_value.object->end());
3749                 return &(m_it.object_iterator->second);
3750             }
3751 
3752             case value_t::array:
3753             {
3754                 assert(m_it.array_iterator != m_object->m_value.array->end());
3755                 return &*m_it.array_iterator;
3756             }
3757 
3758             default:
3759             {
3760                 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3761                 {
3762                     return m_object;
3763                 }
3764 
3765                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3766             }
3767         }
3768     }
3769 
3770     /*!
3771     @brief post-increment (it++)
3772     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3773     */
operator ++(int)3774     iter_impl operator++(int)
3775     {
3776         auto result = *this;
3777         ++(*this);
3778         return result;
3779     }
3780 
3781     /*!
3782     @brief pre-increment (++it)
3783     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3784     */
operator ++()3785     iter_impl& operator++()
3786     {
3787         assert(m_object != nullptr);
3788 
3789         switch (m_object->m_type)
3790         {
3791             case value_t::object:
3792             {
3793                 std::advance(m_it.object_iterator, 1);
3794                 break;
3795             }
3796 
3797             case value_t::array:
3798             {
3799                 std::advance(m_it.array_iterator, 1);
3800                 break;
3801             }
3802 
3803             default:
3804             {
3805                 ++m_it.primitive_iterator;
3806                 break;
3807             }
3808         }
3809 
3810         return *this;
3811     }
3812 
3813     /*!
3814     @brief post-decrement (it--)
3815     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3816     */
operator --(int)3817     iter_impl operator--(int)
3818     {
3819         auto result = *this;
3820         --(*this);
3821         return result;
3822     }
3823 
3824     /*!
3825     @brief pre-decrement (--it)
3826     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3827     */
operator --()3828     iter_impl& operator--()
3829     {
3830         assert(m_object != nullptr);
3831 
3832         switch (m_object->m_type)
3833         {
3834             case value_t::object:
3835             {
3836                 std::advance(m_it.object_iterator, -1);
3837                 break;
3838             }
3839 
3840             case value_t::array:
3841             {
3842                 std::advance(m_it.array_iterator, -1);
3843                 break;
3844             }
3845 
3846             default:
3847             {
3848                 --m_it.primitive_iterator;
3849                 break;
3850             }
3851         }
3852 
3853         return *this;
3854     }
3855 
3856     /*!
3857     @brief  comparison: equal
3858     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3859     */
operator ==(const iter_impl & other) const3860     bool operator==(const iter_impl& other) const
3861     {
3862         // if objects are not the same, the comparison is undefined
3863         if (JSON_UNLIKELY(m_object != other.m_object))
3864         {
3865             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
3866         }
3867 
3868         assert(m_object != nullptr);
3869 
3870         switch (m_object->m_type)
3871         {
3872             case value_t::object:
3873                 return (m_it.object_iterator == other.m_it.object_iterator);
3874 
3875             case value_t::array:
3876                 return (m_it.array_iterator == other.m_it.array_iterator);
3877 
3878             default:
3879                 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
3880         }
3881     }
3882 
3883     /*!
3884     @brief  comparison: not equal
3885     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3886     */
operator !=(const iter_impl & other) const3887     bool operator!=(const iter_impl& other) const
3888     {
3889         return not operator==(other);
3890     }
3891 
3892     /*!
3893     @brief  comparison: smaller
3894     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3895     */
operator <(const iter_impl & other) const3896     bool operator<(const iter_impl& other) const
3897     {
3898         // if objects are not the same, the comparison is undefined
3899         if (JSON_UNLIKELY(m_object != other.m_object))
3900         {
3901             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
3902         }
3903 
3904         assert(m_object != nullptr);
3905 
3906         switch (m_object->m_type)
3907         {
3908             case value_t::object:
3909                 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
3910 
3911             case value_t::array:
3912                 return (m_it.array_iterator < other.m_it.array_iterator);
3913 
3914             default:
3915                 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
3916         }
3917     }
3918 
3919     /*!
3920     @brief  comparison: less than or equal
3921     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3922     */
operator <=(const iter_impl & other) const3923     bool operator<=(const iter_impl& other) const
3924     {
3925         return not other.operator < (*this);
3926     }
3927 
3928     /*!
3929     @brief  comparison: greater than
3930     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3931     */
operator >(const iter_impl & other) const3932     bool operator>(const iter_impl& other) const
3933     {
3934         return not operator<=(other);
3935     }
3936 
3937     /*!
3938     @brief  comparison: greater than or equal
3939     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3940     */
operator >=(const iter_impl & other) const3941     bool operator>=(const iter_impl& other) const
3942     {
3943         return not operator<(other);
3944     }
3945 
3946     /*!
3947     @brief  add to iterator
3948     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3949     */
operator +=(difference_type i)3950     iter_impl& operator+=(difference_type i)
3951     {
3952         assert(m_object != nullptr);
3953 
3954         switch (m_object->m_type)
3955         {
3956             case value_t::object:
3957                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
3958 
3959             case value_t::array:
3960             {
3961                 std::advance(m_it.array_iterator, i);
3962                 break;
3963             }
3964 
3965             default:
3966             {
3967                 m_it.primitive_iterator += i;
3968                 break;
3969             }
3970         }
3971 
3972         return *this;
3973     }
3974 
3975     /*!
3976     @brief  subtract from iterator
3977     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3978     */
operator -=(difference_type i)3979     iter_impl& operator-=(difference_type i)
3980     {
3981         return operator+=(-i);
3982     }
3983 
3984     /*!
3985     @brief  add to iterator
3986     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3987     */
operator +(difference_type i) const3988     iter_impl operator+(difference_type i) const
3989     {
3990         auto result = *this;
3991         result += i;
3992         return result;
3993     }
3994 
3995     /*!
3996     @brief  addition of distance and iterator
3997     @pre The iterator is initialized; i.e. `m_object != nullptr`.
3998     */
operator +(difference_type i,const iter_impl & it)3999     friend iter_impl operator+(difference_type i, const iter_impl& it)
4000     {
4001         auto result = it;
4002         result += i;
4003         return result;
4004     }
4005 
4006     /*!
4007     @brief  subtract from iterator
4008     @pre The iterator is initialized; i.e. `m_object != nullptr`.
4009     */
operator -(difference_type i) const4010     iter_impl operator-(difference_type i) const
4011     {
4012         auto result = *this;
4013         result -= i;
4014         return result;
4015     }
4016 
4017     /*!
4018     @brief  return difference
4019     @pre The iterator is initialized; i.e. `m_object != nullptr`.
4020     */
operator -(const iter_impl & other) const4021     difference_type operator-(const iter_impl& other) const
4022     {
4023         assert(m_object != nullptr);
4024 
4025         switch (m_object->m_type)
4026         {
4027             case value_t::object:
4028                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4029 
4030             case value_t::array:
4031                 return m_it.array_iterator - other.m_it.array_iterator;
4032 
4033             default:
4034                 return m_it.primitive_iterator - other.m_it.primitive_iterator;
4035         }
4036     }
4037 
4038     /*!
4039     @brief  access to successor
4040     @pre The iterator is initialized; i.e. `m_object != nullptr`.
4041     */
operator [](difference_type n) const4042     reference operator[](difference_type n) const
4043     {
4044         assert(m_object != nullptr);
4045 
4046         switch (m_object->m_type)
4047         {
4048             case value_t::object:
4049                 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
4050 
4051             case value_t::array:
4052                 return *std::next(m_it.array_iterator, n);
4053 
4054             case value_t::null:
4055                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4056 
4057             default:
4058             {
4059                 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4060                 {
4061                     return *m_object;
4062                 }
4063 
4064                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4065             }
4066         }
4067     }
4068 
4069     /*!
4070     @brief  return the key of an object iterator
4071     @pre The iterator is initialized; i.e. `m_object != nullptr`.
4072     */
key() const4073     typename object_t::key_type key() const
4074     {
4075         assert(m_object != nullptr);
4076 
4077         if (JSON_LIKELY(m_object->is_object()))
4078         {
4079             return m_it.object_iterator->first;
4080         }
4081 
4082         JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
4083     }
4084 
4085     /*!
4086     @brief  return the value of an iterator
4087     @pre The iterator is initialized; i.e. `m_object != nullptr`.
4088     */
value() const4089     reference value() const
4090     {
4091         return operator*();
4092     }
4093 
4094   private:
4095     /// associated JSON instance
4096     pointer m_object = nullptr;
4097     /// the actual iterator of the associated instance
4098     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it = {};
4099 };
4100 
4101 /// proxy class for the iterator_wrapper functions
4102 template<typename IteratorType> class iteration_proxy
4103 {
4104   private:
4105     /// helper class for iteration
4106     class iteration_proxy_internal
4107     {
4108       private:
4109         /// the iterator
4110         IteratorType anchor;
4111         /// an index for arrays (used to create key names)
4112         std::size_t array_index = 0;
4113 
4114       public:
iteration_proxy_internal(IteratorType it)4115         explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4116 
4117         /// dereference operator (needed for range-based for)
operator *()4118         iteration_proxy_internal& operator*()
4119         {
4120             return *this;
4121         }
4122 
4123         /// increment operator (needed for range-based for)
operator ++()4124         iteration_proxy_internal& operator++()
4125         {
4126             ++anchor;
4127             ++array_index;
4128 
4129             return *this;
4130         }
4131 
4132         /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_internal & o) const4133         bool operator!=(const iteration_proxy_internal& o) const noexcept
4134         {
4135             return anchor != o.anchor;
4136         }
4137 
4138         /// return key of the iterator
key() const4139         std::string key() const
4140         {
4141             assert(anchor.m_object != nullptr);
4142 
4143             switch (anchor.m_object->type())
4144             {
4145                 // use integer array index as key
4146                 case value_t::array:
4147                     return std::to_string(array_index);
4148 
4149                 // use key from the object
4150                 case value_t::object:
4151                     return anchor.key();
4152 
4153                 // use an empty key for all primitive types
4154                 default:
4155                     return "";
4156             }
4157         }
4158 
4159         /// return value of the iterator
value() const4160         typename IteratorType::reference value() const
4161         {
4162             return anchor.value();
4163         }
4164     };
4165 
4166     /// the container to iterate
4167     typename IteratorType::reference container;
4168 
4169   public:
4170     /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)4171     explicit iteration_proxy(typename IteratorType::reference cont)
4172         : container(cont) {}
4173 
4174     /// return iterator begin (needed for range-based for)
begin()4175     iteration_proxy_internal begin() noexcept
4176     {
4177         return iteration_proxy_internal(container.begin());
4178     }
4179 
4180     /// return iterator end (needed for range-based for)
end()4181     iteration_proxy_internal end() noexcept
4182     {
4183         return iteration_proxy_internal(container.end());
4184     }
4185 };
4186 
4187 /*!
4188 @brief a template for a reverse iterator class
4189 @tparam Base the base iterator type to reverse. Valid types are @ref
4190 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
4191 create @ref const_reverse_iterator).
4192 @requirement The class satisfies the following concept requirements:
4193 -
4194 [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
4195   The iterator that can be moved to point (forward and backward) to any
4196   element in constant time.
4197 - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
4198   It is possible to write to the pointed-to element (only if @a Base is
4199   @ref iterator).
4200 @since version 1.0.0
4201 */
4202 template<typename Base>
4203 class json_reverse_iterator : public std::reverse_iterator<Base>
4204 {
4205   public:
4206     using difference_type = std::ptrdiff_t;
4207     /// shortcut to the reverse iterator adaptor
4208     using base_iterator = std::reverse_iterator<Base>;
4209     /// the reference type for the pointed-to element
4210     using reference = typename Base::reference;
4211 
4212     /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)4213     json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
4214         : base_iterator(it) {}
4215 
4216     /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)4217     json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
4218 
4219     /// post-increment (it++)
operator ++(int)4220     json_reverse_iterator operator++(int)
4221     {
4222         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4223     }
4224 
4225     /// pre-increment (++it)
operator ++()4226     json_reverse_iterator& operator++()
4227     {
4228         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
4229     }
4230 
4231     /// post-decrement (it--)
operator --(int)4232     json_reverse_iterator operator--(int)
4233     {
4234         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4235     }
4236 
4237     /// pre-decrement (--it)
operator --()4238     json_reverse_iterator& operator--()
4239     {
4240         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
4241     }
4242 
4243     /// add to iterator
operator +=(difference_type i)4244     json_reverse_iterator& operator+=(difference_type i)
4245     {
4246         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
4247     }
4248 
4249     /// add to iterator
operator +(difference_type i) const4250     json_reverse_iterator operator+(difference_type i) const
4251     {
4252         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4253     }
4254 
4255     /// subtract from iterator
operator -(difference_type i) const4256     json_reverse_iterator operator-(difference_type i) const
4257     {
4258         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4259     }
4260 
4261     /// return difference
operator -(const json_reverse_iterator & other) const4262     difference_type operator-(const json_reverse_iterator& other) const
4263     {
4264         return base_iterator(*this) - base_iterator(other);
4265     }
4266 
4267     /// access to successor
operator [](difference_type n) const4268     reference operator[](difference_type n) const
4269     {
4270         return *(this->operator+(n));
4271     }
4272 
4273     /// return the key of an object iterator
key() const4274     auto key() const -> decltype(std::declval<Base>().key())
4275     {
4276         auto it = --this->base();
4277         return it.key();
4278     }
4279 
4280     /// return the value of an iterator
value() const4281     reference value() const
4282     {
4283         auto it = --this->base();
4284         return it.operator * ();
4285     }
4286 };
4287 
4288 /////////////////////
4289 // output adapters //
4290 /////////////////////
4291 
4292 /// abstract output adapter interface
4293 template<typename CharType> struct output_adapter_protocol
4294 {
4295     virtual void write_character(CharType c) = 0;
4296     virtual void write_characters(const CharType* s, std::size_t length) = 0;
4297     virtual ~output_adapter_protocol() = default;
4298 };
4299 
4300 /// a type to simplify interfaces
4301 template<typename CharType>
4302 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4303 
4304 /// output adapter for byte vectors
4305 template<typename CharType>
4306 class output_vector_adapter : public output_adapter_protocol<CharType>
4307 {
4308   public:
output_vector_adapter(std::vector<CharType> & vec)4309     explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
4310 
write_character(CharType c)4311     void write_character(CharType c) override
4312     {
4313         v.push_back(c);
4314     }
4315 
write_characters(const CharType * s,std::size_t length)4316     void write_characters(const CharType* s, std::size_t length) override
4317     {
4318         std::copy(s, s + length, std::back_inserter(v));
4319     }
4320 
4321   private:
4322     std::vector<CharType>& v;
4323 };
4324 
4325 /// output adapter for output streams
4326 template<typename CharType>
4327 class output_stream_adapter : public output_adapter_protocol<CharType>
4328 {
4329   public:
output_stream_adapter(std::basic_ostream<CharType> & s)4330     explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
4331 
write_character(CharType c)4332     void write_character(CharType c) override
4333     {
4334         stream.put(c);
4335     }
4336 
write_characters(const CharType * s,std::size_t length)4337     void write_characters(const CharType* s, std::size_t length) override
4338     {
4339         stream.write(s, static_cast<std::streamsize>(length));
4340     }
4341 
4342   private:
4343     std::basic_ostream<CharType>& stream;
4344 };
4345 
4346 /// output adapter for basic_string
4347 template<typename CharType>
4348 class output_string_adapter : public output_adapter_protocol<CharType>
4349 {
4350   public:
output_string_adapter(std::basic_string<CharType> & s)4351     explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {}
4352 
write_character(CharType c)4353     void write_character(CharType c) override
4354     {
4355         str.push_back(c);
4356     }
4357 
write_characters(const CharType * s,std::size_t length)4358     void write_characters(const CharType* s, std::size_t length) override
4359     {
4360         str.append(s, length);
4361     }
4362 
4363   private:
4364     std::basic_string<CharType>& str;
4365 };
4366 
4367 template<typename CharType>
4368 class output_adapter
4369 {
4370   public:
output_adapter(std::vector<CharType> & vec)4371     output_adapter(std::vector<CharType>& vec)
4372         : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4373 
output_adapter(std::basic_ostream<CharType> & s)4374     output_adapter(std::basic_ostream<CharType>& s)
4375         : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4376 
output_adapter(std::basic_string<CharType> & s)4377     output_adapter(std::basic_string<CharType>& s)
4378         : oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
4379 
operator output_adapter_t<CharType>()4380     operator output_adapter_t<CharType>()
4381     {
4382         return oa;
4383     }
4384 
4385   private:
4386     output_adapter_t<CharType> oa = nullptr;
4387 };
4388 
4389 //////////////////////////////
4390 // binary reader and writer //
4391 //////////////////////////////
4392 
4393 /*!
4394 @brief deserialization of CBOR and MessagePack values
4395 */
4396 template<typename BasicJsonType>
4397 class binary_reader
4398 {
4399     using number_integer_t = typename BasicJsonType::number_integer_t;
4400     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4401 
4402   public:
4403     /*!
4404     @brief create a binary reader
4405     @param[in] adapter  input adapter to read from
4406     */
binary_reader(input_adapter_t adapter)4407     explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4408     {
4409         assert(ia);
4410     }
4411 
4412     /*!
4413     @brief create a JSON value from CBOR input
4414     @param[in] strict  whether to expect the input to be consumed completed
4415     @return JSON value created from CBOR input
4416     @throw parse_error.110 if input ended unexpectedly or the end of file was
4417                            not reached when @a strict was set to true
4418     @throw parse_error.112 if unsupported byte was read
4419     */
parse_cbor(const bool strict)4420     BasicJsonType parse_cbor(const bool strict)
4421     {
4422         const auto res = parse_cbor_internal();
4423         if (strict)
4424         {
4425             get();
4426             check_eof(true);
4427         }
4428         return res;
4429     }
4430 
4431     /*!
4432     @brief create a JSON value from MessagePack input
4433     @param[in] strict  whether to expect the input to be consumed completed
4434     @return JSON value created from MessagePack input
4435     @throw parse_error.110 if input ended unexpectedly or the end of file was
4436                            not reached when @a strict was set to true
4437     @throw parse_error.112 if unsupported byte was read
4438     */
parse_msgpack(const bool strict)4439     BasicJsonType parse_msgpack(const bool strict)
4440     {
4441         const auto res = parse_msgpack_internal();
4442         if (strict)
4443         {
4444             get();
4445             check_eof(true);
4446         }
4447         return res;
4448     }
4449 
4450     /*!
4451     @brief determine system byte order
4452     @return true if and only if system's byte order is little endian
4453     @note from http://stackoverflow.com/a/1001328/266378
4454     */
little_endianess(int num=1)4455     static constexpr bool little_endianess(int num = 1) noexcept
4456     {
4457         return (*reinterpret_cast<char*>(&num) == 1);
4458     }
4459 
4460   private:
4461     /*!
4462     @param[in] get_char  whether a new character should be retrieved from the
4463                          input (true, default) or whether the last read
4464                          character should be considered instead
4465     */
parse_cbor_internal(const bool get_char=true)4466     BasicJsonType parse_cbor_internal(const bool get_char = true)
4467     {
4468         switch (get_char ? get() : current)
4469         {
4470             // EOF
4471             case std::char_traits<char>::eof():
4472                 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4473 
4474             // Integer 0x00..0x17 (0..23)
4475             case 0x00:
4476             case 0x01:
4477             case 0x02:
4478             case 0x03:
4479             case 0x04:
4480             case 0x05:
4481             case 0x06:
4482             case 0x07:
4483             case 0x08:
4484             case 0x09:
4485             case 0x0a:
4486             case 0x0b:
4487             case 0x0c:
4488             case 0x0d:
4489             case 0x0e:
4490             case 0x0f:
4491             case 0x10:
4492             case 0x11:
4493             case 0x12:
4494             case 0x13:
4495             case 0x14:
4496             case 0x15:
4497             case 0x16:
4498             case 0x17:
4499                 return static_cast<number_unsigned_t>(current);
4500 
4501             case 0x18: // Unsigned integer (one-byte uint8_t follows)
4502                 return get_number<uint8_t>();
4503 
4504             case 0x19: // Unsigned integer (two-byte uint16_t follows)
4505                 return get_number<uint16_t>();
4506 
4507             case 0x1a: // Unsigned integer (four-byte uint32_t follows)
4508                 return get_number<uint32_t>();
4509 
4510             case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
4511                 return get_number<uint64_t>();
4512 
4513             // Negative integer -1-0x00..-1-0x17 (-1..-24)
4514             case 0x20:
4515             case 0x21:
4516             case 0x22:
4517             case 0x23:
4518             case 0x24:
4519             case 0x25:
4520             case 0x26:
4521             case 0x27:
4522             case 0x28:
4523             case 0x29:
4524             case 0x2a:
4525             case 0x2b:
4526             case 0x2c:
4527             case 0x2d:
4528             case 0x2e:
4529             case 0x2f:
4530             case 0x30:
4531             case 0x31:
4532             case 0x32:
4533             case 0x33:
4534             case 0x34:
4535             case 0x35:
4536             case 0x36:
4537             case 0x37:
4538                 return static_cast<int8_t>(0x20 - 1 - current);
4539 
4540             case 0x38: // Negative integer (one-byte uint8_t follows)
4541             {
4542                 // must be uint8_t !
4543                 return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
4544             }
4545 
4546             case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
4547             {
4548                 return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
4549             }
4550 
4551             case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
4552             {
4553                 return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
4554             }
4555 
4556             case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
4557             {
4558                 return static_cast<number_integer_t>(-1) -
4559                        static_cast<number_integer_t>(get_number<uint64_t>());
4560             }
4561 
4562             // UTF-8 string (0x00..0x17 bytes follow)
4563             case 0x60:
4564             case 0x61:
4565             case 0x62:
4566             case 0x63:
4567             case 0x64:
4568             case 0x65:
4569             case 0x66:
4570             case 0x67:
4571             case 0x68:
4572             case 0x69:
4573             case 0x6a:
4574             case 0x6b:
4575             case 0x6c:
4576             case 0x6d:
4577             case 0x6e:
4578             case 0x6f:
4579             case 0x70:
4580             case 0x71:
4581             case 0x72:
4582             case 0x73:
4583             case 0x74:
4584             case 0x75:
4585             case 0x76:
4586             case 0x77:
4587             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4588             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4589             case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
4590             case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
4591             case 0x7f: // UTF-8 string (indefinite length)
4592             {
4593                 return get_cbor_string();
4594             }
4595 
4596             // array (0x00..0x17 data items follow)
4597             case 0x80:
4598             case 0x81:
4599             case 0x82:
4600             case 0x83:
4601             case 0x84:
4602             case 0x85:
4603             case 0x86:
4604             case 0x87:
4605             case 0x88:
4606             case 0x89:
4607             case 0x8a:
4608             case 0x8b:
4609             case 0x8c:
4610             case 0x8d:
4611             case 0x8e:
4612             case 0x8f:
4613             case 0x90:
4614             case 0x91:
4615             case 0x92:
4616             case 0x93:
4617             case 0x94:
4618             case 0x95:
4619             case 0x96:
4620             case 0x97:
4621             {
4622                 return get_cbor_array(current & 0x1f);
4623             }
4624 
4625             case 0x98: // array (one-byte uint8_t for n follows)
4626             {
4627                 return get_cbor_array(get_number<uint8_t>());
4628             }
4629 
4630             case 0x99: // array (two-byte uint16_t for n follow)
4631             {
4632                 return get_cbor_array(get_number<uint16_t>());
4633             }
4634 
4635             case 0x9a: // array (four-byte uint32_t for n follow)
4636             {
4637                 return get_cbor_array(get_number<uint32_t>());
4638             }
4639 
4640             case 0x9b: // array (eight-byte uint64_t for n follow)
4641             {
4642                 return get_cbor_array(get_number<uint64_t>());
4643             }
4644 
4645             case 0x9f: // array (indefinite length)
4646             {
4647                 BasicJsonType result = value_t::array;
4648                 while (get() != 0xff)
4649                 {
4650                     result.push_back(parse_cbor_internal(false));
4651                 }
4652                 return result;
4653             }
4654 
4655             // map (0x00..0x17 pairs of data items follow)
4656             case 0xa0:
4657             case 0xa1:
4658             case 0xa2:
4659             case 0xa3:
4660             case 0xa4:
4661             case 0xa5:
4662             case 0xa6:
4663             case 0xa7:
4664             case 0xa8:
4665             case 0xa9:
4666             case 0xaa:
4667             case 0xab:
4668             case 0xac:
4669             case 0xad:
4670             case 0xae:
4671             case 0xaf:
4672             case 0xb0:
4673             case 0xb1:
4674             case 0xb2:
4675             case 0xb3:
4676             case 0xb4:
4677             case 0xb5:
4678             case 0xb6:
4679             case 0xb7:
4680             {
4681                 return get_cbor_object(current & 0x1f);
4682             }
4683 
4684             case 0xb8: // map (one-byte uint8_t for n follows)
4685             {
4686                 return get_cbor_object(get_number<uint8_t>());
4687             }
4688 
4689             case 0xb9: // map (two-byte uint16_t for n follow)
4690             {
4691                 return get_cbor_object(get_number<uint16_t>());
4692             }
4693 
4694             case 0xba: // map (four-byte uint32_t for n follow)
4695             {
4696                 return get_cbor_object(get_number<uint32_t>());
4697             }
4698 
4699             case 0xbb: // map (eight-byte uint64_t for n follow)
4700             {
4701                 return get_cbor_object(get_number<uint64_t>());
4702             }
4703 
4704             case 0xbf: // map (indefinite length)
4705             {
4706                 BasicJsonType result = value_t::object;
4707                 while (get() != 0xff)
4708                 {
4709                     auto key = get_cbor_string();
4710                     result[key] = parse_cbor_internal();
4711                 }
4712                 return result;
4713             }
4714 
4715             case 0xf4: // false
4716             {
4717                 return false;
4718             }
4719 
4720             case 0xf5: // true
4721             {
4722                 return true;
4723             }
4724 
4725             case 0xf6: // null
4726             {
4727                 return value_t::null;
4728             }
4729 
4730             case 0xf9: // Half-Precision Float (two-byte IEEE 754)
4731             {
4732                 const int byte1 = get();
4733                 check_eof();
4734                 const int byte2 = get();
4735                 check_eof();
4736 
4737                 // code from RFC 7049, Appendix D, Figure 3:
4738                 // As half-precision floating-point numbers were only added
4739                 // to IEEE 754 in 2008, today's programming platforms often
4740                 // still only have limited support for them. It is very
4741                 // easy to include at least decoding support for them even
4742                 // without such support. An example of a small decoder for
4743                 // half-precision floating-point numbers in the C language
4744                 // is shown in Fig. 3.
4745                 const int half = (byte1 << 8) + byte2;
4746                 const int exp = (half >> 10) & 0x1f;
4747                 const int mant = half & 0x3ff;
4748                 double val;
4749                 if (exp == 0)
4750                 {
4751                     val = std::ldexp(mant, -24);
4752                 }
4753                 else if (exp != 31)
4754                 {
4755                     val = std::ldexp(mant + 1024, exp - 25);
4756                 }
4757                 else
4758                 {
4759                     val = (mant == 0) ? std::numeric_limits<double>::infinity()
4760                           : std::numeric_limits<double>::quiet_NaN();
4761                 }
4762                 return (half & 0x8000) != 0 ? -val : val;
4763             }
4764 
4765             case 0xfa: // Single-Precision Float (four-byte IEEE 754)
4766             {
4767                 return get_number<float>();
4768             }
4769 
4770             case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
4771             {
4772                 return get_number<double>();
4773             }
4774 
4775             default: // anything else (0xFF is handled inside the other types)
4776             {
4777                 std::stringstream ss;
4778                 ss << std::setw(2) << std::setfill('0') << std::hex << current;
4779                 JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + ss.str()));
4780             }
4781         }
4782     }
4783 
parse_msgpack_internal()4784     BasicJsonType parse_msgpack_internal()
4785     {
4786         switch (get())
4787         {
4788             // EOF
4789             case std::char_traits<char>::eof():
4790                 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4791 
4792             // positive fixint
4793             case 0x00:
4794             case 0x01:
4795             case 0x02:
4796             case 0x03:
4797             case 0x04:
4798             case 0x05:
4799             case 0x06:
4800             case 0x07:
4801             case 0x08:
4802             case 0x09:
4803             case 0x0a:
4804             case 0x0b:
4805             case 0x0c:
4806             case 0x0d:
4807             case 0x0e:
4808             case 0x0f:
4809             case 0x10:
4810             case 0x11:
4811             case 0x12:
4812             case 0x13:
4813             case 0x14:
4814             case 0x15:
4815             case 0x16:
4816             case 0x17:
4817             case 0x18:
4818             case 0x19:
4819             case 0x1a:
4820             case 0x1b:
4821             case 0x1c:
4822             case 0x1d:
4823             case 0x1e:
4824             case 0x1f:
4825             case 0x20:
4826             case 0x21:
4827             case 0x22:
4828             case 0x23:
4829             case 0x24:
4830             case 0x25:
4831             case 0x26:
4832             case 0x27:
4833             case 0x28:
4834             case 0x29:
4835             case 0x2a:
4836             case 0x2b:
4837             case 0x2c:
4838             case 0x2d:
4839             case 0x2e:
4840             case 0x2f:
4841             case 0x30:
4842             case 0x31:
4843             case 0x32:
4844             case 0x33:
4845             case 0x34:
4846             case 0x35:
4847             case 0x36:
4848             case 0x37:
4849             case 0x38:
4850             case 0x39:
4851             case 0x3a:
4852             case 0x3b:
4853             case 0x3c:
4854             case 0x3d:
4855             case 0x3e:
4856             case 0x3f:
4857             case 0x40:
4858             case 0x41:
4859             case 0x42:
4860             case 0x43:
4861             case 0x44:
4862             case 0x45:
4863             case 0x46:
4864             case 0x47:
4865             case 0x48:
4866             case 0x49:
4867             case 0x4a:
4868             case 0x4b:
4869             case 0x4c:
4870             case 0x4d:
4871             case 0x4e:
4872             case 0x4f:
4873             case 0x50:
4874             case 0x51:
4875             case 0x52:
4876             case 0x53:
4877             case 0x54:
4878             case 0x55:
4879             case 0x56:
4880             case 0x57:
4881             case 0x58:
4882             case 0x59:
4883             case 0x5a:
4884             case 0x5b:
4885             case 0x5c:
4886             case 0x5d:
4887             case 0x5e:
4888             case 0x5f:
4889             case 0x60:
4890             case 0x61:
4891             case 0x62:
4892             case 0x63:
4893             case 0x64:
4894             case 0x65:
4895             case 0x66:
4896             case 0x67:
4897             case 0x68:
4898             case 0x69:
4899             case 0x6a:
4900             case 0x6b:
4901             case 0x6c:
4902             case 0x6d:
4903             case 0x6e:
4904             case 0x6f:
4905             case 0x70:
4906             case 0x71:
4907             case 0x72:
4908             case 0x73:
4909             case 0x74:
4910             case 0x75:
4911             case 0x76:
4912             case 0x77:
4913             case 0x78:
4914             case 0x79:
4915             case 0x7a:
4916             case 0x7b:
4917             case 0x7c:
4918             case 0x7d:
4919             case 0x7e:
4920             case 0x7f:
4921                 return static_cast<number_unsigned_t>(current);
4922 
4923             // fixmap
4924             case 0x80:
4925             case 0x81:
4926             case 0x82:
4927             case 0x83:
4928             case 0x84:
4929             case 0x85:
4930             case 0x86:
4931             case 0x87:
4932             case 0x88:
4933             case 0x89:
4934             case 0x8a:
4935             case 0x8b:
4936             case 0x8c:
4937             case 0x8d:
4938             case 0x8e:
4939             case 0x8f:
4940             {
4941                 return get_msgpack_object(current & 0x0f);
4942             }
4943 
4944             // fixarray
4945             case 0x90:
4946             case 0x91:
4947             case 0x92:
4948             case 0x93:
4949             case 0x94:
4950             case 0x95:
4951             case 0x96:
4952             case 0x97:
4953             case 0x98:
4954             case 0x99:
4955             case 0x9a:
4956             case 0x9b:
4957             case 0x9c:
4958             case 0x9d:
4959             case 0x9e:
4960             case 0x9f:
4961             {
4962                 return get_msgpack_array(current & 0x0f);
4963             }
4964 
4965             // fixstr
4966             case 0xa0:
4967             case 0xa1:
4968             case 0xa2:
4969             case 0xa3:
4970             case 0xa4:
4971             case 0xa5:
4972             case 0xa6:
4973             case 0xa7:
4974             case 0xa8:
4975             case 0xa9:
4976             case 0xaa:
4977             case 0xab:
4978             case 0xac:
4979             case 0xad:
4980             case 0xae:
4981             case 0xaf:
4982             case 0xb0:
4983             case 0xb1:
4984             case 0xb2:
4985             case 0xb3:
4986             case 0xb4:
4987             case 0xb5:
4988             case 0xb6:
4989             case 0xb7:
4990             case 0xb8:
4991             case 0xb9:
4992             case 0xba:
4993             case 0xbb:
4994             case 0xbc:
4995             case 0xbd:
4996             case 0xbe:
4997             case 0xbf:
4998                 return get_msgpack_string();
4999 
5000             case 0xc0: // nil
5001                 return value_t::null;
5002 
5003             case 0xc2: // false
5004                 return false;
5005 
5006             case 0xc3: // true
5007                 return true;
5008 
5009             case 0xca: // float 32
5010                 return get_number<float>();
5011 
5012             case 0xcb: // float 64
5013                 return get_number<double>();
5014 
5015             case 0xcc: // uint 8
5016                 return get_number<uint8_t>();
5017 
5018             case 0xcd: // uint 16
5019                 return get_number<uint16_t>();
5020 
5021             case 0xce: // uint 32
5022                 return get_number<uint32_t>();
5023 
5024             case 0xcf: // uint 64
5025                 return get_number<uint64_t>();
5026 
5027             case 0xd0: // int 8
5028                 return get_number<int8_t>();
5029 
5030             case 0xd1: // int 16
5031                 return get_number<int16_t>();
5032 
5033             case 0xd2: // int 32
5034                 return get_number<int32_t>();
5035 
5036             case 0xd3: // int 64
5037                 return get_number<int64_t>();
5038 
5039             case 0xd9: // str 8
5040             case 0xda: // str 16
5041             case 0xdb: // str 32
5042                 return get_msgpack_string();
5043 
5044             case 0xdc: // array 16
5045             {
5046                 return get_msgpack_array(get_number<uint16_t>());
5047             }
5048 
5049             case 0xdd: // array 32
5050             {
5051                 return get_msgpack_array(get_number<uint32_t>());
5052             }
5053 
5054             case 0xde: // map 16
5055             {
5056                 return get_msgpack_object(get_number<uint16_t>());
5057             }
5058 
5059             case 0xdf: // map 32
5060             {
5061                 return get_msgpack_object(get_number<uint32_t>());
5062             }
5063 
5064             // positive fixint
5065             case 0xe0:
5066             case 0xe1:
5067             case 0xe2:
5068             case 0xe3:
5069             case 0xe4:
5070             case 0xe5:
5071             case 0xe6:
5072             case 0xe7:
5073             case 0xe8:
5074             case 0xe9:
5075             case 0xea:
5076             case 0xeb:
5077             case 0xec:
5078             case 0xed:
5079             case 0xee:
5080             case 0xef:
5081             case 0xf0:
5082             case 0xf1:
5083             case 0xf2:
5084             case 0xf3:
5085             case 0xf4:
5086             case 0xf5:
5087             case 0xf6:
5088             case 0xf7:
5089             case 0xf8:
5090             case 0xf9:
5091             case 0xfa:
5092             case 0xfb:
5093             case 0xfc:
5094             case 0xfd:
5095             case 0xfe:
5096             case 0xff:
5097                 return static_cast<int8_t>(current);
5098 
5099             default: // anything else
5100             {
5101                 std::stringstream ss;
5102                 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5103                 JSON_THROW(parse_error::create(112, chars_read,
5104                                                "error reading MessagePack; last byte: 0x" + ss.str()));
5105             }
5106         }
5107     }
5108 
5109     /*!
5110     @brief get next character from the input
5111     This function provides the interface to the used input adapter. It does
5112     not throw in case the input reached EOF, but returns a -'ve valued
5113     `std::char_traits<char>::eof()` in that case.
5114     @return character read from the input
5115     */
get()5116     int get()
5117     {
5118         ++chars_read;
5119         return (current = ia->get_character());
5120     }
5121 
5122     /*
5123     @brief read a number from the input
5124     @tparam NumberType the type of the number
5125     @return number of type @a NumberType
5126     @note This function needs to respect the system's endianess, because
5127           bytes in CBOR and MessagePack are stored in network order (big
5128           endian) and therefore need reordering on little endian systems.
5129     @throw parse_error.110 if input has less than `sizeof(NumberType)` bytes
5130     */
get_number()5131     template<typename NumberType> NumberType get_number()
5132     {
5133         // step 1: read input into array with system's byte order
5134         std::array<uint8_t, sizeof(NumberType)> vec;
5135         for (std::size_t i = 0; i < sizeof(NumberType); ++i)
5136         {
5137             get();
5138             check_eof();
5139 
5140             // reverse byte order prior to conversion if necessary
5141             if (is_little_endian)
5142             {
5143                 vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5144             }
5145             else
5146             {
5147                 vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
5148             }
5149         }
5150 
5151         // step 2: convert array into number of type T and return
5152         NumberType result;
5153         std::memcpy(&result, vec.data(), sizeof(NumberType));
5154         return result;
5155     }
5156 
5157     /*!
5158     @brief create a string by reading characters from the input
5159     @param[in] len number of bytes to read
5160     @note We can not reserve @a len bytes for the result, because @a len
5161           may be too large. Usually, @ref check_eof() detects the end of
5162           the input before we run out of string memory.
5163     @return string created by reading @a len bytes
5164     @throw parse_error.110 if input has less than @a len bytes
5165     */
5166     template<typename NumberType>
get_string(const NumberType len)5167     std::string get_string(const NumberType len)
5168     {
5169         std::string result;
5170         std::generate_n(std::back_inserter(result), len, [this]()
5171         {
5172             get();
5173             check_eof();
5174             return static_cast<char>(current);
5175         });
5176         return result;
5177     }
5178 
5179     /*!
5180     @brief reads a CBOR string
5181     This function first reads starting bytes to determine the expected
5182     string length and then copies this number of bytes into a string.
5183     Additionally, CBOR's strings with indefinite lengths are supported.
5184     @return string
5185     @throw parse_error.110 if input ended
5186     @throw parse_error.113 if an unexpected byte is read
5187     */
get_cbor_string()5188     std::string get_cbor_string()
5189     {
5190         check_eof();
5191 
5192         switch (current)
5193         {
5194             // UTF-8 string (0x00..0x17 bytes follow)
5195             case 0x60:
5196             case 0x61:
5197             case 0x62:
5198             case 0x63:
5199             case 0x64:
5200             case 0x65:
5201             case 0x66:
5202             case 0x67:
5203             case 0x68:
5204             case 0x69:
5205             case 0x6a:
5206             case 0x6b:
5207             case 0x6c:
5208             case 0x6d:
5209             case 0x6e:
5210             case 0x6f:
5211             case 0x70:
5212             case 0x71:
5213             case 0x72:
5214             case 0x73:
5215             case 0x74:
5216             case 0x75:
5217             case 0x76:
5218             case 0x77:
5219             {
5220                 return get_string(current & 0x1f);
5221             }
5222 
5223             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5224             {
5225                 return get_string(get_number<uint8_t>());
5226             }
5227 
5228             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5229             {
5230                 return get_string(get_number<uint16_t>());
5231             }
5232 
5233             case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
5234             {
5235                 return get_string(get_number<uint32_t>());
5236             }
5237 
5238             case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
5239             {
5240                 return get_string(get_number<uint64_t>());
5241             }
5242 
5243             case 0x7f: // UTF-8 string (indefinite length)
5244             {
5245                 std::string result;
5246                 while (get() != 0xff)
5247                 {
5248                     check_eof();
5249                     result.push_back(static_cast<char>(current));
5250                 }
5251                 return result;
5252             }
5253 
5254             default:
5255             {
5256                 std::stringstream ss;
5257                 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5258                 JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + ss.str()));
5259             }
5260         }
5261     }
5262 
5263     template<typename NumberType>
get_cbor_array(const NumberType len)5264     BasicJsonType get_cbor_array(const NumberType len)
5265     {
5266         BasicJsonType result = value_t::array;
5267         std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
5268         {
5269             return parse_cbor_internal();
5270         });
5271         return result;
5272     }
5273 
5274     template<typename NumberType>
get_cbor_object(const NumberType len)5275     BasicJsonType get_cbor_object(const NumberType len)
5276     {
5277         BasicJsonType result = value_t::object;
5278         std::generate_n(std::inserter(*result.m_value.object,
5279                                       result.m_value.object->end()),
5280                         len, [this]()
5281         {
5282             get();
5283             auto key = get_cbor_string();
5284             auto val = parse_cbor_internal();
5285             return std::make_pair(std::move(key), std::move(val));
5286         });
5287         return result;
5288     }
5289 
5290     /*!
5291     @brief reads a MessagePack string
5292     This function first reads starting bytes to determine the expected
5293     string length and then copies this number of bytes into a string.
5294     @return string
5295     @throw parse_error.110 if input ended
5296     @throw parse_error.113 if an unexpected byte is read
5297     */
get_msgpack_string()5298     std::string get_msgpack_string()
5299     {
5300         check_eof();
5301 
5302         switch (current)
5303         {
5304             // fixstr
5305             case 0xa0:
5306             case 0xa1:
5307             case 0xa2:
5308             case 0xa3:
5309             case 0xa4:
5310             case 0xa5:
5311             case 0xa6:
5312             case 0xa7:
5313             case 0xa8:
5314             case 0xa9:
5315             case 0xaa:
5316             case 0xab:
5317             case 0xac:
5318             case 0xad:
5319             case 0xae:
5320             case 0xaf:
5321             case 0xb0:
5322             case 0xb1:
5323             case 0xb2:
5324             case 0xb3:
5325             case 0xb4:
5326             case 0xb5:
5327             case 0xb6:
5328             case 0xb7:
5329             case 0xb8:
5330             case 0xb9:
5331             case 0xba:
5332             case 0xbb:
5333             case 0xbc:
5334             case 0xbd:
5335             case 0xbe:
5336             case 0xbf:
5337             {
5338                 return get_string(current & 0x1f);
5339             }
5340 
5341             case 0xd9: // str 8
5342             {
5343                 return get_string(get_number<uint8_t>());
5344             }
5345 
5346             case 0xda: // str 16
5347             {
5348                 return get_string(get_number<uint16_t>());
5349             }
5350 
5351             case 0xdb: // str 32
5352             {
5353                 return get_string(get_number<uint32_t>());
5354             }
5355 
5356             default:
5357             {
5358                 std::stringstream ss;
5359                 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5360                 JSON_THROW(parse_error::create(113, chars_read,
5361                                                "expected a MessagePack string; last byte: 0x" + ss.str()));
5362             }
5363         }
5364     }
5365 
5366     template<typename NumberType>
get_msgpack_array(const NumberType len)5367     BasicJsonType get_msgpack_array(const NumberType len)
5368     {
5369         BasicJsonType result = value_t::array;
5370         std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
5371         {
5372             return parse_msgpack_internal();
5373         });
5374         return result;
5375     }
5376 
5377     template<typename NumberType>
get_msgpack_object(const NumberType len)5378     BasicJsonType get_msgpack_object(const NumberType len)
5379     {
5380         BasicJsonType result = value_t::object;
5381         std::generate_n(std::inserter(*result.m_value.object,
5382                                       result.m_value.object->end()),
5383                         len, [this]()
5384         {
5385             get();
5386             auto key = get_msgpack_string();
5387             auto val = parse_msgpack_internal();
5388             return std::make_pair(std::move(key), std::move(val));
5389         });
5390         return result;
5391     }
5392 
5393     /*!
5394     @brief check if input ended
5395     @throw parse_error.110 if input ended
5396     */
check_eof(const bool expect_eof=false) const5397     void check_eof(const bool expect_eof = false) const
5398     {
5399         if (expect_eof)
5400         {
5401             if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
5402             {
5403                 JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
5404             }
5405         }
5406         else
5407         {
5408             if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
5409             {
5410                 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5411             }
5412         }
5413     }
5414 
5415   private:
5416     /// input adapter
5417     input_adapter_t ia = nullptr;
5418 
5419     /// the current character
5420     int current = std::char_traits<char>::eof();
5421 
5422     /// the number of characters read
5423     std::size_t chars_read = 0;
5424 
5425     /// whether we can assume little endianess
5426     const bool is_little_endian = little_endianess();
5427 };
5428 
5429 /*!
5430 @brief serialization to CBOR and MessagePack values
5431 */
5432 template<typename BasicJsonType, typename CharType>
5433 class binary_writer
5434 {
5435   public:
5436     /*!
5437     @brief create a binary writer
5438     @param[in] adapter  output adapter to write to
5439     */
binary_writer(output_adapter_t<CharType> adapter)5440     explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
5441     {
5442         assert(oa);
5443     }
5444 
5445     /*!
5446     @brief[in] j  JSON value to serialize
5447     */
write_cbor(const BasicJsonType & j)5448     void write_cbor(const BasicJsonType& j)
5449     {
5450         switch (j.type())
5451         {
5452             case value_t::null:
5453             {
5454                 oa->write_character(static_cast<CharType>(0xf6));
5455                 break;
5456             }
5457 
5458             case value_t::boolean:
5459             {
5460                 oa->write_character(j.m_value.boolean
5461                                     ? static_cast<CharType>(0xf5)
5462                                     : static_cast<CharType>(0xf4));
5463                 break;
5464             }
5465 
5466             case value_t::number_integer:
5467             {
5468                 if (j.m_value.number_integer >= 0)
5469                 {
5470                     // CBOR does not differentiate between positive signed
5471                     // integers and unsigned integers. Therefore, we used the
5472                     // code from the value_t::number_unsigned case here.
5473                     if (j.m_value.number_integer <= 0x17)
5474                     {
5475                         write_number(static_cast<uint8_t>(j.m_value.number_integer));
5476                     }
5477                     else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
5478                     {
5479                         oa->write_character(static_cast<CharType>(0x18));
5480                         write_number(static_cast<uint8_t>(j.m_value.number_integer));
5481                     }
5482                     else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
5483                     {
5484                         oa->write_character(static_cast<CharType>(0x19));
5485                         write_number(static_cast<uint16_t>(j.m_value.number_integer));
5486                     }
5487                     else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
5488                     {
5489                         oa->write_character(static_cast<CharType>(0x1a));
5490                         write_number(static_cast<uint32_t>(j.m_value.number_integer));
5491                     }
5492                     else
5493                     {
5494                         oa->write_character(static_cast<CharType>(0x1b));
5495                         write_number(static_cast<uint64_t>(j.m_value.number_integer));
5496                     }
5497                 }
5498                 else
5499                 {
5500                     // The conversions below encode the sign in the first
5501                     // byte, and the value is converted to a positive number.
5502                     const auto positive_number = -1 - j.m_value.number_integer;
5503                     if (j.m_value.number_integer >= -24)
5504                     {
5505                         write_number(static_cast<uint8_t>(0x20 + positive_number));
5506                     }
5507                     else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
5508                     {
5509                         oa->write_character(static_cast<CharType>(0x38));
5510                         write_number(static_cast<uint8_t>(positive_number));
5511                     }
5512                     else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
5513                     {
5514                         oa->write_character(static_cast<CharType>(0x39));
5515                         write_number(static_cast<uint16_t>(positive_number));
5516                     }
5517                     else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
5518                     {
5519                         oa->write_character(static_cast<CharType>(0x3a));
5520                         write_number(static_cast<uint32_t>(positive_number));
5521                     }
5522                     else
5523                     {
5524                         oa->write_character(static_cast<CharType>(0x3b));
5525                         write_number(static_cast<uint64_t>(positive_number));
5526                     }
5527                 }
5528                 break;
5529             }
5530 
5531             case value_t::number_unsigned:
5532             {
5533                 if (j.m_value.number_unsigned <= 0x17)
5534                 {
5535                     write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
5536                 }
5537                 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5538                 {
5539                     oa->write_character(static_cast<CharType>(0x18));
5540                     write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
5541                 }
5542                 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5543                 {
5544                     oa->write_character(static_cast<CharType>(0x19));
5545                     write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
5546                 }
5547                 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5548                 {
5549                     oa->write_character(static_cast<CharType>(0x1a));
5550                     write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
5551                 }
5552                 else
5553                 {
5554                     oa->write_character(static_cast<CharType>(0x1b));
5555                     write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
5556                 }
5557                 break;
5558             }
5559 
5560             case value_t::number_float: // Double-Precision Float
5561             {
5562                 oa->write_character(static_cast<CharType>(0xfb));
5563                 write_number(j.m_value.number_float);
5564                 break;
5565             }
5566 
5567             case value_t::string:
5568             {
5569                 // step 1: write control byte and the string length
5570                 const auto N = j.m_value.string->size();
5571                 if (N <= 0x17)
5572                 {
5573                     write_number(static_cast<uint8_t>(0x60 + N));
5574                 }
5575                 else if (N <= 0xff)
5576                 {
5577                     oa->write_character(static_cast<CharType>(0x78));
5578                     write_number(static_cast<uint8_t>(N));
5579                 }
5580                 else if (N <= 0xffff)
5581                 {
5582                     oa->write_character(static_cast<CharType>(0x79));
5583                     write_number(static_cast<uint16_t>(N));
5584                 }
5585                 else if (N <= 0xffffffff)
5586                 {
5587                     oa->write_character(static_cast<CharType>(0x7a));
5588                     write_number(static_cast<uint32_t>(N));
5589                 }
5590                 // LCOV_EXCL_START
5591                 else if (N <= 0xffffffffffffffff)
5592                 {
5593                     oa->write_character(static_cast<CharType>(0x7b));
5594                     write_number(static_cast<uint64_t>(N));
5595                 }
5596                 // LCOV_EXCL_STOP
5597 
5598                 // step 2: write the string
5599                 oa->write_characters(
5600                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
5601                     j.m_value.string->size());
5602                 break;
5603             }
5604 
5605             case value_t::array:
5606             {
5607                 // step 1: write control byte and the array size
5608                 const auto N = j.m_value.array->size();
5609                 if (N <= 0x17)
5610                 {
5611                     write_number(static_cast<uint8_t>(0x80 + N));
5612                 }
5613                 else if (N <= 0xff)
5614                 {
5615                     oa->write_character(static_cast<CharType>(0x98));
5616                     write_number(static_cast<uint8_t>(N));
5617                 }
5618                 else if (N <= 0xffff)
5619                 {
5620                     oa->write_character(static_cast<CharType>(0x99));
5621                     write_number(static_cast<uint16_t>(N));
5622                 }
5623                 else if (N <= 0xffffffff)
5624                 {
5625                     oa->write_character(static_cast<CharType>(0x9a));
5626                     write_number(static_cast<uint32_t>(N));
5627                 }
5628                 // LCOV_EXCL_START
5629                 else if (N <= 0xffffffffffffffff)
5630                 {
5631                     oa->write_character(static_cast<CharType>(0x9b));
5632                     write_number(static_cast<uint64_t>(N));
5633                 }
5634                 // LCOV_EXCL_STOP
5635 
5636                 // step 2: write each element
5637                 for (const auto& el : *j.m_value.array)
5638                 {
5639                     write_cbor(el);
5640                 }
5641                 break;
5642             }
5643 
5644             case value_t::object:
5645             {
5646                 // step 1: write control byte and the object size
5647                 const auto N = j.m_value.object->size();
5648                 if (N <= 0x17)
5649                 {
5650                     write_number(static_cast<uint8_t>(0xa0 + N));
5651                 }
5652                 else if (N <= 0xff)
5653                 {
5654                     oa->write_character(static_cast<CharType>(0xb8));
5655                     write_number(static_cast<uint8_t>(N));
5656                 }
5657                 else if (N <= 0xffff)
5658                 {
5659                     oa->write_character(static_cast<CharType>(0xb9));
5660                     write_number(static_cast<uint16_t>(N));
5661                 }
5662                 else if (N <= 0xffffffff)
5663                 {
5664                     oa->write_character(static_cast<CharType>(0xba));
5665                     write_number(static_cast<uint32_t>(N));
5666                 }
5667                 // LCOV_EXCL_START
5668                 else if (N <= 0xffffffffffffffff)
5669                 {
5670                     oa->write_character(static_cast<CharType>(0xbb));
5671                     write_number(static_cast<uint64_t>(N));
5672                 }
5673                 // LCOV_EXCL_STOP
5674 
5675                 // step 2: write each element
5676                 for (const auto& el : *j.m_value.object)
5677                 {
5678                     write_cbor(el.first);
5679                     write_cbor(el.second);
5680                 }
5681                 break;
5682             }
5683 
5684             default:
5685                 break;
5686         }
5687     }
5688 
5689     /*!
5690     @brief[in] j  JSON value to serialize
5691     */
write_msgpack(const BasicJsonType & j)5692     void write_msgpack(const BasicJsonType& j)
5693     {
5694         switch (j.type())
5695         {
5696             case value_t::null: // nil
5697             {
5698                 oa->write_character(static_cast<CharType>(0xc0));
5699                 break;
5700             }
5701 
5702             case value_t::boolean: // true and false
5703             {
5704                 oa->write_character(j.m_value.boolean
5705                                     ? static_cast<CharType>(0xc3)
5706                                     : static_cast<CharType>(0xc2));
5707                 break;
5708             }
5709 
5710             case value_t::number_integer:
5711             {
5712                 if (j.m_value.number_integer >= 0)
5713                 {
5714                     // MessagePack does not differentiate between positive
5715                     // signed integers and unsigned integers. Therefore, we used
5716                     // the code from the value_t::number_unsigned case here.
5717                     if (j.m_value.number_unsigned < 128)
5718                     {
5719                         // positive fixnum
5720                         write_number(static_cast<uint8_t>(j.m_value.number_integer));
5721                     }
5722                     else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5723                     {
5724                         // uint 8
5725                         oa->write_character(static_cast<CharType>(0xcc));
5726                         write_number(static_cast<uint8_t>(j.m_value.number_integer));
5727                     }
5728                     else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5729                     {
5730                         // uint 16
5731                         oa->write_character(static_cast<CharType>(0xcd));
5732                         write_number(static_cast<uint16_t>(j.m_value.number_integer));
5733                     }
5734                     else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5735                     {
5736                         // uint 32
5737                         oa->write_character(static_cast<CharType>(0xce));
5738                         write_number(static_cast<uint32_t>(j.m_value.number_integer));
5739                     }
5740                     else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5741                     {
5742                         // uint 64
5743                         oa->write_character(static_cast<CharType>(0xcf));
5744                         write_number(static_cast<uint64_t>(j.m_value.number_integer));
5745                     }
5746                 }
5747                 else
5748                 {
5749                     if (j.m_value.number_integer >= -32)
5750                     {
5751                         // negative fixnum
5752                         write_number(static_cast<int8_t>(j.m_value.number_integer));
5753                     }
5754                     else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
5755                              j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
5756                     {
5757                         // int 8
5758                         oa->write_character(static_cast<CharType>(0xd0));
5759                         write_number(static_cast<int8_t>(j.m_value.number_integer));
5760                     }
5761                     else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
5762                              j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
5763                     {
5764                         // int 16
5765                         oa->write_character(static_cast<CharType>(0xd1));
5766                         write_number(static_cast<int16_t>(j.m_value.number_integer));
5767                     }
5768                     else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
5769                              j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
5770                     {
5771                         // int 32
5772                         oa->write_character(static_cast<CharType>(0xd2));
5773                         write_number(static_cast<int32_t>(j.m_value.number_integer));
5774                     }
5775                     else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
5776                              j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
5777                     {
5778                         // int 64
5779                         oa->write_character(static_cast<CharType>(0xd3));
5780                         write_number(static_cast<int64_t>(j.m_value.number_integer));
5781                     }
5782                 }
5783                 break;
5784             }
5785 
5786             case value_t::number_unsigned:
5787             {
5788                 if (j.m_value.number_unsigned < 128)
5789                 {
5790                     // positive fixnum
5791                     write_number(static_cast<uint8_t>(j.m_value.number_integer));
5792                 }
5793                 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5794                 {
5795                     // uint 8
5796                     oa->write_character(static_cast<CharType>(0xcc));
5797                     write_number(static_cast<uint8_t>(j.m_value.number_integer));
5798                 }
5799                 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5800                 {
5801                     // uint 16
5802                     oa->write_character(static_cast<CharType>(0xcd));
5803                     write_number(static_cast<uint16_t>(j.m_value.number_integer));
5804                 }
5805                 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5806                 {
5807                     // uint 32
5808                     oa->write_character(static_cast<CharType>(0xce));
5809                     write_number(static_cast<uint32_t>(j.m_value.number_integer));
5810                 }
5811                 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5812                 {
5813                     // uint 64
5814                     oa->write_character(static_cast<CharType>(0xcf));
5815                     write_number(static_cast<uint64_t>(j.m_value.number_integer));
5816                 }
5817                 break;
5818             }
5819 
5820             case value_t::number_float: // float 64
5821             {
5822                 oa->write_character(static_cast<CharType>(0xcb));
5823                 write_number(j.m_value.number_float);
5824                 break;
5825             }
5826 
5827             case value_t::string:
5828             {
5829                 // step 1: write control byte and the string length
5830                 const auto N = j.m_value.string->size();
5831                 if (N <= 31)
5832                 {
5833                     // fixstr
5834                     write_number(static_cast<uint8_t>(0xa0 | N));
5835                 }
5836                 else if (N <= 255)
5837                 {
5838                     // str 8
5839                     oa->write_character(static_cast<CharType>(0xd9));
5840                     write_number(static_cast<uint8_t>(N));
5841                 }
5842                 else if (N <= 65535)
5843                 {
5844                     // str 16
5845                     oa->write_character(static_cast<CharType>(0xda));
5846                     write_number(static_cast<uint16_t>(N));
5847                 }
5848                 else if (N <= 4294967295)
5849                 {
5850                     // str 32
5851                     oa->write_character(static_cast<CharType>(0xdb));
5852                     write_number(static_cast<uint32_t>(N));
5853                 }
5854 
5855                 // step 2: write the string
5856                 oa->write_characters(
5857                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
5858                     j.m_value.string->size());
5859                 break;
5860             }
5861 
5862             case value_t::array:
5863             {
5864                 // step 1: write control byte and the array size
5865                 const auto N = j.m_value.array->size();
5866                 if (N <= 15)
5867                 {
5868                     // fixarray
5869                     write_number(static_cast<uint8_t>(0x90 | N));
5870                 }
5871                 else if (N <= 0xffff)
5872                 {
5873                     // array 16
5874                     oa->write_character(static_cast<CharType>(0xdc));
5875                     write_number(static_cast<uint16_t>(N));
5876                 }
5877                 else if (N <= 0xffffffff)
5878                 {
5879                     // array 32
5880                     oa->write_character(static_cast<CharType>(0xdd));
5881                     write_number(static_cast<uint32_t>(N));
5882                 }
5883 
5884                 // step 2: write each element
5885                 for (const auto& el : *j.m_value.array)
5886                 {
5887                     write_msgpack(el);
5888                 }
5889                 break;
5890             }
5891 
5892             case value_t::object:
5893             {
5894                 // step 1: write control byte and the object size
5895                 const auto N = j.m_value.object->size();
5896                 if (N <= 15)
5897                 {
5898                     // fixmap
5899                     write_number(static_cast<uint8_t>(0x80 | (N & 0xf)));
5900                 }
5901                 else if (N <= 65535)
5902                 {
5903                     // map 16
5904                     oa->write_character(static_cast<CharType>(0xde));
5905                     write_number(static_cast<uint16_t>(N));
5906                 }
5907                 else if (N <= 4294967295)
5908                 {
5909                     // map 32
5910                     oa->write_character(static_cast<CharType>(0xdf));
5911                     write_number(static_cast<uint32_t>(N));
5912                 }
5913 
5914                 // step 2: write each element
5915                 for (const auto& el : *j.m_value.object)
5916                 {
5917                     write_msgpack(el.first);
5918                     write_msgpack(el.second);
5919                 }
5920                 break;
5921             }
5922 
5923             default:
5924                 break;
5925         }
5926     }
5927 
5928   private:
5929     /*
5930     @brief write a number to output input
5931     @param[in] n number of type @a NumberType
5932     @tparam NumberType the type of the number
5933     @note This function needs to respect the system's endianess, because bytes
5934           in CBOR and MessagePack are stored in network order (big endian) and
5935           therefore need reordering on little endian systems.
5936     */
write_number(NumberType n)5937     template<typename NumberType> void write_number(NumberType n)
5938     {
5939         // step 1: write number to array of length NumberType
5940         std::array<CharType, sizeof(NumberType)> vec;
5941         std::memcpy(vec.data(), &n, sizeof(NumberType));
5942 
5943         // step 2: write array to output (with possible reordering)
5944         if (is_little_endian)
5945         {
5946             // reverse byte order prior to conversion if necessary
5947             std::reverse(vec.begin(), vec.end());
5948         }
5949 
5950         oa->write_characters(vec.data(), sizeof(NumberType));
5951     }
5952 
5953   private:
5954     /// whether we can assume little endianess
5955     const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
5956 
5957     /// the output
5958     output_adapter_t<CharType> oa = nullptr;
5959 };
5960 
5961 ///////////////////
5962 // serialization //
5963 ///////////////////
5964 
5965 template<typename BasicJsonType>
5966 class serializer
5967 {
5968     using string_t = typename BasicJsonType::string_t;
5969     using number_float_t = typename BasicJsonType::number_float_t;
5970     using number_integer_t = typename BasicJsonType::number_integer_t;
5971     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5972   public:
5973     /*!
5974     @param[in] s  output stream to serialize to
5975     @param[in] ichar  indentation character to use
5976     */
serializer(output_adapter_t<char> s,const char ichar)5977     serializer(output_adapter_t<char> s, const char ichar)
5978         : o(std::move(s)), loc(std::localeconv()),
5979           thousands_sep(loc->thousands_sep == nullptr ? '\0' : loc->thousands_sep[0]),
5980           decimal_point(loc->decimal_point == nullptr ? '\0' : loc->decimal_point[0]),
5981           indent_char(ichar), indent_string(512, indent_char) {}
5982 
5983     // delete because of pointer members
5984     serializer(const serializer&) = delete;
5985     serializer& operator=(const serializer&) = delete;
5986 
5987     /*!
5988     @brief internal implementation of the serialization function
5989     This function is called by the public member function dump and organizes
5990     the serialization internally. The indentation level is propagated as
5991     additional parameter. In case of arrays and objects, the function is
5992     called recursively.
5993     - strings and object keys are escaped using `escape_string()`
5994     - integer numbers are converted implicitly via `operator<<`
5995     - floating-point numbers are converted to a string using `"%g"` format
5996     @param[in] val             value to serialize
5997     @param[in] pretty_print    whether the output shall be pretty-printed
5998     @param[in] indent_step     the indent level
5999     @param[in] current_indent  the current indent level (only used internally)
6000     */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)6001     void dump(const BasicJsonType& val, const bool pretty_print,
6002               const bool ensure_ascii,
6003               const unsigned int indent_step,
6004               const unsigned int current_indent = 0)
6005     {
6006         switch (val.m_type)
6007         {
6008             case value_t::object:
6009             {
6010                 if (val.m_value.object->empty())
6011                 {
6012                     o->write_characters("{}", 2);
6013                     return;
6014                 }
6015 
6016                 if (pretty_print)
6017                 {
6018                     o->write_characters("{\n", 2);
6019 
6020                     // variable to hold indentation for recursive calls
6021                     const auto new_indent = current_indent + indent_step;
6022                     if (JSON_UNLIKELY(indent_string.size() < new_indent))
6023                     {
6024                         indent_string.resize(indent_string.size() * 2, ' ');
6025                     }
6026 
6027                     // first n-1 elements
6028                     auto i = val.m_value.object->cbegin();
6029                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6030                     {
6031                         o->write_characters(indent_string.c_str(), new_indent);
6032                         o->write_character('\"');
6033                         dump_escaped(i->first, ensure_ascii);
6034                         o->write_characters("\": ", 3);
6035                         dump(i->second, true, ensure_ascii, indent_step, new_indent);
6036                         o->write_characters(",\n", 2);
6037                     }
6038 
6039                     // last element
6040                     assert(i != val.m_value.object->cend());
6041                     assert(std::next(i) == val.m_value.object->cend());
6042                     o->write_characters(indent_string.c_str(), new_indent);
6043                     o->write_character('\"');
6044                     dump_escaped(i->first, ensure_ascii);
6045                     o->write_characters("\": ", 3);
6046                     dump(i->second, true, ensure_ascii, indent_step, new_indent);
6047 
6048                     o->write_character('\n');
6049                     o->write_characters(indent_string.c_str(), current_indent);
6050                     o->write_character('}');
6051                 }
6052                 else
6053                 {
6054                     o->write_character('{');
6055 
6056                     // first n-1 elements
6057                     auto i = val.m_value.object->cbegin();
6058                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6059                     {
6060                         o->write_character('\"');
6061                         dump_escaped(i->first, ensure_ascii);
6062                         o->write_characters("\":", 2);
6063                         dump(i->second, false, ensure_ascii, indent_step, current_indent);
6064                         o->write_character(',');
6065                     }
6066 
6067                     // last element
6068                     assert(i != val.m_value.object->cend());
6069                     assert(std::next(i) == val.m_value.object->cend());
6070                     o->write_character('\"');
6071                     dump_escaped(i->first, ensure_ascii);
6072                     o->write_characters("\":", 2);
6073                     dump(i->second, false, ensure_ascii, indent_step, current_indent);
6074 
6075                     o->write_character('}');
6076                 }
6077 
6078                 return;
6079             }
6080 
6081             case value_t::array:
6082             {
6083                 if (val.m_value.array->empty())
6084                 {
6085                     o->write_characters("[]", 2);
6086                     return;
6087                 }
6088 
6089                 if (pretty_print)
6090                 {
6091                     o->write_characters("[\n", 2);
6092 
6093                     // variable to hold indentation for recursive calls
6094                     const auto new_indent = current_indent + indent_step;
6095                     if (JSON_UNLIKELY(indent_string.size() < new_indent))
6096                     {
6097                         indent_string.resize(indent_string.size() * 2, ' ');
6098                     }
6099 
6100                     // first n-1 elements
6101                     for (auto i = val.m_value.array->cbegin();
6102                             i != val.m_value.array->cend() - 1; ++i)
6103                     {
6104                         o->write_characters(indent_string.c_str(), new_indent);
6105                         dump(*i, true, ensure_ascii, indent_step, new_indent);
6106                         o->write_characters(",\n", 2);
6107                     }
6108 
6109                     // last element
6110                     assert(not val.m_value.array->empty());
6111                     o->write_characters(indent_string.c_str(), new_indent);
6112                     dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
6113 
6114                     o->write_character('\n');
6115                     o->write_characters(indent_string.c_str(), current_indent);
6116                     o->write_character(']');
6117                 }
6118                 else
6119                 {
6120                     o->write_character('[');
6121 
6122                     // first n-1 elements
6123                     for (auto i = val.m_value.array->cbegin();
6124                             i != val.m_value.array->cend() - 1; ++i)
6125                     {
6126                         dump(*i, false, ensure_ascii, indent_step, current_indent);
6127                         o->write_character(',');
6128                     }
6129 
6130                     // last element
6131                     assert(not val.m_value.array->empty());
6132                     dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
6133 
6134                     o->write_character(']');
6135                 }
6136 
6137                 return;
6138             }
6139 
6140             case value_t::string:
6141             {
6142                 o->write_character('\"');
6143                 dump_escaped(*val.m_value.string, ensure_ascii);
6144                 o->write_character('\"');
6145                 return;
6146             }
6147 
6148             case value_t::boolean:
6149             {
6150                 if (val.m_value.boolean)
6151                 {
6152                     o->write_characters("true", 4);
6153                 }
6154                 else
6155                 {
6156                     o->write_characters("false", 5);
6157                 }
6158                 return;
6159             }
6160 
6161             case value_t::number_integer:
6162             {
6163                 dump_integer(val.m_value.number_integer);
6164                 return;
6165             }
6166 
6167             case value_t::number_unsigned:
6168             {
6169                 dump_integer(val.m_value.number_unsigned);
6170                 return;
6171             }
6172 
6173             case value_t::number_float:
6174             {
6175                 dump_float(val.m_value.number_float);
6176                 return;
6177             }
6178 
6179             case value_t::discarded:
6180             {
6181                 o->write_characters("<discarded>", 11);
6182                 return;
6183             }
6184 
6185             case value_t::null:
6186             {
6187                 o->write_characters("null", 4);
6188                 return;
6189             }
6190         }
6191     }
6192 
6193   private:
6194     /*!
6195     @brief returns the number of expected bytes following in UTF-8 string
6196     @param[in]  u  the first byte of a UTF-8 string
6197     @return  the number of expected bytes following
6198     */
bytes_following(const uint8_t u)6199     static constexpr std::size_t bytes_following(const uint8_t u)
6200     {
6201         return ((u <= 127) ? 0
6202                 : ((192 <= u and u <= 223) ? 1
6203                    : ((224 <= u and u <= 239) ? 2
6204                       : ((240 <= u and u <= 247) ? 3 : std::string::npos))));
6205     }
6206 
6207     /*!
6208     @brief calculates the extra space to escape a JSON string
6209     @param[in] s  the string to escape
6210     @param[in] ensure_ascii  whether to escape non-ASCII characters with
6211                              \uXXXX sequences
6212     @return the number of characters required to escape string @a s
6213     @complexity Linear in the length of string @a s.
6214     */
extra_space(const string_t & s,const bool ensure_ascii)6215     static std::size_t extra_space(const string_t& s,
6216                                    const bool ensure_ascii) noexcept
6217     {
6218         std::size_t res = 0;
6219 
6220         for (std::size_t i = 0; i < s.size(); ++i)
6221         {
6222             switch (s[i])
6223             {
6224                 // control characters that can be escaped with a backslash
6225                 case '"':
6226                 case '\\':
6227                 case '\b':
6228                 case '\f':
6229                 case '\n':
6230                 case '\r':
6231                 case '\t':
6232                 {
6233                     // from c (1 byte) to \x (2 bytes)
6234                     res += 1;
6235                     break;
6236                 }
6237 
6238                 // control characters that need \uxxxx escaping
6239                 case 0x00:
6240                 case 0x01:
6241                 case 0x02:
6242                 case 0x03:
6243                 case 0x04:
6244                 case 0x05:
6245                 case 0x06:
6246                 case 0x07:
6247                 case 0x0b:
6248                 case 0x0e:
6249                 case 0x0f:
6250                 case 0x10:
6251                 case 0x11:
6252                 case 0x12:
6253                 case 0x13:
6254                 case 0x14:
6255                 case 0x15:
6256                 case 0x16:
6257                 case 0x17:
6258                 case 0x18:
6259                 case 0x19:
6260                 case 0x1a:
6261                 case 0x1b:
6262                 case 0x1c:
6263                 case 0x1d:
6264                 case 0x1e:
6265                 case 0x1f:
6266                 {
6267                     // from c (1 byte) to \uxxxx (6 bytes)
6268                     res += 5;
6269                     break;
6270                 }
6271 
6272                 default:
6273                 {
6274                     if (ensure_ascii and (s[i] & 0x80 or s[i] == 0x7F))
6275                     {
6276                         const auto bytes = bytes_following(static_cast<uint8_t>(s[i]));
6277                         if (bytes == std::string::npos)
6278                         {
6279                             // invalid characters are treated as is, so no
6280                             // additional space will be used
6281                             break;
6282                         }
6283 
6284                         if (bytes == 3)
6285                         {
6286                             // codepoints that need 4 bytes (i.e., 3 additional
6287                             // bytes) in UTF-8 need a surrogate pair when \u
6288                             // escaping is used: from 4 bytes to \uxxxx\uxxxx
6289                             // (12 bytes)
6290                             res += (12 - bytes - 1);
6291                         }
6292                         else
6293                         {
6294                             // from x bytes to \uxxxx (6 bytes)
6295                             res += (6 - bytes - 1);
6296                         }
6297 
6298                         // skip the additional bytes
6299                         i += bytes;
6300                     }
6301                     break;
6302                 }
6303             }
6304         }
6305 
6306         return res;
6307     }
6308 
escape_codepoint(int codepoint,string_t & result,std::size_t & pos)6309     static void escape_codepoint(int codepoint, string_t& result, std::size_t& pos)
6310     {
6311         // expecting a proper codepoint
6312         assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
6313 
6314         // the last written character was the backslash before the 'u'
6315         assert(result[pos] == '\\');
6316 
6317         // write the 'u'
6318         result[++pos] = 'u';
6319 
6320         // convert a number 0..15 to its hex representation (0..f)
6321         static const std::array<char, 16> hexify =
6322         {
6323             {
6324                 '0', '1', '2', '3', '4', '5', '6', '7',
6325                 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
6326             }
6327         };
6328 
6329         if (codepoint < 0x10000)
6330         {
6331             // codepoints U+0000..U+FFFF can be represented as \uxxxx.
6332             result[++pos] = hexify[(codepoint >> 12) & 0x0F];
6333             result[++pos] = hexify[(codepoint >> 8) & 0x0F];
6334             result[++pos] = hexify[(codepoint >> 4) & 0x0F];
6335             result[++pos] = hexify[codepoint & 0x0F];
6336         }
6337         else
6338         {
6339             // codepoints U+10000..U+10FFFF need a surrogate pair to be
6340             // represented as \uxxxx\uxxxx.
6341             // http://www.unicode.org/faq/utf_bom.html#utf16-4
6342             codepoint -= 0x10000;
6343             const int high_surrogate = 0xD800 | ((codepoint >> 10) & 0x3FF);
6344             const int low_surrogate = 0xDC00 | (codepoint & 0x3FF);
6345             result[++pos] = hexify[(high_surrogate >> 12) & 0x0F];
6346             result[++pos] = hexify[(high_surrogate >> 8) & 0x0F];
6347             result[++pos] = hexify[(high_surrogate >> 4) & 0x0F];
6348             result[++pos] = hexify[high_surrogate & 0x0F];
6349             ++pos;  // backslash is already in output
6350             result[++pos] = 'u';
6351             result[++pos] = hexify[(low_surrogate >> 12) & 0x0F];
6352             result[++pos] = hexify[(low_surrogate >> 8) & 0x0F];
6353             result[++pos] = hexify[(low_surrogate >> 4) & 0x0F];
6354             result[++pos] = hexify[low_surrogate & 0x0F];
6355         }
6356 
6357         ++pos;
6358     }
6359 
6360     /*!
6361     @brief dump escaped string
6362     Escape a string by replacing certain special characters by a sequence of an
6363     escape character (backslash) and another character and other control
6364     characters by a sequence of "\u" followed by a four-digit hex
6365     representation. The escaped string is written to output stream @a o.
6366     @param[in] s  the string to escape
6367     @param[in] ensure_ascii  whether to escape non-ASCII characters with
6368                              \uXXXX sequences
6369     @complexity Linear in the length of string @a s.
6370     */
dump_escaped(const string_t & s,const bool ensure_ascii) const6371     void dump_escaped(const string_t& s, const bool ensure_ascii) const
6372     {
6373         const auto space = extra_space(s, ensure_ascii);
6374         if (space == 0)
6375         {
6376             o->write_characters(s.c_str(), s.size());
6377             return;
6378         }
6379 
6380         // create a result string of necessary size
6381         string_t result(s.size() + space, '\\');
6382         std::size_t pos = 0;
6383 
6384         for (std::size_t i = 0; i < s.size(); ++i)
6385         {
6386             switch (s[i])
6387             {
6388                 case '"': // quotation mark (0x22)
6389                 {
6390                     result[pos + 1] = '"';
6391                     pos += 2;
6392                     break;
6393                 }
6394 
6395                 case '\\': // reverse solidus (0x5c)
6396                 {
6397                     // nothing to change
6398                     pos += 2;
6399                     break;
6400                 }
6401 
6402                 case '\b': // backspace (0x08)
6403                 {
6404                     result[pos + 1] = 'b';
6405                     pos += 2;
6406                     break;
6407                 }
6408 
6409                 case '\f': // formfeed (0x0c)
6410                 {
6411                     result[pos + 1] = 'f';
6412                     pos += 2;
6413                     break;
6414                 }
6415 
6416                 case '\n': // newline (0x0a)
6417                 {
6418                     result[pos + 1] = 'n';
6419                     pos += 2;
6420                     break;
6421                 }
6422 
6423                 case '\r': // carriage return (0x0d)
6424                 {
6425                     result[pos + 1] = 'r';
6426                     pos += 2;
6427                     break;
6428                 }
6429 
6430                 case '\t': // horizontal tab (0x09)
6431                 {
6432                     result[pos + 1] = 't';
6433                     pos += 2;
6434                     break;
6435                 }
6436 
6437                 default:
6438                 {
6439                     // escape control characters (0x00..0x1F) or, if
6440                     // ensure_ascii parameter is used, non-ASCII characters
6441                     if ((0x00 <= s[i] and s[i] <= 0x1F) or
6442                             (ensure_ascii and (s[i] & 0x80 or s[i] == 0x7F)))
6443                     {
6444                         const auto bytes = bytes_following(static_cast<uint8_t>(s[i]));
6445                         if (bytes == std::string::npos)
6446                         {
6447                             // copy invalid character as is
6448                             result[pos++] = s[i];
6449                             break;
6450                         }
6451 
6452                         // check that the additional bytes are present
6453                         assert(i + bytes < s.size());
6454 
6455                         // to use \uxxxx escaping, we first need to caluclate
6456                         // the codepoint from the UTF-8 bytes
6457                         int codepoint = 0;
6458 
6459                         assert(0 <= bytes and bytes <= 3);
6460                         switch (bytes)
6461                         {
6462                             case 0:
6463                             {
6464                                 codepoint = s[i] & 0xFF;
6465                                 break;
6466                             }
6467 
6468                             case 1:
6469                             {
6470                                 codepoint = ((s[i] & 0x3F) << 6)
6471                                             + (s[i + 1] & 0x7F);
6472                                 break;
6473                             }
6474 
6475                             case 2:
6476                             {
6477                                 codepoint = ((s[i] & 0x1F) << 12)
6478                                             + ((s[i + 1] & 0x7F) << 6)
6479                                             + (s[i + 2] & 0x7F);
6480                                 break;
6481                             }
6482 
6483                             case 3:
6484                             {
6485                                 codepoint = ((s[i] & 0xF) << 18)
6486                                             + ((s[i + 1] & 0x7F) << 12)
6487                                             + ((s[i + 2] & 0x7F) << 6)
6488                                             + (s[i + 3] & 0x7F);
6489                                 break;
6490                             }
6491 
6492                             default:
6493                                 break;  // LCOV_EXCL_LINE
6494                         }
6495 
6496                         escape_codepoint(codepoint, result, pos);
6497                         i += bytes;
6498                     }
6499                     else
6500                     {
6501                         // all other characters are added as-is
6502                         result[pos++] = s[i];
6503                     }
6504                     break;
6505                 }
6506             }
6507         }
6508 
6509         assert(pos == result.size());
6510         o->write_characters(result.c_str(), result.size());
6511     }
6512 
6513     /*!
6514     @brief dump an integer
6515     Dump a given integer to output stream @a o. Works internally with
6516     @a number_buffer.
6517     @param[in] x  integer number (signed or unsigned) to dump
6518     @tparam NumberType either @a number_integer_t or @a number_unsigned_t
6519     */
6520     template <
6521         typename NumberType,
6522         detail::enable_if_t<std::is_same<NumberType, number_unsigned_t>::value or
6523                             std::is_same<NumberType, number_integer_t>::value,
6524                             int> = 0 >
dump_integer(NumberType x)6525     void dump_integer(NumberType x)
6526     {
6527         // special case for "0"
6528         if (x == 0)
6529         {
6530             o->write_character('0');
6531             return;
6532         }
6533 
6534         const bool is_negative = (x <= 0) and (x != 0);  // see issue #755
6535         std::size_t i = 0;
6536 
6537         while (x != 0)
6538         {
6539             // spare 1 byte for '\0'
6540             assert(i < number_buffer.size() - 1);
6541 
6542             const auto digit = std::labs(static_cast<long>(x % 10));
6543             number_buffer[i++] = static_cast<char>('0' + digit);
6544             x /= 10;
6545         }
6546 
6547         if (is_negative)
6548         {
6549             // make sure there is capacity for the '-'
6550             assert(i < number_buffer.size() - 2);
6551             number_buffer[i++] = '-';
6552         }
6553 
6554         std::reverse(number_buffer.begin(), number_buffer.begin() + i);
6555         o->write_characters(number_buffer.data(), i);
6556     }
6557 
6558     /*!
6559     @brief dump a floating-point number
6560     Dump a given floating-point number to output stream @a o. Works internally
6561     with @a number_buffer.
6562     @param[in] x  floating-point number to dump
6563     */
dump_float(number_float_t x)6564     void dump_float(number_float_t x)
6565     {
6566         // NaN / inf
6567         if (not std::isfinite(x) or std::isnan(x))
6568         {
6569             o->write_characters("null", 4);
6570             return;
6571         }
6572 
6573         // get number of digits for a text -> float -> text round-trip
6574         static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
6575 
6576         // the actual conversion
6577         std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
6578 
6579         // negative value indicates an error
6580         assert(len > 0);
6581         // check if buffer was large enough
6582         assert(static_cast<std::size_t>(len) < number_buffer.size());
6583 
6584         // erase thousands separator
6585         if (thousands_sep != '\0')
6586         {
6587             const auto end = std::remove(number_buffer.begin(),
6588                                          number_buffer.begin() + len, thousands_sep);
6589             std::fill(end, number_buffer.end(), '\0');
6590             assert((end - number_buffer.begin()) <= len);
6591             len = (end - number_buffer.begin());
6592         }
6593 
6594         // convert decimal point to '.'
6595         if (decimal_point != '\0' and decimal_point != '.')
6596         {
6597             const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
6598             if (dec_pos != number_buffer.end())
6599             {
6600                 *dec_pos = '.';
6601             }
6602         }
6603 
6604         o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
6605 
6606         // determine if need to append ".0"
6607         const bool value_is_int_like =
6608             std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
6609                          [](char c)
6610         {
6611             return (c == '.' or c == 'e');
6612         });
6613 
6614         if (value_is_int_like)
6615         {
6616             o->write_characters(".0", 2);
6617         }
6618     }
6619 
6620   private:
6621     /// the output of the serializer
6622     output_adapter_t<char> o = nullptr;
6623 
6624     /// a (hopefully) large enough character buffer
6625     std::array<char, 64> number_buffer{{}};
6626 
6627     /// the locale
6628     const std::lconv* loc = nullptr;
6629     /// the locale's thousand separator character
6630     const char thousands_sep = '\0';
6631     /// the locale's decimal point character
6632     const char decimal_point = '\0';
6633 
6634     /// the indentation character
6635     const char indent_char;
6636 
6637     /// the indentation string
6638     string_t indent_string;
6639 };
6640 
6641 template<typename BasicJsonType>
6642 class json_ref
6643 {
6644   public:
6645     using value_type = BasicJsonType;
6646 
json_ref(value_type && value)6647     json_ref(value_type&& value)
6648         : owned_value(std::move(value)),
6649           value_ref(&owned_value),
6650           is_rvalue(true)
6651     {}
6652 
json_ref(const value_type & value)6653     json_ref(const value_type& value)
6654         : value_ref(const_cast<value_type*>(&value)),
6655           is_rvalue(false)
6656     {}
6657 
json_ref(std::initializer_list<json_ref> init)6658     json_ref(std::initializer_list<json_ref> init)
6659         : owned_value(init),
6660           value_ref(&owned_value),
6661           is_rvalue(true)
6662     {}
6663 
6664     template <class... Args>
json_ref(Args...args)6665     json_ref(Args... args)
6666         : owned_value(std::forward<Args>(args)...),
6667           value_ref(&owned_value),
6668           is_rvalue(true)
6669     {}
6670 
6671     // class should be movable only
6672     json_ref(json_ref&&) = default;
6673     json_ref(const json_ref&) = delete;
6674     json_ref& operator=(const json_ref&) = delete;
6675 
moved_or_copied() const6676     value_type moved_or_copied() const
6677     {
6678         if (is_rvalue)
6679         {
6680             return std::move(*value_ref);
6681         }
6682         return *value_ref;
6683     }
6684 
operator *() const6685     value_type const& operator*() const
6686     {
6687         return *static_cast<value_type const*>(value_ref);
6688     }
6689 
operator ->() const6690     value_type const* operator->() const
6691     {
6692         return static_cast<value_type const*>(value_ref);
6693     }
6694 
6695   private:
6696     mutable value_type owned_value = nullptr;
6697     value_type* value_ref = nullptr;
6698     const bool is_rvalue;
6699 };
6700 
6701 } // namespace detail
6702 
6703 /// namespace to hold default `to_json` / `from_json` functions
6704 namespace
6705 {
6706 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
6707 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
6708 }
6709 
6710 
6711 /*!
6712 @brief default JSONSerializer template argument
6713 This serializer ignores the template arguments and uses ADL
6714 ([argument-dependent lookup](http://en.cppreference.com/w/cpp/language/adl))
6715 for serialization.
6716 */
6717 template<typename, typename>
6718 struct adl_serializer
6719 {
6720     /*!
6721     @brief convert a JSON value to any value type
6722     This function is usually called by the `get()` function of the
6723     @ref basic_json class (either explicit or via conversion operators).
6724     @param[in] j         JSON value to read from
6725     @param[in,out] val  value to write to
6726     */
6727     template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer6728     static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
6729         noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
6730     {
6731         ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
6732     }
6733 
6734     /*!
6735     @brief convert any value type to a JSON value
6736     This function is usually called by the constructors of the @ref basic_json
6737     class.
6738     @param[in,out] j  JSON value to write to
6739     @param[in] val     value to read from
6740     */
6741     template<typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer6742     static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
6743         noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
6744     {
6745         ::nlohmann::to_json(j, std::forward<ValueType>(val));
6746     }
6747 };
6748 
6749 /*!
6750 @brief JSON Pointer
6751 A JSON pointer defines a string syntax for identifying a specific value
6752 within a JSON document. It can be used with functions `at` and
6753 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
6754 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
6755 @since version 2.0.0
6756 */
6757 class json_pointer
6758 {
6759     /// allow basic_json to access private members
6760     NLOHMANN_BASIC_JSON_TPL_DECLARATION
6761     friend class basic_json;
6762 
6763   public:
6764     /*!
6765     @brief create JSON pointer
6766     Create a JSON pointer according to the syntax described in
6767     [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
6768     @param[in] s  string representing the JSON pointer; if omitted, the empty
6769                   string is assumed which references the whole JSON value
6770     @throw parse_error.107 if the given JSON pointer @a s is nonempty and
6771     does not begin with a slash (`/`); see example below
6772     @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s
6773     is not followed by `0` (representing `~`) or `1` (representing `/`);
6774     see example below
6775     @liveexample{The example shows the construction several valid JSON
6776     pointers as well as the exceptional behavior.,json_pointer}
6777     @since version 2.0.0
6778     */
json_pointer(const std::string & s="")6779     explicit json_pointer(const std::string& s = "") : reference_tokens(split(s)) {}
6780 
6781     /*!
6782     @brief return a string representation of the JSON pointer
6783     @invariant For each JSON pointer `ptr`, it holds:
6784     @code {.cpp}
6785     ptr == json_pointer(ptr.to_string());
6786     @endcode
6787     @return a string representation of the JSON pointer
6788     @liveexample{The example shows the result of `to_string`.,
6789     json_pointer__to_string}
6790     @since version 2.0.0
6791     */
to_string() const6792     std::string to_string() const noexcept
6793     {
6794         return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
6795                                std::string{},
6796                                [](const std::string & a, const std::string & b)
6797         {
6798             return a + "/" + escape(b);
6799         });
6800     }
6801 
6802     /// @copydoc to_string()
operator std::string() const6803     operator std::string() const
6804     {
6805         return to_string();
6806     }
6807 
6808   private:
6809     /*!
6810     @brief remove and return last reference pointer
6811     @throw out_of_range.405 if JSON pointer has no parent
6812     */
pop_back()6813     std::string pop_back()
6814     {
6815         if (JSON_UNLIKELY(is_root()))
6816         {
6817             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
6818         }
6819 
6820         auto last = reference_tokens.back();
6821         reference_tokens.pop_back();
6822         return last;
6823     }
6824 
6825     /// return whether pointer points to the root document
is_root() const6826     bool is_root() const
6827     {
6828         return reference_tokens.empty();
6829     }
6830 
top() const6831     json_pointer top() const
6832     {
6833         if (JSON_UNLIKELY(is_root()))
6834         {
6835             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
6836         }
6837 
6838         json_pointer result = *this;
6839         result.reference_tokens = {reference_tokens[0]};
6840         return result;
6841     }
6842 
6843 
6844     /*!
6845     @brief create and return a reference to the pointed to value
6846     @complexity Linear in the number of reference tokens.
6847     @throw parse_error.109 if array index is not a number
6848     @throw type_error.313 if value cannot be unflattened
6849     */
6850     NLOHMANN_BASIC_JSON_TPL_DECLARATION
6851     NLOHMANN_BASIC_JSON_TPL& get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const;
6852 
6853     /*!
6854     @brief return a reference to the pointed to value
6855     @note This version does not throw if a value is not present, but tries to
6856           create nested values instead. For instance, calling this function
6857           with pointer `"/this/that"` on a null value is equivalent to calling
6858           `operator[]("this").operator[]("that")` on that value, effectively
6859           changing the null value to an object.
6860     @param[in] ptr  a JSON value
6861     @return reference to the JSON value pointed to by the JSON pointer
6862     @complexity Linear in the length of the JSON pointer.
6863     @throw parse_error.106   if an array index begins with '0'
6864     @throw parse_error.109   if an array index was not a number
6865     @throw out_of_range.404  if the JSON pointer can not be resolved
6866     */
6867     NLOHMANN_BASIC_JSON_TPL_DECLARATION
6868     NLOHMANN_BASIC_JSON_TPL& get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const;
6869 
6870     /*!
6871     @throw parse_error.106   if an array index begins with '0'
6872     @throw parse_error.109   if an array index was not a number
6873     @throw out_of_range.402  if the array index '-' is used
6874     @throw out_of_range.404  if the JSON pointer can not be resolved
6875     */
6876     NLOHMANN_BASIC_JSON_TPL_DECLARATION
6877     NLOHMANN_BASIC_JSON_TPL& get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const;
6878 
6879     /*!
6880     @brief return a const reference to the pointed to value
6881     @param[in] ptr  a JSON value
6882     @return const reference to the JSON value pointed to by the JSON
6883     pointer
6884     @throw parse_error.106   if an array index begins with '0'
6885     @throw parse_error.109   if an array index was not a number
6886     @throw out_of_range.402  if the array index '-' is used
6887     @throw out_of_range.404  if the JSON pointer can not be resolved
6888     */
6889     NLOHMANN_BASIC_JSON_TPL_DECLARATION
6890     const NLOHMANN_BASIC_JSON_TPL& get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const;
6891 
6892     /*!
6893     @throw parse_error.106   if an array index begins with '0'
6894     @throw parse_error.109   if an array index was not a number
6895     @throw out_of_range.402  if the array index '-' is used
6896     @throw out_of_range.404  if the JSON pointer can not be resolved
6897     */
6898     NLOHMANN_BASIC_JSON_TPL_DECLARATION
6899     const NLOHMANN_BASIC_JSON_TPL& get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const;
6900 
6901     /*!
6902     @brief split the string input to reference tokens
6903     @note This function is only called by the json_pointer constructor.
6904           All exceptions below are documented there.
6905     @throw parse_error.107  if the pointer is not empty or begins with '/'
6906     @throw parse_error.108  if character '~' is not followed by '0' or '1'
6907     */
split(const std::string & reference_string)6908     static std::vector<std::string> split(const std::string& reference_string)
6909     {
6910         std::vector<std::string> result;
6911 
6912         // special case: empty reference string -> no reference tokens
6913         if (reference_string.empty())
6914         {
6915             return result;
6916         }
6917 
6918         // check if nonempty reference string begins with slash
6919         if (JSON_UNLIKELY(reference_string[0] != '/'))
6920         {
6921             JSON_THROW(detail::parse_error::create(107, 1,
6922                                                    "JSON pointer must be empty or begin with '/' - was: '" +
6923                                                    reference_string + "'"));
6924         }
6925 
6926         // extract the reference tokens:
6927         // - slash: position of the last read slash (or end of string)
6928         // - start: position after the previous slash
6929         for (
6930             // search for the first slash after the first character
6931             std::size_t slash = reference_string.find_first_of('/', 1),
6932             // set the beginning of the first reference token
6933             start = 1;
6934             // we can stop if start == string::npos+1 = 0
6935             start != 0;
6936             // set the beginning of the next reference token
6937             // (will eventually be 0 if slash == std::string::npos)
6938             start = slash + 1,
6939             // find next slash
6940             slash = reference_string.find_first_of('/', start))
6941         {
6942             // use the text between the beginning of the reference token
6943             // (start) and the last slash (slash).
6944             auto reference_token = reference_string.substr(start, slash - start);
6945 
6946             // check reference tokens are properly escaped
6947             for (std::size_t pos = reference_token.find_first_of('~');
6948                     pos != std::string::npos;
6949                     pos = reference_token.find_first_of('~', pos + 1))
6950             {
6951                 assert(reference_token[pos] == '~');
6952 
6953                 // ~ must be followed by 0 or 1
6954                 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
6955                                   (reference_token[pos + 1] != '0' and
6956                                    reference_token[pos + 1] != '1')))
6957                 {
6958                     JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
6959                 }
6960             }
6961 
6962             // finally, store the reference token
6963             unescape(reference_token);
6964             result.push_back(reference_token);
6965         }
6966 
6967         return result;
6968     }
6969 
6970     /*!
6971     @brief replace all occurrences of a substring by another string
6972     @param[in,out] s  the string to manipulate; changed so that all
6973                    occurrences of @a f are replaced with @a t
6974     @param[in]     f  the substring to replace with @a t
6975     @param[in]     t  the string to replace @a f
6976     @pre The search string @a f must not be empty. **This precondition is
6977     enforced with an assertion.**
6978     @since version 2.0.0
6979     */
replace_substring(std::string & s,const std::string & f,const std::string & t)6980     static void replace_substring(std::string& s, const std::string& f,
6981                                   const std::string& t)
6982     {
6983         assert(not f.empty());
6984         for (auto pos = s.find(f);                // find first occurrence of f
6985                 pos != std::string::npos;         // make sure f was found
6986                 s.replace(pos, f.size(), t),      // replace with t, and
6987                 pos = s.find(f, pos + t.size()))  // find next occurrence of f
6988         {}
6989     }
6990 
6991     /// escape "~"" to "~0" and "/" to "~1"
escape(std::string s)6992     static std::string escape(std::string s)
6993     {
6994         replace_substring(s, "~", "~0");
6995         replace_substring(s, "/", "~1");
6996         return s;
6997     }
6998 
6999     /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)7000     static void unescape(std::string& s)
7001     {
7002         replace_substring(s, "~1", "/");
7003         replace_substring(s, "~0", "~");
7004     }
7005 
7006     /*!
7007     @param[in] reference_string  the reference string to the current value
7008     @param[in] value             the value to consider
7009     @param[in,out] result        the result object to insert values to
7010     @note Empty objects or arrays are flattened to `null`.
7011     */
7012     NLOHMANN_BASIC_JSON_TPL_DECLARATION
7013     static void flatten(const std::string& reference_string,
7014                         const NLOHMANN_BASIC_JSON_TPL& value,
7015                         NLOHMANN_BASIC_JSON_TPL& result);
7016 
7017     /*!
7018     @param[in] value  flattened JSON
7019     @return unflattened JSON
7020     @throw parse_error.109 if array index is not a number
7021     @throw type_error.314  if value is not an object
7022     @throw type_error.315  if object values are not primitive
7023     @throw type_error.313  if value cannot be unflattened
7024     */
7025     NLOHMANN_BASIC_JSON_TPL_DECLARATION
7026     static NLOHMANN_BASIC_JSON_TPL
7027     unflatten(const NLOHMANN_BASIC_JSON_TPL& value);
7028 
7029     friend bool operator==(json_pointer const& lhs,
7030                            json_pointer const& rhs) noexcept;
7031 
7032     friend bool operator!=(json_pointer const& lhs,
7033                            json_pointer const& rhs) noexcept;
7034 
7035     /// the reference tokens
7036     std::vector<std::string> reference_tokens;
7037 };
7038 
7039 /*!
7040 @brief a class to store JSON values
7041 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
7042 in @ref object_t)
7043 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
7044 in @ref array_t)
7045 @tparam StringType type for JSON strings and object keys (`std::string` by
7046 default; will be used in @ref string_t)
7047 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
7048 in @ref boolean_t)
7049 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
7050 default; will be used in @ref number_integer_t)
7051 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
7052 `uint64_t` by default; will be used in @ref number_unsigned_t)
7053 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
7054 default; will be used in @ref number_float_t)
7055 @tparam AllocatorType type of the allocator to use (`std::allocator` by
7056 default)
7057 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
7058 and `from_json()` (@ref adl_serializer by default)
7059 @requirement The class satisfies the following concept requirements:
7060 - Basic
7061  - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
7062    JSON values can be default constructed. The result will be a JSON null
7063    value.
7064  - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
7065    A JSON value can be constructed from an rvalue argument.
7066  - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
7067    A JSON value can be copy-constructed from an lvalue expression.
7068  - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
7069    A JSON value van be assigned from an rvalue argument.
7070  - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
7071    A JSON value can be copy-assigned from an lvalue expression.
7072  - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
7073    JSON values can be destructed.
7074 - Layout
7075  - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
7076    JSON values have
7077    [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
7078    All non-static data members are private and standard layout types, the
7079    class has no virtual functions or (virtual) base classes.
7080 - Library-wide
7081  - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
7082    JSON values can be compared with `==`, see @ref
7083    operator==(const_reference,const_reference).
7084  - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
7085    JSON values can be compared with `<`, see @ref
7086    operator<(const_reference,const_reference).
7087  - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
7088    Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
7089    other compatible types, using unqualified function call @ref swap().
7090  - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
7091    JSON values can be compared against `std::nullptr_t` objects which are used
7092    to model the `null` value.
7093 - Container
7094  - [Container](http://en.cppreference.com/w/cpp/concept/Container):
7095    JSON values can be used like STL containers and provide iterator access.
7096  - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
7097    JSON values can be used like STL containers and provide reverse iterator
7098    access.
7099 @invariant The member variables @a m_value and @a m_type have the following
7100 relationship:
7101 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
7102 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
7103 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
7104 The invariants are checked by member function assert_invariant().
7105 @internal
7106 @note ObjectType trick from http://stackoverflow.com/a/9860911
7107 @endinternal
7108 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
7109 Format](http://rfc7159.net/rfc7159)
7110 @since version 1.0.0
7111 @nosubgrouping
7112 */
7113 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7114 class basic_json
7115 {
7116   private:
7117     template<detail::value_t> friend struct detail::external_constructor;
7118     friend ::nlohmann::json_pointer;
7119     friend ::nlohmann::detail::parser<basic_json>;
7120     friend ::nlohmann::detail::serializer<basic_json>;
7121     template<typename BasicJsonType>
7122     friend class ::nlohmann::detail::iter_impl;
7123     template<typename BasicJsonType, typename CharType>
7124     friend class ::nlohmann::detail::binary_writer;
7125     template<typename BasicJsonType>
7126     friend class ::nlohmann::detail::binary_reader;
7127 
7128     /// workaround type for MSVC
7129     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
7130 
7131     // convenience aliases for types residing in namespace detail;
7132     using lexer = ::nlohmann::detail::lexer<basic_json>;
7133     using parser = ::nlohmann::detail::parser<basic_json>;
7134 
7135     using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
7136     template<typename BasicJsonType>
7137     using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
7138     template<typename BasicJsonType>
7139     using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
7140     template<typename Iterator>
7141     using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
7142     template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
7143 
7144     template<typename CharType>
7145     using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
7146 
7147     using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
7148     template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
7149 
7150     using serializer = ::nlohmann::detail::serializer<basic_json>;
7151 
7152   public:
7153     using value_t = detail::value_t;
7154     // forward declarations
7155     using json_pointer = ::nlohmann::json_pointer;
7156     template<typename T, typename SFINAE>
7157     using json_serializer = JSONSerializer<T, SFINAE>;
7158 
7159     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
7160 
7161     ////////////////
7162     // exceptions //
7163     ////////////////
7164 
7165     /// @name exceptions
7166     /// Classes to implement user-defined exceptions.
7167     /// @{
7168 
7169     /// @copydoc detail::exception
7170     using exception = detail::exception;
7171     /// @copydoc detail::parse_error
7172     using parse_error = detail::parse_error;
7173     /// @copydoc detail::invalid_iterator
7174     using invalid_iterator = detail::invalid_iterator;
7175     /// @copydoc detail::type_error
7176     using type_error = detail::type_error;
7177     /// @copydoc detail::out_of_range
7178     using out_of_range = detail::out_of_range;
7179     /// @copydoc detail::other_error
7180     using other_error = detail::other_error;
7181 
7182     /// @}
7183 
7184 
7185     /////////////////////
7186     // container types //
7187     /////////////////////
7188 
7189     /// @name container types
7190     /// The canonic container types to use @ref basic_json like any other STL
7191     /// container.
7192     /// @{
7193 
7194     /// the type of elements in a basic_json container
7195     using value_type = basic_json;
7196 
7197     /// the type of an element reference
7198     using reference = value_type&;
7199     /// the type of an element const reference
7200     using const_reference = const value_type&;
7201 
7202     /// a type to represent differences between iterators
7203     using difference_type = std::ptrdiff_t;
7204     /// a type to represent container sizes
7205     using size_type = std::size_t;
7206 
7207     /// the allocator type
7208     using allocator_type = AllocatorType<basic_json>;
7209 
7210     /// the type of an element pointer
7211     using pointer = typename std::allocator_traits<allocator_type>::pointer;
7212     /// the type of an element const pointer
7213     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
7214 
7215     /// an iterator for a basic_json container
7216     using iterator = iter_impl<basic_json>;
7217     /// a const iterator for a basic_json container
7218     using const_iterator = iter_impl<const basic_json>;
7219     /// a reverse iterator for a basic_json container
7220     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
7221     /// a const reverse iterator for a basic_json container
7222     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
7223 
7224     /// @}
7225 
7226 
7227     /*!
7228     @brief returns the allocator associated with the container
7229     */
get_allocator()7230     static allocator_type get_allocator()
7231     {
7232         return allocator_type();
7233     }
7234 
7235     /*!
7236     @brief returns version information on the library
7237     This function returns a JSON object with information about the library,
7238     including the version number and information on the platform and compiler.
7239     @return JSON object holding version information
7240     key         | description
7241     ----------- | ---------------
7242     `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).
7243     `copyright` | The copyright line for the library as string.
7244     `name`      | The name of the library as string.
7245     `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
7246     `url`       | The URL of the project as string.
7247     `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).
7248     @liveexample{The following code shows an example output of the `meta()`
7249     function.,meta}
7250     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
7251     changes to any JSON value.
7252     @complexity Constant.
7253     @since 2.1.0
7254     */
meta()7255     static basic_json meta()
7256     {
7257         basic_json result;
7258 
7259         result["copyright"] = "(C) 2013-2017 Niels Lohmann";
7260         result["name"] = "JSON for Modern C++";
7261         result["url"] = "https://github.com/nlohmann/json";
7262         result["version"] =
7263         {
7264             {"string", "2.1.1"}, {"major", 2}, {"minor", 1}, {"patch", 1}
7265         };
7266 
7267 #ifdef _WIN32
7268         result["platform"] = "win32";
7269 #elif defined __linux__
7270         result["platform"] = "linux";
7271 #elif defined __APPLE__
7272         result["platform"] = "apple";
7273 #elif defined __unix__
7274         result["platform"] = "unix";
7275 #else
7276         result["platform"] = "unknown";
7277 #endif
7278 
7279 #if defined(__ICC) || defined(__INTEL_COMPILER)
7280         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
7281 #elif defined(__clang__)
7282         result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
7283 #elif defined(__GNUC__) || defined(__GNUG__)
7284         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
7285 #elif defined(__HP_cc) || defined(__HP_aCC)
7286         result["compiler"] = "hp"
7287 #elif defined(__IBMCPP__)
7288         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
7289 #elif defined(_MSC_VER)
7290         result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
7291 #elif defined(__PGI)
7292         result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
7293 #elif defined(__SUNPRO_CC)
7294         result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
7295 #else
7296         result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
7297 #endif
7298 
7299 #ifdef __cplusplus
7300         result["compiler"]["c++"] = std::to_string(__cplusplus);
7301 #else
7302         result["compiler"]["c++"] = "unknown";
7303 #endif
7304         return result;
7305     }
7306 
7307 
7308     ///////////////////////////
7309     // JSON value data types //
7310     ///////////////////////////
7311 
7312     /// @name JSON value data types
7313     /// The data types to store a JSON value. These types are derived from
7314     /// the template arguments passed to class @ref basic_json.
7315     /// @{
7316 
7317     /*!
7318     @brief a type for an object
7319     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
7320     > An object is an unordered collection of zero or more name/value pairs,
7321     > where a name is a string and a value is a string, number, boolean, null,
7322     > object, or array.
7323     To store objects in C++, a type is defined by the template parameters
7324     described below.
7325     @tparam ObjectType  the container to store objects (e.g., `std::map` or
7326     `std::unordered_map`)
7327     @tparam StringType the type of the keys or names (e.g., `std::string`).
7328     The comparison function `std::less<StringType>` is used to order elements
7329     inside the container.
7330     @tparam AllocatorType the allocator to use for objects (e.g.,
7331     `std::allocator`)
7332     #### Default type
7333     With the default values for @a ObjectType (`std::map`), @a StringType
7334     (`std::string`), and @a AllocatorType (`std::allocator`), the default
7335     value for @a object_t is:
7336     @code {.cpp}
7337     std::map<
7338       std::string, // key_type
7339       basic_json, // value_type
7340       std::less<std::string>, // key_compare
7341       std::allocator<std::pair<const std::string, basic_json>> // allocator_type
7342     >
7343     @endcode
7344     #### Behavior
7345     The choice of @a object_t influences the behavior of the JSON class. With
7346     the default type, objects have the following behavior:
7347     - When all names are unique, objects will be interoperable in the sense
7348       that all software implementations receiving that object will agree on
7349       the name-value mappings.
7350     - When the names within an object are not unique, later stored name/value
7351       pairs overwrite previously stored name/value pairs, leaving the used
7352       names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will
7353       be treated as equal and both stored as `{"key": 1}`.
7354     - Internally, name/value pairs are stored in lexicographical order of the
7355       names. Objects will also be serialized (see @ref dump) in this order.
7356       For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
7357       and serialized as `{"a": 2, "b": 1}`.
7358     - When comparing objects, the order of the name/value pairs is irrelevant.
7359       This makes objects interoperable in the sense that they will not be
7360       affected by these differences. For instance, `{"b": 1, "a": 2}` and
7361       `{"a": 2, "b": 1}` will be treated as equal.
7362     #### Limits
7363     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7364     > An implementation may set limits on the maximum depth of nesting.
7365     In this class, the object's limit of nesting is not explicitly constrained.
7366     However, a maximum depth of nesting may be introduced by the compiler or
7367     runtime environment. A theoretical limit can be queried by calling the
7368     @ref max_size function of a JSON object.
7369     #### Storage
7370     Objects are stored as pointers in a @ref basic_json type. That is, for any
7371     access to object values, a pointer of type `object_t*` must be
7372     dereferenced.
7373     @sa @ref array_t -- type for an array value
7374     @since version 1.0.0
7375     @note The order name/value pairs are added to the object is *not*
7376     preserved by the library. Therefore, iterating an object may return
7377     name/value pairs in a different order than they were originally stored. In
7378     fact, keys will be traversed in alphabetical order as `std::map` with
7379     `std::less` is used by default. Please note this behavior conforms to [RFC
7380     7159](http://rfc7159.net/rfc7159), because any order implements the
7381     specified "unordered" nature of JSON objects.
7382     */
7383 
7384 #if defined(JSON_HAS_CPP_14)
7385     // Use transparent comparator if possible, combined with perfect forwarding
7386     // on find() and count() calls prevents unnecessary string construction.
7387     using object_comparator_t = std::less<>;
7388 #else
7389     using object_comparator_t = std::less<StringType>;
7390 #endif
7391     using object_t = ObjectType<StringType,
7392           basic_json,
7393           object_comparator_t,
7394           AllocatorType<std::pair<const StringType,
7395           basic_json>>>;
7396 
7397     /*!
7398     @brief a type for an array
7399     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
7400     > An array is an ordered sequence of zero or more values.
7401     To store objects in C++, a type is defined by the template parameters
7402     explained below.
7403     @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
7404     `std::list`)
7405     @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
7406     #### Default type
7407     With the default values for @a ArrayType (`std::vector`) and @a
7408     AllocatorType (`std::allocator`), the default value for @a array_t is:
7409     @code {.cpp}
7410     std::vector<
7411       basic_json, // value_type
7412       std::allocator<basic_json> // allocator_type
7413     >
7414     @endcode
7415     #### Limits
7416     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7417     > An implementation may set limits on the maximum depth of nesting.
7418     In this class, the array's limit of nesting is not explicitly constrained.
7419     However, a maximum depth of nesting may be introduced by the compiler or
7420     runtime environment. A theoretical limit can be queried by calling the
7421     @ref max_size function of a JSON array.
7422     #### Storage
7423     Arrays are stored as pointers in a @ref basic_json type. That is, for any
7424     access to array values, a pointer of type `array_t*` must be dereferenced.
7425     @sa @ref object_t -- type for an object value
7426     @since version 1.0.0
7427     */
7428     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
7429 
7430     /*!
7431     @brief a type for a string
7432     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
7433     > A string is a sequence of zero or more Unicode characters.
7434     To store objects in C++, a type is defined by the template parameter
7435     described below. Unicode values are split by the JSON class into
7436     byte-sized characters during deserialization.
7437     @tparam StringType  the container to store strings (e.g., `std::string`).
7438     Note this container is used for keys/names in objects, see @ref object_t.
7439     #### Default type
7440     With the default values for @a StringType (`std::string`), the default
7441     value for @a string_t is:
7442     @code {.cpp}
7443     std::string
7444     @endcode
7445     #### Encoding
7446     Strings are stored in UTF-8 encoding. Therefore, functions like
7447     `std::string::size()` or `std::string::length()` return the number of
7448     bytes in the string rather than the number of characters or glyphs.
7449     #### String comparison
7450     [RFC 7159](http://rfc7159.net/rfc7159) states:
7451     > Software implementations are typically required to test names of object
7452     > members for equality. Implementations that transform the textual
7453     > representation into sequences of Unicode code units and then perform the
7454     > comparison numerically, code unit by code unit, are interoperable in the
7455     > sense that implementations will agree in all cases on equality or
7456     > inequality of two strings. For example, implementations that compare
7457     > strings with escaped characters unconverted may incorrectly find that
7458     > `"a\\b"` and `"a\u005Cb"` are not equal.
7459     This implementation is interoperable as it does compare strings code unit
7460     by code unit.
7461     #### Storage
7462     String values are stored as pointers in a @ref basic_json type. That is,
7463     for any access to string values, a pointer of type `string_t*` must be
7464     dereferenced.
7465     @since version 1.0.0
7466     */
7467     using string_t = StringType;
7468 
7469     /*!
7470     @brief a type for a boolean
7471     [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
7472     type which differentiates the two literals `true` and `false`.
7473     To store objects in C++, a type is defined by the template parameter @a
7474     BooleanType which chooses the type to use.
7475     #### Default type
7476     With the default values for @a BooleanType (`bool`), the default value for
7477     @a boolean_t is:
7478     @code {.cpp}
7479     bool
7480     @endcode
7481     #### Storage
7482     Boolean values are stored directly inside a @ref basic_json type.
7483     @since version 1.0.0
7484     */
7485     using boolean_t = BooleanType;
7486 
7487     /*!
7488     @brief a type for a number (integer)
7489     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7490     > The representation of numbers is similar to that used in most
7491     > programming languages. A number is represented in base 10 using decimal
7492     > digits. It contains an integer component that may be prefixed with an
7493     > optional minus sign, which may be followed by a fraction part and/or an
7494     > exponent part. Leading zeros are not allowed. (...) Numeric values that
7495     > cannot be represented in the grammar below (such as Infinity and NaN)
7496     > are not permitted.
7497     This description includes both integer and floating-point numbers.
7498     However, C++ allows more precise storage if it is known whether the number
7499     is a signed integer, an unsigned integer or a floating-point number.
7500     Therefore, three different types, @ref number_integer_t, @ref
7501     number_unsigned_t and @ref number_float_t are used.
7502     To store integer numbers in C++, a type is defined by the template
7503     parameter @a NumberIntegerType which chooses the type to use.
7504     #### Default type
7505     With the default values for @a NumberIntegerType (`int64_t`), the default
7506     value for @a number_integer_t is:
7507     @code {.cpp}
7508     int64_t
7509     @endcode
7510     #### Default behavior
7511     - The restrictions about leading zeros is not enforced in C++. Instead,
7512       leading zeros in integer literals lead to an interpretation as octal
7513       number. Internally, the value will be stored as decimal number. For
7514       instance, the C++ integer literal `010` will be serialized to `8`.
7515       During deserialization, leading zeros yield an error.
7516     - Not-a-number (NaN) values will be serialized to `null`.
7517     #### Limits
7518     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7519     > An implementation may set limits on the range and precision of numbers.
7520     When the default type is used, the maximal integer number that can be
7521     stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
7522     that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
7523     that are out of range will yield over/underflow when used in a
7524     constructor. During deserialization, too large or small integer numbers
7525     will be automatically be stored as @ref number_unsigned_t or @ref
7526     number_float_t.
7527     [RFC 7159](http://rfc7159.net/rfc7159) further states:
7528     > Note that when such software is used, numbers that are integers and are
7529     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
7530     > that implementations will agree exactly on their numeric values.
7531     As this range is a subrange of the exactly supported range [INT64_MIN,
7532     INT64_MAX], this class's integer type is interoperable.
7533     #### Storage
7534     Integer number values are stored directly inside a @ref basic_json type.
7535     @sa @ref number_float_t -- type for number values (floating-point)
7536     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
7537     @since version 1.0.0
7538     */
7539     using number_integer_t = NumberIntegerType;
7540 
7541     /*!
7542     @brief a type for a number (unsigned)
7543     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7544     > The representation of numbers is similar to that used in most
7545     > programming languages. A number is represented in base 10 using decimal
7546     > digits. It contains an integer component that may be prefixed with an
7547     > optional minus sign, which may be followed by a fraction part and/or an
7548     > exponent part. Leading zeros are not allowed. (...) Numeric values that
7549     > cannot be represented in the grammar below (such as Infinity and NaN)
7550     > are not permitted.
7551     This description includes both integer and floating-point numbers.
7552     However, C++ allows more precise storage if it is known whether the number
7553     is a signed integer, an unsigned integer or a floating-point number.
7554     Therefore, three different types, @ref number_integer_t, @ref
7555     number_unsigned_t and @ref number_float_t are used.
7556     To store unsigned integer numbers in C++, a type is defined by the
7557     template parameter @a NumberUnsignedType which chooses the type to use.
7558     #### Default type
7559     With the default values for @a NumberUnsignedType (`uint64_t`), the
7560     default value for @a number_unsigned_t is:
7561     @code {.cpp}
7562     uint64_t
7563     @endcode
7564     #### Default behavior
7565     - The restrictions about leading zeros is not enforced in C++. Instead,
7566       leading zeros in integer literals lead to an interpretation as octal
7567       number. Internally, the value will be stored as decimal number. For
7568       instance, the C++ integer literal `010` will be serialized to `8`.
7569       During deserialization, leading zeros yield an error.
7570     - Not-a-number (NaN) values will be serialized to `null`.
7571     #### Limits
7572     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7573     > An implementation may set limits on the range and precision of numbers.
7574     When the default type is used, the maximal integer number that can be
7575     stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
7576     number that can be stored is `0`. Integer numbers that are out of range
7577     will yield over/underflow when used in a constructor. During
7578     deserialization, too large or small integer numbers will be automatically
7579     be stored as @ref number_integer_t or @ref number_float_t.
7580     [RFC 7159](http://rfc7159.net/rfc7159) further states:
7581     > Note that when such software is used, numbers that are integers and are
7582     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
7583     > that implementations will agree exactly on their numeric values.
7584     As this range is a subrange (when considered in conjunction with the
7585     number_integer_t type) of the exactly supported range [0, UINT64_MAX],
7586     this class's integer type is interoperable.
7587     #### Storage
7588     Integer number values are stored directly inside a @ref basic_json type.
7589     @sa @ref number_float_t -- type for number values (floating-point)
7590     @sa @ref number_integer_t -- type for number values (integer)
7591     @since version 2.0.0
7592     */
7593     using number_unsigned_t = NumberUnsignedType;
7594 
7595     /*!
7596     @brief a type for a number (floating-point)
7597     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7598     > The representation of numbers is similar to that used in most
7599     > programming languages. A number is represented in base 10 using decimal
7600     > digits. It contains an integer component that may be prefixed with an
7601     > optional minus sign, which may be followed by a fraction part and/or an
7602     > exponent part. Leading zeros are not allowed. (...) Numeric values that
7603     > cannot be represented in the grammar below (such as Infinity and NaN)
7604     > are not permitted.
7605     This description includes both integer and floating-point numbers.
7606     However, C++ allows more precise storage if it is known whether the number
7607     is a signed integer, an unsigned integer or a floating-point number.
7608     Therefore, three different types, @ref number_integer_t, @ref
7609     number_unsigned_t and @ref number_float_t are used.
7610     To store floating-point numbers in C++, a type is defined by the template
7611     parameter @a NumberFloatType which chooses the type to use.
7612     #### Default type
7613     With the default values for @a NumberFloatType (`double`), the default
7614     value for @a number_float_t is:
7615     @code {.cpp}
7616     double
7617     @endcode
7618     #### Default behavior
7619     - The restrictions about leading zeros is not enforced in C++. Instead,
7620       leading zeros in floating-point literals will be ignored. Internally,
7621       the value will be stored as decimal number. For instance, the C++
7622       floating-point literal `01.2` will be serialized to `1.2`. During
7623       deserialization, leading zeros yield an error.
7624     - Not-a-number (NaN) values will be serialized to `null`.
7625     #### Limits
7626     [RFC 7159](http://rfc7159.net/rfc7159) states:
7627     > This specification allows implementations to set limits on the range and
7628     > precision of numbers accepted. Since software that implements IEEE
7629     > 754-2008 binary64 (double precision) numbers is generally available and
7630     > widely used, good interoperability can be achieved by implementations
7631     > that expect no more precision or range than these provide, in the sense
7632     > that implementations will approximate JSON numbers within the expected
7633     > precision.
7634     This implementation does exactly follow this approach, as it uses double
7635     precision floating-point numbers. Note values smaller than
7636     `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
7637     will be stored as NaN internally and be serialized to `null`.
7638     #### Storage
7639     Floating-point number values are stored directly inside a @ref basic_json
7640     type.
7641     @sa @ref number_integer_t -- type for number values (integer)
7642     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
7643     @since version 1.0.0
7644     */
7645     using number_float_t = NumberFloatType;
7646 
7647     /// @}
7648 
7649   private:
7650 
7651     /// helper for exception-safe object creation
7652     template<typename T, typename... Args>
create(Args &&...args)7653     static T* create(Args&& ... args)
7654     {
7655         AllocatorType<T> alloc;
7656         auto deleter = [&](T * object)
7657         {
7658             alloc.deallocate(object, 1);
7659         };
7660         std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
7661         alloc.construct(object.get(), std::forward<Args>(args)...);
7662         assert(object != nullptr);
7663         return object.release();
7664     }
7665 
7666     ////////////////////////
7667     // JSON value storage //
7668     ////////////////////////
7669 
7670     /*!
7671     @brief a JSON value
7672     The actual storage for a JSON value of the @ref basic_json class. This
7673     union combines the different storage types for the JSON value types
7674     defined in @ref value_t.
7675     JSON type | value_t type    | used type
7676     --------- | --------------- | ------------------------
7677     object    | object          | pointer to @ref object_t
7678     array     | array           | pointer to @ref array_t
7679     string    | string          | pointer to @ref string_t
7680     boolean   | boolean         | @ref boolean_t
7681     number    | number_integer  | @ref number_integer_t
7682     number    | number_unsigned | @ref number_unsigned_t
7683     number    | number_float    | @ref number_float_t
7684     null      | null            | *no value is stored*
7685     @note Variable-length types (objects, arrays, and strings) are stored as
7686     pointers. The size of the union should not exceed 64 bits if the default
7687     value types are used.
7688     @since version 1.0.0
7689     */
7690     union json_value
7691     {
7692         /// object (stored with pointer to save storage)
7693         object_t* object;
7694         /// array (stored with pointer to save storage)
7695         array_t* array;
7696         /// string (stored with pointer to save storage)
7697         string_t* string;
7698         /// boolean
7699         boolean_t boolean;
7700         /// number (integer)
7701         number_integer_t number_integer;
7702         /// number (unsigned integer)
7703         number_unsigned_t number_unsigned;
7704         /// number (floating-point)
7705         number_float_t number_float;
7706 
7707         /// default constructor (for null values)
7708         json_value() = default;
7709         /// constructor for booleans
json_value(boolean_t v)7710         json_value(boolean_t v) noexcept : boolean(v) {}
7711         /// constructor for numbers (integer)
json_value(number_integer_t v)7712         json_value(number_integer_t v) noexcept : number_integer(v) {}
7713         /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)7714         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
7715         /// constructor for numbers (floating-point)
json_value(number_float_t v)7716         json_value(number_float_t v) noexcept : number_float(v) {}
7717         /// constructor for empty values of a given type
json_value(value_t t)7718         json_value(value_t t)
7719         {
7720             switch (t)
7721             {
7722                 case value_t::object:
7723                 {
7724                     object = create<object_t>();
7725                     break;
7726                 }
7727 
7728                 case value_t::array:
7729                 {
7730                     array = create<array_t>();
7731                     break;
7732                 }
7733 
7734                 case value_t::string:
7735                 {
7736                     string = create<string_t>("");
7737                     break;
7738                 }
7739 
7740                 case value_t::boolean:
7741                 {
7742                     boolean = boolean_t(false);
7743                     break;
7744                 }
7745 
7746                 case value_t::number_integer:
7747                 {
7748                     number_integer = number_integer_t(0);
7749                     break;
7750                 }
7751 
7752                 case value_t::number_unsigned:
7753                 {
7754                     number_unsigned = number_unsigned_t(0);
7755                     break;
7756                 }
7757 
7758                 case value_t::number_float:
7759                 {
7760                     number_float = number_float_t(0.0);
7761                     break;
7762                 }
7763 
7764                 case value_t::null:
7765                 {
7766                     break;
7767                 }
7768 
7769                 default:
7770                 {
7771                     if (JSON_UNLIKELY(t == value_t::null))
7772                     {
7773                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
7774                     }
7775                     break;
7776                 }
7777             }
7778         }
7779 
7780         /// constructor for strings
json_value(const string_t & value)7781         json_value(const string_t& value)
7782         {
7783             string = create<string_t>(value);
7784         }
7785 
7786         /// constructor for rvalue strings
json_value(string_t && value)7787         json_value(string_t&& value)
7788         {
7789             string = create<string_t>(std::move(value));
7790         }
7791 
7792         /// constructor for objects
json_value(const object_t & value)7793         json_value(const object_t& value)
7794         {
7795             object = create<object_t>(value);
7796         }
7797 
7798         /// constructor for rvalue objects
json_value(object_t && value)7799         json_value(object_t&& value)
7800         {
7801             object = create<object_t>(std::move(value));
7802         }
7803 
7804         /// constructor for arrays
json_value(const array_t & value)7805         json_value(const array_t& value)
7806         {
7807             array = create<array_t>(value);
7808         }
7809 
7810         /// constructor for rvalue arrays
json_value(array_t && value)7811         json_value(array_t&& value)
7812         {
7813             array = create<array_t>(std::move(value));
7814         }
7815 
destroy(value_t t)7816         void destroy(value_t t)
7817         {
7818             switch (t)
7819             {
7820                 case value_t::object:
7821                 {
7822                     AllocatorType<object_t> alloc;
7823                     alloc.destroy(object);
7824                     alloc.deallocate(object, 1);
7825                     break;
7826                 }
7827 
7828                 case value_t::array:
7829                 {
7830                     AllocatorType<array_t> alloc;
7831                     alloc.destroy(array);
7832                     alloc.deallocate(array, 1);
7833                     break;
7834                 }
7835 
7836                 case value_t::string:
7837                 {
7838                     AllocatorType<string_t> alloc;
7839                     alloc.destroy(string);
7840                     alloc.deallocate(string, 1);
7841                     break;
7842                 }
7843 
7844                 default:
7845                 {
7846                     break;
7847                 }
7848             }
7849         }
7850     };
7851 
7852     /*!
7853     @brief checks the class invariants
7854     This function asserts the class invariants. It needs to be called at the
7855     end of every constructor to make sure that created objects respect the
7856     invariant. Furthermore, it has to be called each time the type of a JSON
7857     value is changed, because the invariant expresses a relationship between
7858     @a m_type and @a m_value.
7859     */
assert_invariant() const7860     void assert_invariant() const
7861     {
7862         assert(m_type != value_t::object or m_value.object != nullptr);
7863         assert(m_type != value_t::array or m_value.array != nullptr);
7864         assert(m_type != value_t::string or m_value.string != nullptr);
7865     }
7866 
7867   public:
7868     //////////////////////////
7869     // JSON parser callback //
7870     //////////////////////////
7871 
7872     using parse_event_t = typename parser::parse_event_t;
7873 
7874     /*!
7875     @brief per-element parser callback type
7876     With a parser callback function, the result of parsing a JSON text can be
7877     influenced. When passed to @ref parse, it is called on certain events
7878     (passed as @ref parse_event_t via parameter @a event) with a set recursion
7879     depth @a depth and context JSON value @a parsed. The return value of the
7880     callback function is a boolean indicating whether the element that emitted
7881     the callback shall be kept or not.
7882     We distinguish six scenarios (determined by the event type) in which the
7883     callback function can be called. The following table describes the values
7884     of the parameters @a depth, @a event, and @a parsed.
7885     parameter @a event | description | parameter @a depth | parameter @a parsed
7886     ------------------ | ----------- | ------------------ | -------------------
7887     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
7888     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
7889     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
7890     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
7891     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
7892     parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
7893     @image html callback_events.png "Example when certain parse events are triggered"
7894     Discarding a value (i.e., returning `false`) has different effects
7895     depending on the context in which function was called:
7896     - Discarded values in structured types are skipped. That is, the parser
7897       will behave as if the discarded value was never read.
7898     - In case a value outside a structured type is skipped, it is replaced
7899       with `null`. This case happens if the top-level element is skipped.
7900     @param[in] depth  the depth of the recursion during parsing
7901     @param[in] event  an event of type parse_event_t indicating the context in
7902     the callback function has been called
7903     @param[in,out] parsed  the current intermediate parse result; note that
7904     writing to this value has no effect for parse_event_t::key events
7905     @return Whether the JSON value which called the function during parsing
7906     should be kept (`true`) or not (`false`). In the latter case, it is either
7907     skipped completely or replaced by an empty discarded object.
7908     @sa @ref parse for examples
7909     @since version 1.0.0
7910     */
7911     using parser_callback_t = typename parser::parser_callback_t;
7912 
7913 
7914     //////////////////
7915     // constructors //
7916     //////////////////
7917 
7918     /// @name constructors and destructors
7919     /// Constructors of class @ref basic_json, copy/move constructor, copy
7920     /// assignment, static functions creating objects, and the destructor.
7921     /// @{
7922 
7923     /*!
7924     @brief create an empty value with a given type
7925     Create an empty JSON value with a given type. The value will be default
7926     initialized with an empty value which depends on the type:
7927     Value type  | initial value
7928     ----------- | -------------
7929     null        | `null`
7930     boolean     | `false`
7931     string      | `""`
7932     number      | `0`
7933     object      | `{}`
7934     array       | `[]`
7935     @param[in] v  the type of the value to create
7936     @complexity Constant.
7937     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
7938     changes to any JSON value.
7939     @liveexample{The following code shows the constructor for different @ref
7940     value_t values,basic_json__value_t}
7941     @sa @ref clear() -- restores the postcondition of this constructor
7942     @since version 1.0.0
7943     */
basic_json(const value_t v)7944     basic_json(const value_t v)
7945         : m_type(v), m_value(v)
7946     {
7947         assert_invariant();
7948     }
7949 
7950     /*!
7951     @brief create a null object
7952     Create a `null` JSON value. It either takes a null pointer as parameter
7953     (explicitly creating `null`) or no parameter (implicitly creating `null`).
7954     The passed null pointer itself is not read -- it is only used to choose
7955     the right constructor.
7956     @complexity Constant.
7957     @exceptionsafety No-throw guarantee: this constructor never throws
7958     exceptions.
7959     @liveexample{The following code shows the constructor with and without a
7960     null pointer parameter.,basic_json__nullptr_t}
7961     @since version 1.0.0
7962     */
basic_json(std::nullptr_t=nullptr)7963     basic_json(std::nullptr_t = nullptr) noexcept
7964         : basic_json(value_t::null)
7965     {
7966         assert_invariant();
7967     }
7968 
7969     /*!
7970     @brief create a JSON value
7971     This is a "catch all" constructor for all compatible JSON types; that is,
7972     types for which a `to_json()` method exsits. The constructor forwards the
7973     parameter @a val to that method (to `json_serializer<U>::to_json` method
7974     with `U = uncvref_t<CompatibleType>`, to be exact).
7975     Template type @a CompatibleType includes, but is not limited to, the
7976     following types:
7977     - **arrays**: @ref array_t and all kinds of compatible containers such as
7978       `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
7979       `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
7980       `std::multiset`, and `std::unordered_multiset` with a `value_type` from
7981       which a @ref basic_json value can be constructed.
7982     - **objects**: @ref object_t and all kinds of compatible associative
7983       containers such as `std::map`, `std::unordered_map`, `std::multimap`,
7984       and `std::unordered_multimap` with a `key_type` compatible to
7985       @ref string_t and a `value_type` from which a @ref basic_json value can
7986       be constructed.
7987     - **strings**: @ref string_t, string literals, and all compatible string
7988       containers can be used.
7989     - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
7990       @ref number_float_t, and all convertible number types such as `int`,
7991       `size_t`, `int64_t`, `float` or `double` can be used.
7992     - **boolean**: @ref boolean_t / `bool` can be used.
7993     See the examples below.
7994     @tparam CompatibleType a type such that:
7995     - @a CompatibleType is not derived from `std::istream`,
7996     - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
7997          constructors),
7998     - @a CompatibleType is not a @ref basic_json nested type (e.g.,
7999          @ref json_pointer, @ref iterator, etc ...)
8000     - @ref @ref json_serializer<U> has a
8001          `to_json(basic_json_t&, CompatibleType&&)` method
8002     @tparam U = `uncvref_t<CompatibleType>`
8003     @param[in] val the value to be forwarded to the respective constructor
8004     @complexity Usually linear in the size of the passed @a val, also
8005                 depending on the implementation of the called `to_json()`
8006                 method.
8007     @exceptionsafety Depends on the called constructor. For types directly
8008     supported by the library (i.e., all types for which no `to_json()` function
8009     was provided), strong guarantee holds: if an exception is thrown, there are
8010     no changes to any JSON value.
8011     @liveexample{The following code shows the constructor with several
8012     compatible types.,basic_json__CompatibleType}
8013     @since version 2.1.0
8014     */
8015     template<typename CompatibleType, typename U = detail::uncvref_t<CompatibleType>,
8016              detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
8017                                  not std::is_same<U, basic_json_t>::value and
8018                                  not detail::is_basic_json_nested_type<
8019                                      basic_json_t, U>::value and
8020                                  detail::has_to_json<basic_json, U>::value,
8021                                  int> = 0>
basic_json(CompatibleType && val)8022     basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
8023                 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
8024     {
8025         JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
8026         assert_invariant();
8027     }
8028 
8029     /*!
8030     @brief create a container (array or object) from an initializer list
8031     Creates a JSON value of type array or object from the passed initializer
8032     list @a init. In case @a type_deduction is `true` (default), the type of
8033     the JSON value to be created is deducted from the initializer list @a init
8034     according to the following rules:
8035     1. If the list is empty, an empty JSON object value `{}` is created.
8036     2. If the list consists of pairs whose first element is a string, a JSON
8037        object value is created where the first elements of the pairs are
8038        treated as keys and the second elements are as values.
8039     3. In all other cases, an array is created.
8040     The rules aim to create the best fit between a C++ initializer list and
8041     JSON values. The rationale is as follows:
8042     1. The empty initializer list is written as `{}` which is exactly an empty
8043        JSON object.
8044     2. C++ has no way of describing mapped types other than to list a list of
8045        pairs. As JSON requires that keys must be of type string, rule 2 is the
8046        weakest constraint one can pose on initializer lists to interpret them
8047        as an object.
8048     3. In all other cases, the initializer list could not be interpreted as
8049        JSON object type, so interpreting it as JSON array type is safe.
8050     With the rules described above, the following JSON values cannot be
8051     expressed by an initializer list:
8052     - the empty array (`[]`): use @ref array(initializer_list_t)
8053       with an empty initializer list in this case
8054     - arrays whose elements satisfy rule 2: use @ref
8055       array(initializer_list_t) with the same initializer list
8056       in this case
8057     @note When used without parentheses around an empty initializer list, @ref
8058     basic_json() is called instead of this function, yielding the JSON null
8059     value.
8060     @param[in] init  initializer list with JSON values
8061     @param[in] type_deduction internal parameter; when set to `true`, the type
8062     of the JSON value is deducted from the initializer list @a init; when set
8063     to `false`, the type provided via @a manual_type is forced. This mode is
8064     used by the functions @ref array(initializer_list_t) and
8065     @ref object(initializer_list_t).
8066     @param[in] manual_type internal parameter; when @a type_deduction is set
8067     to `false`, the created JSON value will use the provided type (only @ref
8068     value_t::array and @ref value_t::object are valid); when @a type_deduction
8069     is set to `true`, this parameter has no effect
8070     @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
8071     `value_t::object`, but @a init contains an element which is not a pair
8072     whose first element is a string. In this case, the constructor could not
8073     create an object. If @a type_deduction would have be `true`, an array
8074     would have been created. See @ref object(initializer_list_t)
8075     for an example.
8076     @complexity Linear in the size of the initializer list @a init.
8077     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8078     changes to any JSON value.
8079     @liveexample{The example below shows how JSON values are created from
8080     initializer lists.,basic_json__list_init_t}
8081     @sa @ref array(initializer_list_t) -- create a JSON array
8082     value from an initializer list
8083     @sa @ref object(initializer_list_t) -- create a JSON object
8084     value from an initializer list
8085     @since version 1.0.0
8086     */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)8087     basic_json(initializer_list_t init,
8088                bool type_deduction = true,
8089                value_t manual_type = value_t::array)
8090     {
8091         // check if each element is an array with two elements whose first
8092         // element is a string
8093         bool is_an_object = std::all_of(init.begin(), init.end(),
8094                                         [](const detail::json_ref<basic_json>& element_ref)
8095         {
8096             return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
8097         });
8098 
8099         // adjust type if type deduction is not wanted
8100         if (not type_deduction)
8101         {
8102             // if array is wanted, do not create an object though possible
8103             if (manual_type == value_t::array)
8104             {
8105                 is_an_object = false;
8106             }
8107 
8108             // if object is wanted but impossible, throw an exception
8109             if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
8110             {
8111                 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
8112             }
8113         }
8114 
8115         if (is_an_object)
8116         {
8117             // the initializer list is a list of pairs -> create object
8118             m_type = value_t::object;
8119             m_value = value_t::object;
8120 
8121             std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
8122             {
8123                 auto element = element_ref.moved_or_copied();
8124                 m_value.object->emplace(
8125                     std::move(*((*element.m_value.array)[0].m_value.string)),
8126                     std::move((*element.m_value.array)[1]));
8127             });
8128         }
8129         else
8130         {
8131             // the initializer list describes an array -> create array
8132             m_type = value_t::array;
8133             m_value.array = create<array_t>(init.begin(), init.end());
8134         }
8135 
8136         assert_invariant();
8137     }
8138 
8139     /*!
8140     @brief explicitly create an array from an initializer list
8141     Creates a JSON array value from a given initializer list. That is, given a
8142     list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
8143     initializer list is empty, the empty array `[]` is created.
8144     @note This function is only needed to express two edge cases that cannot
8145     be realized with the initializer list constructor (@ref
8146     basic_json(initializer_list_t, bool, value_t)). These cases
8147     are:
8148     1. creating an array whose elements are all pairs whose first element is a
8149     string -- in this case, the initializer list constructor would create an
8150     object, taking the first elements as keys
8151     2. creating an empty array -- passing the empty initializer list to the
8152     initializer list constructor yields an empty object
8153     @param[in] init  initializer list with JSON values to create an array from
8154     (optional)
8155     @return JSON array value
8156     @complexity Linear in the size of @a init.
8157     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8158     changes to any JSON value.
8159     @liveexample{The following code shows an example for the `array`
8160     function.,array}
8161     @sa @ref basic_json(initializer_list_t, bool, value_t) --
8162     create a JSON value from an initializer list
8163     @sa @ref object(initializer_list_t) -- create a JSON object
8164     value from an initializer list
8165     @since version 1.0.0
8166     */
array(initializer_list_t init={})8167     static basic_json array(initializer_list_t init = {})
8168     {
8169         return basic_json(init, false, value_t::array);
8170     }
8171 
8172     /*!
8173     @brief explicitly create an object from an initializer list
8174     Creates a JSON object value from a given initializer list. The initializer
8175     lists elements must be pairs, and their first elements must be strings. If
8176     the initializer list is empty, the empty object `{}` is created.
8177     @note This function is only added for symmetry reasons. In contrast to the
8178     related function @ref array(initializer_list_t), there are
8179     no cases which can only be expressed by this function. That is, any
8180     initializer list @a init can also be passed to the initializer list
8181     constructor @ref basic_json(initializer_list_t, bool, value_t).
8182     @param[in] init  initializer list to create an object from (optional)
8183     @return JSON object value
8184     @throw type_error.301 if @a init is not a list of pairs whose first
8185     elements are strings. In this case, no object can be created. When such a
8186     value is passed to @ref basic_json(initializer_list_t, bool, value_t),
8187     an array would have been created from the passed initializer list @a init.
8188     See example below.
8189     @complexity Linear in the size of @a init.
8190     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8191     changes to any JSON value.
8192     @liveexample{The following code shows an example for the `object`
8193     function.,object}
8194     @sa @ref basic_json(initializer_list_t, bool, value_t) --
8195     create a JSON value from an initializer list
8196     @sa @ref array(initializer_list_t) -- create a JSON array
8197     value from an initializer list
8198     @since version 1.0.0
8199     */
object(initializer_list_t init={})8200     static basic_json object(initializer_list_t init = {})
8201     {
8202         return basic_json(init, false, value_t::object);
8203     }
8204 
8205     /*!
8206     @brief construct an array with count copies of given value
8207     Constructs a JSON array value by creating @a cnt copies of a passed value.
8208     In case @a cnt is `0`, an empty array is created.
8209     @param[in] cnt  the number of JSON copies of @a val to create
8210     @param[in] val  the JSON value to copy
8211     @post `std::distance(begin(),end()) == cnt` holds.
8212     @complexity Linear in @a cnt.
8213     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8214     changes to any JSON value.
8215     @liveexample{The following code shows examples for the @ref
8216     basic_json(size_type\, const basic_json&)
8217     constructor.,basic_json__size_type_basic_json}
8218     @since version 1.0.0
8219     */
basic_json(size_type cnt,const basic_json & val)8220     basic_json(size_type cnt, const basic_json& val)
8221         : m_type(value_t::array)
8222     {
8223         m_value.array = create<array_t>(cnt, val);
8224         assert_invariant();
8225     }
8226 
8227     /*!
8228     @brief construct a JSON container given an iterator range
8229     Constructs the JSON value with the contents of the range `[first, last)`.
8230     The semantics depends on the different types a JSON value can have:
8231     - In case of a null type, invalid_iterator.206 is thrown.
8232     - In case of other primitive types (number, boolean, or string), @a first
8233       must be `begin()` and @a last must be `end()`. In this case, the value is
8234       copied. Otherwise, invalid_iterator.204 is thrown.
8235     - In case of structured types (array, object), the constructor behaves as
8236       similar versions for `std::vector` or `std::map`; that is, a JSON array
8237       or object is constructed from the values in the range.
8238     @tparam InputIT an input iterator type (@ref iterator or @ref
8239     const_iterator)
8240     @param[in] first begin of the range to copy from (included)
8241     @param[in] last end of the range to copy from (excluded)
8242     @pre Iterators @a first and @a last must be initialized. **This
8243          precondition is enforced with an assertion (see warning).** If
8244          assertions are switched off, a violation of this precondition yields
8245          undefined behavior.
8246     @pre Range `[first, last)` is valid. Usually, this precondition cannot be
8247          checked efficiently. Only certain edge cases are detected; see the
8248          description of the exceptions below. A violation of this precondition
8249          yields undefined behavior.
8250     @warning A precondition is enforced with a runtime assertion that will
8251              result in calling `std::abort` if this precondition is not met.
8252              Assertions can be disabled by defining `NDEBUG` at compile time.
8253              See http://en.cppreference.com/w/cpp/error/assert for more
8254              information.
8255     @throw invalid_iterator.201 if iterators @a first and @a last are not
8256     compatible (i.e., do not belong to the same JSON value). In this case,
8257     the range `[first, last)` is undefined.
8258     @throw invalid_iterator.204 if iterators @a first and @a last belong to a
8259     primitive type (number, boolean, or string), but @a first does not point
8260     to the first element any more. In this case, the range `[first, last)` is
8261     undefined. See example code below.
8262     @throw invalid_iterator.206 if iterators @a first and @a last belong to a
8263     null value. In this case, the range `[first, last)` is undefined.
8264     @complexity Linear in distance between @a first and @a last.
8265     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8266     changes to any JSON value.
8267     @liveexample{The example below shows several ways to create JSON values by
8268     specifying a subrange with iterators.,basic_json__InputIt_InputIt}
8269     @since version 1.0.0
8270     */
8271     template<class InputIT, typename std::enable_if<
8272                  std::is_same<InputIT, typename basic_json_t::iterator>::value or
8273                  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)8274     basic_json(InputIT first, InputIT last)
8275     {
8276         assert(first.m_object != nullptr);
8277         assert(last.m_object != nullptr);
8278 
8279         // make sure iterator fits the current value
8280         if (JSON_UNLIKELY(first.m_object != last.m_object))
8281         {
8282             JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
8283         }
8284 
8285         // copy type from first iterator
8286         m_type = first.m_object->m_type;
8287 
8288         // check if iterator range is complete for primitive values
8289         switch (m_type)
8290         {
8291             case value_t::boolean:
8292             case value_t::number_float:
8293             case value_t::number_integer:
8294             case value_t::number_unsigned:
8295             case value_t::string:
8296             {
8297                 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
8298                                   or not last.m_it.primitive_iterator.is_end()))
8299                 {
8300                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
8301                 }
8302                 break;
8303             }
8304 
8305             default:
8306                 break;
8307         }
8308 
8309         switch (m_type)
8310         {
8311             case value_t::number_integer:
8312             {
8313                 m_value.number_integer = first.m_object->m_value.number_integer;
8314                 break;
8315             }
8316 
8317             case value_t::number_unsigned:
8318             {
8319                 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
8320                 break;
8321             }
8322 
8323             case value_t::number_float:
8324             {
8325                 m_value.number_float = first.m_object->m_value.number_float;
8326                 break;
8327             }
8328 
8329             case value_t::boolean:
8330             {
8331                 m_value.boolean = first.m_object->m_value.boolean;
8332                 break;
8333             }
8334 
8335             case value_t::string:
8336             {
8337                 m_value = *first.m_object->m_value.string;
8338                 break;
8339             }
8340 
8341             case value_t::object:
8342             {
8343                 m_value.object = create<object_t>(first.m_it.object_iterator,
8344                                                   last.m_it.object_iterator);
8345                 break;
8346             }
8347 
8348             case value_t::array:
8349             {
8350                 m_value.array = create<array_t>(first.m_it.array_iterator,
8351                                                 last.m_it.array_iterator);
8352                 break;
8353             }
8354 
8355             default:
8356                 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
8357                                                     std::string(first.m_object->type_name())));
8358         }
8359 
8360         assert_invariant();
8361     }
8362 
8363 
8364     ///////////////////////////////////////
8365     // other constructors and destructor //
8366     ///////////////////////////////////////
8367 
8368     /// @private
basic_json(const detail::json_ref<basic_json> & ref)8369     basic_json(const detail::json_ref<basic_json>& ref)
8370         : basic_json(ref.moved_or_copied())
8371     {}
8372 
8373     /*!
8374     @brief copy constructor
8375     Creates a copy of a given JSON value.
8376     @param[in] other  the JSON value to copy
8377     @post `*this == other`
8378     @complexity Linear in the size of @a other.
8379     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8380     changes to any JSON value.
8381     @requirement This function helps `basic_json` satisfying the
8382     [Container](http://en.cppreference.com/w/cpp/concept/Container)
8383     requirements:
8384     - The complexity is linear.
8385     - As postcondition, it holds: `other == basic_json(other)`.
8386     @liveexample{The following code shows an example for the copy
8387     constructor.,basic_json__basic_json}
8388     @since version 1.0.0
8389     */
basic_json(const basic_json & other)8390     basic_json(const basic_json& other)
8391         : m_type(other.m_type)
8392     {
8393         // check of passed value is valid
8394         other.assert_invariant();
8395 
8396         switch (m_type)
8397         {
8398             case value_t::object:
8399             {
8400                 m_value = *other.m_value.object;
8401                 break;
8402             }
8403 
8404             case value_t::array:
8405             {
8406                 m_value = *other.m_value.array;
8407                 break;
8408             }
8409 
8410             case value_t::string:
8411             {
8412                 m_value = *other.m_value.string;
8413                 break;
8414             }
8415 
8416             case value_t::boolean:
8417             {
8418                 m_value = other.m_value.boolean;
8419                 break;
8420             }
8421 
8422             case value_t::number_integer:
8423             {
8424                 m_value = other.m_value.number_integer;
8425                 break;
8426             }
8427 
8428             case value_t::number_unsigned:
8429             {
8430                 m_value = other.m_value.number_unsigned;
8431                 break;
8432             }
8433 
8434             case value_t::number_float:
8435             {
8436                 m_value = other.m_value.number_float;
8437                 break;
8438             }
8439 
8440             default:
8441                 break;
8442         }
8443 
8444         assert_invariant();
8445     }
8446 
8447     /*!
8448     @brief move constructor
8449     Move constructor. Constructs a JSON value with the contents of the given
8450     value @a other using move semantics. It "steals" the resources from @a
8451     other and leaves it as JSON null value.
8452     @param[in,out] other  value to move to this object
8453     @post `*this` has the same value as @a other before the call.
8454     @post @a other is a JSON null value.
8455     @complexity Constant.
8456     @exceptionsafety No-throw guarantee: this constructor never throws
8457     exceptions.
8458     @requirement This function helps `basic_json` satisfying the
8459     [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible)
8460     requirements.
8461     @liveexample{The code below shows the move constructor explicitly called
8462     via std::move.,basic_json__moveconstructor}
8463     @since version 1.0.0
8464     */
basic_json(basic_json && other)8465     basic_json(basic_json&& other) noexcept
8466         : m_type(std::move(other.m_type)),
8467           m_value(std::move(other.m_value))
8468     {
8469         // check that passed value is valid
8470         other.assert_invariant();
8471 
8472         // invalidate payload
8473         other.m_type = value_t::null;
8474         other.m_value = {};
8475 
8476         assert_invariant();
8477     }
8478 
8479     /*!
8480     @brief copy assignment
8481     Copy assignment operator. Copies a JSON value via the "copy and swap"
8482     strategy: It is expressed in terms of the copy constructor, destructor,
8483     and the `swap()` member function.
8484     @param[in] other  value to copy from
8485     @complexity Linear.
8486     @requirement This function helps `basic_json` satisfying the
8487     [Container](http://en.cppreference.com/w/cpp/concept/Container)
8488     requirements:
8489     - The complexity is linear.
8490     @liveexample{The code below shows and example for the copy assignment. It
8491     creates a copy of value `a` which is then swapped with `b`. Finally\, the
8492     copy of `a` (which is the null value after the swap) is
8493     destroyed.,basic_json__copyassignment}
8494     @since version 1.0.0
8495     */
operator =(basic_json other)8496     reference& operator=(basic_json other) noexcept (
8497         std::is_nothrow_move_constructible<value_t>::value and
8498         std::is_nothrow_move_assignable<value_t>::value and
8499         std::is_nothrow_move_constructible<json_value>::value and
8500         std::is_nothrow_move_assignable<json_value>::value
8501     )
8502     {
8503         // check that passed value is valid
8504         other.assert_invariant();
8505 
8506         using std::swap;
8507         swap(m_type, other.m_type);
8508         swap(m_value, other.m_value);
8509 
8510         assert_invariant();
8511         return *this;
8512     }
8513 
8514     /*!
8515     @brief destructor
8516     Destroys the JSON value and frees all allocated memory.
8517     @complexity Linear.
8518     @requirement This function helps `basic_json` satisfying the
8519     [Container](http://en.cppreference.com/w/cpp/concept/Container)
8520     requirements:
8521     - The complexity is linear.
8522     - All stored elements are destroyed and all memory is freed.
8523     @since version 1.0.0
8524     */
~basic_json()8525     ~basic_json()
8526     {
8527         assert_invariant();
8528         m_value.destroy(m_type);
8529     }
8530 
8531     /// @}
8532 
8533   public:
8534     ///////////////////////
8535     // object inspection //
8536     ///////////////////////
8537 
8538     /// @name object inspection
8539     /// Functions to inspect the type of a JSON value.
8540     /// @{
8541 
8542     /*!
8543     @brief serialization
8544     Serialization function for JSON values. The function tries to mimic
8545     Python's `json.dumps()` function, and currently supports its @a indent
8546     and @a ensure_ascii parameters.
8547     @param[in] indent If indent is nonnegative, then array elements and object
8548     members will be pretty-printed with that indent level. An indent level of
8549     `0` will only insert newlines. `-1` (the default) selects the most compact
8550     representation.
8551     @param[in] indent_char The character to use for indentation if @a indent is
8552     greater than `0`. The default is ` ` (space).
8553     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
8554     in the output are escaped with \uXXXX sequences, and the result consists
8555     of ASCII characters only.
8556     @return string containing the serialization of the JSON value
8557     @complexity Linear.
8558     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8559     changes in the JSON value.
8560     @liveexample{The following example shows the effect of different @a indent\,
8561     @a indent_char\, and @a ensure_ascii parameters to the result of the
8562     serialization.,dump}
8563     @see https://docs.python.org/2/library/json.html#json.dump
8564     @since version 1.0.0; indentation character @a indent_char and option
8565            @a ensure_ascii added in version 3.0.0
8566     */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false) const8567     string_t dump(const int indent = -1, const char indent_char = ' ',
8568                   const bool ensure_ascii = false) const
8569     {
8570         string_t result;
8571         serializer s(detail::output_adapter<char>(result), indent_char);
8572 
8573         if (indent >= 0)
8574         {
8575             s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
8576         }
8577         else
8578         {
8579             s.dump(*this, false, ensure_ascii, 0);
8580         }
8581 
8582         return result;
8583     }
8584 
8585     /*!
8586     @brief return the type of the JSON value (explicit)
8587     Return the type of the JSON value as a value from the @ref value_t
8588     enumeration.
8589     @return the type of the JSON value
8590             Value type                | return value
8591             ------------------------- | -------------------------
8592             null                      | value_t::null
8593             boolean                   | value_t::boolean
8594             string                    | value_t::string
8595             number (integer)          | value_t::number_integer
8596             number (unsigned integer) | value_t::number_unsigned
8597             number (foating-point)    | value_t::number_float
8598             object                    | value_t::object
8599             array                     | value_t::array
8600             discarded                 | value_t::discarded
8601     @complexity Constant.
8602     @exceptionsafety No-throw guarantee: this member function never throws
8603     exceptions.
8604     @liveexample{The following code exemplifies `type()` for all JSON
8605     types.,type}
8606     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
8607     @sa @ref type_name() -- return the type as string
8608     @since version 1.0.0
8609     */
type() const8610     constexpr value_t type() const noexcept
8611     {
8612         return m_type;
8613     }
8614 
8615     /*!
8616     @brief return whether type is primitive
8617     This function returns true if and only if the JSON type is primitive
8618     (string, number, boolean, or null).
8619     @return `true` if type is primitive (string, number, boolean, or null),
8620     `false` otherwise.
8621     @complexity Constant.
8622     @exceptionsafety No-throw guarantee: this member function never throws
8623     exceptions.
8624     @liveexample{The following code exemplifies `is_primitive()` for all JSON
8625     types.,is_primitive}
8626     @sa @ref is_structured() -- returns whether JSON value is structured
8627     @sa @ref is_null() -- returns whether JSON value is `null`
8628     @sa @ref is_string() -- returns whether JSON value is a string
8629     @sa @ref is_boolean() -- returns whether JSON value is a boolean
8630     @sa @ref is_number() -- returns whether JSON value is a number
8631     @since version 1.0.0
8632     */
is_primitive() const8633     constexpr bool is_primitive() const noexcept
8634     {
8635         return is_null() or is_string() or is_boolean() or is_number();
8636     }
8637 
8638     /*!
8639     @brief return whether type is structured
8640     This function returns true if and only if the JSON type is structured
8641     (array or object).
8642     @return `true` if type is structured (array or object), `false` otherwise.
8643     @complexity Constant.
8644     @exceptionsafety No-throw guarantee: this member function never throws
8645     exceptions.
8646     @liveexample{The following code exemplifies `is_structured()` for all JSON
8647     types.,is_structured}
8648     @sa @ref is_primitive() -- returns whether value is primitive
8649     @sa @ref is_array() -- returns whether value is an array
8650     @sa @ref is_object() -- returns whether value is an object
8651     @since version 1.0.0
8652     */
is_structured() const8653     constexpr bool is_structured() const noexcept
8654     {
8655         return is_array() or is_object();
8656     }
8657 
8658     /*!
8659     @brief return whether value is null
8660     This function returns true if and only if the JSON value is null.
8661     @return `true` if type is null, `false` otherwise.
8662     @complexity Constant.
8663     @exceptionsafety No-throw guarantee: this member function never throws
8664     exceptions.
8665     @liveexample{The following code exemplifies `is_null()` for all JSON
8666     types.,is_null}
8667     @since version 1.0.0
8668     */
is_null() const8669     constexpr bool is_null() const noexcept
8670     {
8671         return (m_type == value_t::null);
8672     }
8673 
8674     /*!
8675     @brief return whether value is a boolean
8676     This function returns true if and only if the JSON value is a boolean.
8677     @return `true` if type is boolean, `false` otherwise.
8678     @complexity Constant.
8679     @exceptionsafety No-throw guarantee: this member function never throws
8680     exceptions.
8681     @liveexample{The following code exemplifies `is_boolean()` for all JSON
8682     types.,is_boolean}
8683     @since version 1.0.0
8684     */
is_boolean() const8685     constexpr bool is_boolean() const noexcept
8686     {
8687         return (m_type == value_t::boolean);
8688     }
8689 
8690     /*!
8691     @brief return whether value is a number
8692     This function returns true if and only if the JSON value is a number. This
8693     includes both integer (signed and unsigned) and floating-point values.
8694     @return `true` if type is number (regardless whether integer, unsigned
8695     integer or floating-type), `false` otherwise.
8696     @complexity Constant.
8697     @exceptionsafety No-throw guarantee: this member function never throws
8698     exceptions.
8699     @liveexample{The following code exemplifies `is_number()` for all JSON
8700     types.,is_number}
8701     @sa @ref is_number_integer() -- check if value is an integer or unsigned
8702     integer number
8703     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
8704     number
8705     @sa @ref is_number_float() -- check if value is a floating-point number
8706     @since version 1.0.0
8707     */
is_number() const8708     constexpr bool is_number() const noexcept
8709     {
8710         return is_number_integer() or is_number_float();
8711     }
8712 
8713     /*!
8714     @brief return whether value is an integer number
8715     This function returns true if and only if the JSON value is a signed or
8716     unsigned integer number. This excludes floating-point values.
8717     @return `true` if type is an integer or unsigned integer number, `false`
8718     otherwise.
8719     @complexity Constant.
8720     @exceptionsafety No-throw guarantee: this member function never throws
8721     exceptions.
8722     @liveexample{The following code exemplifies `is_number_integer()` for all
8723     JSON types.,is_number_integer}
8724     @sa @ref is_number() -- check if value is a number
8725     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
8726     number
8727     @sa @ref is_number_float() -- check if value is a floating-point number
8728     @since version 1.0.0
8729     */
is_number_integer() const8730     constexpr bool is_number_integer() const noexcept
8731     {
8732         return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
8733     }
8734 
8735     /*!
8736     @brief return whether value is an unsigned integer number
8737     This function returns true if and only if the JSON value is an unsigned
8738     integer number. This excludes floating-point and signed integer values.
8739     @return `true` if type is an unsigned integer number, `false` otherwise.
8740     @complexity Constant.
8741     @exceptionsafety No-throw guarantee: this member function never throws
8742     exceptions.
8743     @liveexample{The following code exemplifies `is_number_unsigned()` for all
8744     JSON types.,is_number_unsigned}
8745     @sa @ref is_number() -- check if value is a number
8746     @sa @ref is_number_integer() -- check if value is an integer or unsigned
8747     integer number
8748     @sa @ref is_number_float() -- check if value is a floating-point number
8749     @since version 2.0.0
8750     */
is_number_unsigned() const8751     constexpr bool is_number_unsigned() const noexcept
8752     {
8753         return (m_type == value_t::number_unsigned);
8754     }
8755 
8756     /*!
8757     @brief return whether value is a floating-point number
8758     This function returns true if and only if the JSON value is a
8759     floating-point number. This excludes signed and unsigned integer values.
8760     @return `true` if type is a floating-point number, `false` otherwise.
8761     @complexity Constant.
8762     @exceptionsafety No-throw guarantee: this member function never throws
8763     exceptions.
8764     @liveexample{The following code exemplifies `is_number_float()` for all
8765     JSON types.,is_number_float}
8766     @sa @ref is_number() -- check if value is number
8767     @sa @ref is_number_integer() -- check if value is an integer number
8768     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
8769     number
8770     @since version 1.0.0
8771     */
is_number_float() const8772     constexpr bool is_number_float() const noexcept
8773     {
8774         return (m_type == value_t::number_float);
8775     }
8776 
8777     /*!
8778     @brief return whether value is an object
8779     This function returns true if and only if the JSON value is an object.
8780     @return `true` if type is object, `false` otherwise.
8781     @complexity Constant.
8782     @exceptionsafety No-throw guarantee: this member function never throws
8783     exceptions.
8784     @liveexample{The following code exemplifies `is_object()` for all JSON
8785     types.,is_object}
8786     @since version 1.0.0
8787     */
is_object() const8788     constexpr bool is_object() const noexcept
8789     {
8790         return (m_type == value_t::object);
8791     }
8792 
8793     /*!
8794     @brief return whether value is an array
8795     This function returns true if and only if the JSON value is an array.
8796     @return `true` if type is array, `false` otherwise.
8797     @complexity Constant.
8798     @exceptionsafety No-throw guarantee: this member function never throws
8799     exceptions.
8800     @liveexample{The following code exemplifies `is_array()` for all JSON
8801     types.,is_array}
8802     @since version 1.0.0
8803     */
is_array() const8804     constexpr bool is_array() const noexcept
8805     {
8806         return (m_type == value_t::array);
8807     }
8808 
8809     /*!
8810     @brief return whether value is a string
8811     This function returns true if and only if the JSON value is a string.
8812     @return `true` if type is string, `false` otherwise.
8813     @complexity Constant.
8814     @exceptionsafety No-throw guarantee: this member function never throws
8815     exceptions.
8816     @liveexample{The following code exemplifies `is_string()` for all JSON
8817     types.,is_string}
8818     @since version 1.0.0
8819     */
is_string() const8820     constexpr bool is_string() const noexcept
8821     {
8822         return (m_type == value_t::string);
8823     }
8824 
8825     /*!
8826     @brief return whether value is discarded
8827     This function returns true if and only if the JSON value was discarded
8828     during parsing with a callback function (see @ref parser_callback_t).
8829     @note This function will always be `false` for JSON values after parsing.
8830     That is, discarded values can only occur during parsing, but will be
8831     removed when inside a structured value or replaced by null in other cases.
8832     @return `true` if type is discarded, `false` otherwise.
8833     @complexity Constant.
8834     @exceptionsafety No-throw guarantee: this member function never throws
8835     exceptions.
8836     @liveexample{The following code exemplifies `is_discarded()` for all JSON
8837     types.,is_discarded}
8838     @since version 1.0.0
8839     */
is_discarded() const8840     constexpr bool is_discarded() const noexcept
8841     {
8842         return (m_type == value_t::discarded);
8843     }
8844 
8845     /*!
8846     @brief return the type of the JSON value (implicit)
8847     Implicitly return the type of the JSON value as a value from the @ref
8848     value_t enumeration.
8849     @return the type of the JSON value
8850     @complexity Constant.
8851     @exceptionsafety No-throw guarantee: this member function never throws
8852     exceptions.
8853     @liveexample{The following code exemplifies the @ref value_t operator for
8854     all JSON types.,operator__value_t}
8855     @sa @ref type() -- return the type of the JSON value (explicit)
8856     @sa @ref type_name() -- return the type as string
8857     @since version 1.0.0
8858     */
operator value_t() const8859     constexpr operator value_t() const noexcept
8860     {
8861         return m_type;
8862     }
8863 
8864     /// @}
8865 
8866   private:
8867     //////////////////
8868     // value access //
8869     //////////////////
8870 
8871     /// get a boolean (explicit)
get_impl(boolean_t *) const8872     boolean_t get_impl(boolean_t* /*unused*/) const
8873     {
8874         if (JSON_LIKELY(is_boolean()))
8875         {
8876             return m_value.boolean;
8877         }
8878 
8879         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
8880     }
8881 
8882     /// get a pointer to the value (object)
get_impl_ptr(object_t *)8883     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
8884     {
8885         return is_object() ? m_value.object : nullptr;
8886     }
8887 
8888     /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const8889     constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
8890     {
8891         return is_object() ? m_value.object : nullptr;
8892     }
8893 
8894     /// get a pointer to the value (array)
get_impl_ptr(array_t *)8895     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
8896     {
8897         return is_array() ? m_value.array : nullptr;
8898     }
8899 
8900     /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const8901     constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
8902     {
8903         return is_array() ? m_value.array : nullptr;
8904     }
8905 
8906     /// get a pointer to the value (string)
get_impl_ptr(string_t *)8907     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
8908     {
8909         return is_string() ? m_value.string : nullptr;
8910     }
8911 
8912     /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const8913     constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
8914     {
8915         return is_string() ? m_value.string : nullptr;
8916     }
8917 
8918     /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)8919     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
8920     {
8921         return is_boolean() ? &m_value.boolean : nullptr;
8922     }
8923 
8924     /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const8925     constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
8926     {
8927         return is_boolean() ? &m_value.boolean : nullptr;
8928     }
8929 
8930     /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)8931     number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
8932     {
8933         return is_number_integer() ? &m_value.number_integer : nullptr;
8934     }
8935 
8936     /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const8937     constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
8938     {
8939         return is_number_integer() ? &m_value.number_integer : nullptr;
8940     }
8941 
8942     /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)8943     number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
8944     {
8945         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
8946     }
8947 
8948     /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const8949     constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
8950     {
8951         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
8952     }
8953 
8954     /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)8955     number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
8956     {
8957         return is_number_float() ? &m_value.number_float : nullptr;
8958     }
8959 
8960     /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const8961     constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
8962     {
8963         return is_number_float() ? &m_value.number_float : nullptr;
8964     }
8965 
8966     /*!
8967     @brief helper function to implement get_ref()
8968     This function helps to implement get_ref() without code duplication for
8969     const and non-const overloads
8970     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
8971     @throw type_error.303 if ReferenceType does not match underlying value
8972     type of the current JSON
8973     */
8974     template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)8975     static ReferenceType get_ref_impl(ThisType& obj)
8976     {
8977         // delegate the call to get_ptr<>()
8978         auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
8979 
8980         if (JSON_LIKELY(ptr != nullptr))
8981         {
8982             return *ptr;
8983         }
8984 
8985         JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
8986     }
8987 
8988   public:
8989     /// @name value access
8990     /// Direct access to the stored value of a JSON value.
8991     /// @{
8992 
8993     /*!
8994     @brief get special-case overload
8995     This overloads avoids a lot of template boilerplate, it can be seen as the
8996     identity method
8997     @tparam BasicJsonType == @ref basic_json
8998     @return a copy of *this
8999     @complexity Constant.
9000     @since version 2.1.0
9001     */
9002     template <
9003         typename BasicJsonType,
9004         detail::enable_if_t<std::is_same<typename std::remove_const<BasicJsonType>::type,
9005                                          basic_json_t>::value,
9006                             int> = 0 >
get() const9007     basic_json get() const
9008     {
9009         return *this;
9010     }
9011 
9012     /*!
9013     @brief get a value (explicit)
9014     Explicit type conversion between the JSON value and a compatible value
9015     which is [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
9016     and [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
9017     The value is converted by calling the @ref json_serializer<ValueType>
9018     `from_json()` method.
9019     The function is equivalent to executing
9020     @code {.cpp}
9021     ValueType ret;
9022     JSONSerializer<ValueType>::from_json(*this, ret);
9023     return ret;
9024     @endcode
9025     This overloads is chosen if:
9026     - @a ValueType is not @ref basic_json,
9027     - @ref json_serializer<ValueType> has a `from_json()` method of the form
9028       `void from_json(const basic_json&, ValueType&)`, and
9029     - @ref json_serializer<ValueType> does not have a `from_json()` method of
9030       the form `ValueType from_json(const basic_json&)`
9031     @tparam ValueTypeCV the provided value type
9032     @tparam ValueType the returned value type
9033     @return copy of the JSON value, converted to @a ValueType
9034     @throw what @ref json_serializer<ValueType> `from_json()` method throws
9035     @liveexample{The example below shows several conversions from JSON values
9036     to other types. There a few things to note: (1) Floating-point numbers can
9037     be converted to integers\, (2) A JSON array can be converted to a standard
9038     `std::vector<short>`\, (3) A JSON object can be converted to C++
9039     associative containers such as `std::unordered_map<std::string\,
9040     json>`.,get__ValueType_const}
9041     @since version 2.1.0
9042     */
9043     template <
9044         typename ValueTypeCV,
9045         typename ValueType = detail::uncvref_t<ValueTypeCV>,
9046         detail::enable_if_t <
9047             not std::is_same<basic_json_t, ValueType>::value and
9048             detail::has_from_json<basic_json_t, ValueType>::value and
9049             not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9050             int > = 0 >
9051     ValueType get() const noexcept(noexcept(
9052                                        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
9053     {
9054         // we cannot static_assert on ValueTypeCV being non-const, because
9055         // there is support for get<const basic_json_t>(), which is why we
9056         // still need the uncvref
9057         static_assert(not std::is_reference<ValueTypeCV>::value,
9058                       "get() cannot be used with reference types, you might want to use get_ref()");
9059         static_assert(std::is_default_constructible<ValueType>::value,
9060                       "types must be DefaultConstructible when used with get()");
9061 
9062         ValueType ret;
9063         JSONSerializer<ValueType>::from_json(*this, ret);
9064         return ret;
9065     }
9066 
9067     /*!
9068     @brief get a value (explicit); special case
9069     Explicit type conversion between the JSON value and a compatible value
9070     which is **not** [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
9071     and **not** [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
9072     The value is converted by calling the @ref json_serializer<ValueType>
9073     `from_json()` method.
9074     The function is equivalent to executing
9075     @code {.cpp}
9076     return JSONSerializer<ValueTypeCV>::from_json(*this);
9077     @endcode
9078     This overloads is chosen if:
9079     - @a ValueType is not @ref basic_json and
9080     - @ref json_serializer<ValueType> has a `from_json()` method of the form
9081       `ValueType from_json(const basic_json&)`
9082     @note If @ref json_serializer<ValueType> has both overloads of
9083     `from_json()`, this one is chosen.
9084     @tparam ValueTypeCV the provided value type
9085     @tparam ValueType the returned value type
9086     @return copy of the JSON value, converted to @a ValueType
9087     @throw what @ref json_serializer<ValueType> `from_json()` method throws
9088     @since version 2.1.0
9089     */
9090     template <
9091         typename ValueTypeCV,
9092         typename ValueType = detail::uncvref_t<ValueTypeCV>,
9093         detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
9094                             detail::has_non_default_from_json<basic_json_t,
9095                                     ValueType>::value, int> = 0 >
9096     ValueType get() const noexcept(noexcept(
9097                                        JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
9098     {
9099         static_assert(not std::is_reference<ValueTypeCV>::value,
9100                       "get() cannot be used with reference types, you might want to use get_ref()");
9101         return JSONSerializer<ValueTypeCV>::from_json(*this);
9102     }
9103 
9104     /*!
9105     @brief get a pointer value (explicit)
9106     Explicit pointer access to the internally stored JSON value. No copies are
9107     made.
9108     @warning The pointer becomes invalid if the underlying JSON object
9109     changes.
9110     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
9111     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
9112     @ref number_unsigned_t, or @ref number_float_t.
9113     @return pointer to the internally stored JSON value if the requested
9114     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
9115     @complexity Constant.
9116     @liveexample{The example below shows how pointers to internal values of a
9117     JSON value can be requested. Note that no type conversions are made and a
9118     `nullptr` is returned if the value and the requested pointer type does not
9119     match.,get__PointerType}
9120     @sa @ref get_ptr() for explicit pointer-member access
9121     @since version 1.0.0
9122     */
9123     template<typename PointerType, typename std::enable_if<
9124                  std::is_pointer<PointerType>::value, int>::type = 0>
9125     PointerType get() noexcept
9126     {
9127         // delegate the call to get_ptr
9128         return get_ptr<PointerType>();
9129     }
9130 
9131     /*!
9132     @brief get a pointer value (explicit)
9133     @copydoc get()
9134     */
9135     template<typename PointerType, typename std::enable_if<
9136                  std::is_pointer<PointerType>::value, int>::type = 0>
get() const9137     constexpr const PointerType get() const noexcept
9138     {
9139         // delegate the call to get_ptr
9140         return get_ptr<PointerType>();
9141     }
9142 
9143     /*!
9144     @brief get a pointer value (implicit)
9145     Implicit pointer access to the internally stored JSON value. No copies are
9146     made.
9147     @warning Writing data to the pointee of the result yields an undefined
9148     state.
9149     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
9150     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
9151     @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
9152     assertion.
9153     @return pointer to the internally stored JSON value if the requested
9154     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
9155     @complexity Constant.
9156     @liveexample{The example below shows how pointers to internal values of a
9157     JSON value can be requested. Note that no type conversions are made and a
9158     `nullptr` is returned if the value and the requested pointer type does not
9159     match.,get_ptr}
9160     @since version 1.0.0
9161     */
9162     template<typename PointerType, typename std::enable_if<
9163                  std::is_pointer<PointerType>::value, int>::type = 0>
9164     PointerType get_ptr() noexcept
9165     {
9166         // get the type of the PointerType (remove pointer and const)
9167         using pointee_t = typename std::remove_const<typename
9168                           std::remove_pointer<typename
9169                           std::remove_const<PointerType>::type>::type>::type;
9170         // make sure the type matches the allowed types
9171         static_assert(
9172             std::is_same<object_t, pointee_t>::value
9173             or std::is_same<array_t, pointee_t>::value
9174             or std::is_same<string_t, pointee_t>::value
9175             or std::is_same<boolean_t, pointee_t>::value
9176             or std::is_same<number_integer_t, pointee_t>::value
9177             or std::is_same<number_unsigned_t, pointee_t>::value
9178             or std::is_same<number_float_t, pointee_t>::value
9179             , "incompatible pointer type");
9180 
9181         // delegate the call to get_impl_ptr<>()
9182         return get_impl_ptr(static_cast<PointerType>(nullptr));
9183     }
9184 
9185     /*!
9186     @brief get a pointer value (implicit)
9187     @copydoc get_ptr()
9188     */
9189     template<typename PointerType, typename std::enable_if<
9190                  std::is_pointer<PointerType>::value and
9191                  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const9192     constexpr const PointerType get_ptr() const noexcept
9193     {
9194         // get the type of the PointerType (remove pointer and const)
9195         using pointee_t = typename std::remove_const<typename
9196                           std::remove_pointer<typename
9197                           std::remove_const<PointerType>::type>::type>::type;
9198         // make sure the type matches the allowed types
9199         static_assert(
9200             std::is_same<object_t, pointee_t>::value
9201             or std::is_same<array_t, pointee_t>::value
9202             or std::is_same<string_t, pointee_t>::value
9203             or std::is_same<boolean_t, pointee_t>::value
9204             or std::is_same<number_integer_t, pointee_t>::value
9205             or std::is_same<number_unsigned_t, pointee_t>::value
9206             or std::is_same<number_float_t, pointee_t>::value
9207             , "incompatible pointer type");
9208 
9209         // delegate the call to get_impl_ptr<>() const
9210         return get_impl_ptr(static_cast<PointerType>(nullptr));
9211     }
9212 
9213     /*!
9214     @brief get a reference value (implicit)
9215     Implicit reference access to the internally stored JSON value. No copies
9216     are made.
9217     @warning Writing data to the referee of the result yields an undefined
9218     state.
9219     @tparam ReferenceType reference type; must be a reference to @ref array_t,
9220     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
9221     @ref number_float_t. Enforced by static assertion.
9222     @return reference to the internally stored JSON value if the requested
9223     reference type @a ReferenceType fits to the JSON value; throws
9224     type_error.303 otherwise
9225     @throw type_error.303 in case passed type @a ReferenceType is incompatible
9226     with the stored JSON value; see example below
9227     @complexity Constant.
9228     @liveexample{The example shows several calls to `get_ref()`.,get_ref}
9229     @since version 1.1.0
9230     */
9231     template<typename ReferenceType, typename std::enable_if<
9232                  std::is_reference<ReferenceType>::value, int>::type = 0>
9233     ReferenceType get_ref()
9234     {
9235         // delegate call to get_ref_impl
9236         return get_ref_impl<ReferenceType>(*this);
9237     }
9238 
9239     /*!
9240     @brief get a reference value (implicit)
9241     @copydoc get_ref()
9242     */
9243     template<typename ReferenceType, typename std::enable_if<
9244                  std::is_reference<ReferenceType>::value and
9245                  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
9246     ReferenceType get_ref() const
9247     {
9248         // delegate call to get_ref_impl
9249         return get_ref_impl<ReferenceType>(*this);
9250     }
9251 
9252     /*!
9253     @brief get a value (implicit)
9254     Implicit type conversion between the JSON value and a compatible value.
9255     The call is realized by calling @ref get() const.
9256     @tparam ValueType non-pointer type compatible to the JSON value, for
9257     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
9258     `std::vector` types for JSON arrays. The character type of @ref string_t
9259     as well as an initializer list of this type is excluded to avoid
9260     ambiguities as these types implicitly convert to `std::string`.
9261     @return copy of the JSON value, converted to type @a ValueType
9262     @throw type_error.302 in case passed type @a ValueType is incompatible
9263     to the JSON value type (e.g., the JSON value is of type boolean, but a
9264     string is requested); see example below
9265     @complexity Linear in the size of the JSON value.
9266     @liveexample{The example below shows several conversions from JSON values
9267     to other types. There a few things to note: (1) Floating-point numbers can
9268     be converted to integers\, (2) A JSON array can be converted to a standard
9269     `std::vector<short>`\, (3) A JSON object can be converted to C++
9270     associative containers such as `std::unordered_map<std::string\,
9271     json>`.,operator__ValueType}
9272     @since version 1.0.0
9273     */
9274     template < typename ValueType, typename std::enable_if <
9275                    not std::is_pointer<ValueType>::value and
9276                    not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
9277                    not std::is_same<ValueType, typename string_t::value_type>::value
9278 #ifndef _MSC_VER  // fix for issue #167 operator<< ambiguity under VS2015
9279                    and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
9280 #endif
9281 #if defined(JSON_HAS_CPP_17)
9282                    and not std::is_same<ValueType, typename std::string_view>::value
9283 #endif
9284                    , int >::type = 0 >
operator ValueType() const9285     operator ValueType() const
9286     {
9287         // delegate the call to get<>() const
9288         return get<ValueType>();
9289     }
9290 
9291     /// @}
9292 
9293 
9294     ////////////////////
9295     // element access //
9296     ////////////////////
9297 
9298     /// @name element access
9299     /// Access to the JSON value.
9300     /// @{
9301 
9302     /*!
9303     @brief access specified array element with bounds checking
9304     Returns a reference to the element at specified location @a idx, with
9305     bounds checking.
9306     @param[in] idx  index of the element to access
9307     @return reference to the element at index @a idx
9308     @throw type_error.304 if the JSON value is not an array; in this case,
9309     calling `at` with an index makes no sense. See example below.
9310     @throw out_of_range.401 if the index @a idx is out of range of the array;
9311     that is, `idx >= size()`. See example below.
9312     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9313     changes in the JSON value.
9314     @complexity Constant.
9315     @since version 1.0.0
9316     @liveexample{The example below shows how array elements can be read and
9317     written using `at()`. It also demonstrates the different exceptions that
9318     can be thrown.,at__size_type}
9319     */
at(size_type idx)9320     reference at(size_type idx)
9321     {
9322         // at only works for arrays
9323         if (JSON_LIKELY(is_array()))
9324         {
9325             JSON_TRY
9326             {
9327                 return m_value.array->at(idx);
9328             }
9329             JSON_CATCH (std::out_of_range&)
9330             {
9331                 // create better exception explanation
9332                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
9333             }
9334         }
9335         else
9336         {
9337             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9338         }
9339     }
9340 
9341     /*!
9342     @brief access specified array element with bounds checking
9343     Returns a const reference to the element at specified location @a idx,
9344     with bounds checking.
9345     @param[in] idx  index of the element to access
9346     @return const reference to the element at index @a idx
9347     @throw type_error.304 if the JSON value is not an array; in this case,
9348     calling `at` with an index makes no sense. See example below.
9349     @throw out_of_range.401 if the index @a idx is out of range of the array;
9350     that is, `idx >= size()`. See example below.
9351     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9352     changes in the JSON value.
9353     @complexity Constant.
9354     @since version 1.0.0
9355     @liveexample{The example below shows how array elements can be read using
9356     `at()`. It also demonstrates the different exceptions that can be thrown.,
9357     at__size_type_const}
9358     */
at(size_type idx) const9359     const_reference at(size_type idx) const
9360     {
9361         // at only works for arrays
9362         if (JSON_LIKELY(is_array()))
9363         {
9364             JSON_TRY
9365             {
9366                 return m_value.array->at(idx);
9367             }
9368             JSON_CATCH (std::out_of_range&)
9369             {
9370                 // create better exception explanation
9371                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
9372             }
9373         }
9374         else
9375         {
9376             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9377         }
9378     }
9379 
9380     /*!
9381     @brief access specified object element with bounds checking
9382     Returns a reference to the element at with specified key @a key, with
9383     bounds checking.
9384     @param[in] key  key of the element to access
9385     @return reference to the element at key @a key
9386     @throw type_error.304 if the JSON value is not an object; in this case,
9387     calling `at` with a key makes no sense. See example below.
9388     @throw out_of_range.403 if the key @a key is is not stored in the object;
9389     that is, `find(key) == end()`. See example below.
9390     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9391     changes in the JSON value.
9392     @complexity Logarithmic in the size of the container.
9393     @sa @ref operator[](const typename object_t::key_type&) for unchecked
9394     access by reference
9395     @sa @ref value() for access by value with a default value
9396     @since version 1.0.0
9397     @liveexample{The example below shows how object elements can be read and
9398     written using `at()`. It also demonstrates the different exceptions that
9399     can be thrown.,at__object_t_key_type}
9400     */
at(const typename object_t::key_type & key)9401     reference at(const typename object_t::key_type& key)
9402     {
9403         // at only works for objects
9404         if (JSON_LIKELY(is_object()))
9405         {
9406             JSON_TRY
9407             {
9408                 return m_value.object->at(key);
9409             }
9410             JSON_CATCH (std::out_of_range&)
9411             {
9412                 // create better exception explanation
9413                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
9414             }
9415         }
9416         else
9417         {
9418             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9419         }
9420     }
9421 
9422     /*!
9423     @brief access specified object element with bounds checking
9424     Returns a const reference to the element at with specified key @a key,
9425     with bounds checking.
9426     @param[in] key  key of the element to access
9427     @return const reference to the element at key @a key
9428     @throw type_error.304 if the JSON value is not an object; in this case,
9429     calling `at` with a key makes no sense. See example below.
9430     @throw out_of_range.403 if the key @a key is is not stored in the object;
9431     that is, `find(key) == end()`. See example below.
9432     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9433     changes in the JSON value.
9434     @complexity Logarithmic in the size of the container.
9435     @sa @ref operator[](const typename object_t::key_type&) for unchecked
9436     access by reference
9437     @sa @ref value() for access by value with a default value
9438     @since version 1.0.0
9439     @liveexample{The example below shows how object elements can be read using
9440     `at()`. It also demonstrates the different exceptions that can be thrown.,
9441     at__object_t_key_type_const}
9442     */
at(const typename object_t::key_type & key) const9443     const_reference at(const typename object_t::key_type& key) const
9444     {
9445         // at only works for objects
9446         if (JSON_LIKELY(is_object()))
9447         {
9448             JSON_TRY
9449             {
9450                 return m_value.object->at(key);
9451             }
9452             JSON_CATCH (std::out_of_range&)
9453             {
9454                 // create better exception explanation
9455                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
9456             }
9457         }
9458         else
9459         {
9460             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9461         }
9462     }
9463 
9464     /*!
9465     @brief access specified array element
9466     Returns a reference to the element at specified location @a idx.
9467     @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
9468     then the array is silently filled up with `null` values to make `idx` a
9469     valid reference to the last stored element.
9470     @param[in] idx  index of the element to access
9471     @return reference to the element at index @a idx
9472     @throw type_error.305 if the JSON value is not an array or null; in that
9473     cases, using the [] operator with an index makes no sense.
9474     @complexity Constant if @a idx is in the range of the array. Otherwise
9475     linear in `idx - size()`.
9476     @liveexample{The example below shows how array elements can be read and
9477     written using `[]` operator. Note the addition of `null`
9478     values.,operatorarray__size_type}
9479     @since version 1.0.0
9480     */
operator [](size_type idx)9481     reference operator[](size_type idx)
9482     {
9483         // implicitly convert null value to an empty array
9484         if (is_null())
9485         {
9486             m_type = value_t::array;
9487             m_value.array = create<array_t>();
9488             assert_invariant();
9489         }
9490 
9491         // operator[] only works for arrays
9492         if (JSON_LIKELY(is_array()))
9493         {
9494             // fill up array with null values if given idx is outside range
9495             if (idx >= m_value.array->size())
9496             {
9497                 m_value.array->insert(m_value.array->end(),
9498                                       idx - m_value.array->size() + 1,
9499                                       basic_json());
9500             }
9501 
9502             return m_value.array->operator[](idx);
9503         }
9504 
9505         JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9506     }
9507 
9508     /*!
9509     @brief access specified array element
9510     Returns a const reference to the element at specified location @a idx.
9511     @param[in] idx  index of the element to access
9512     @return const reference to the element at index @a idx
9513     @throw type_error.305 if the JSON value is not an array; in that cases,
9514     using the [] operator with an index makes no sense.
9515     @complexity Constant.
9516     @liveexample{The example below shows how array elements can be read using
9517     the `[]` operator.,operatorarray__size_type_const}
9518     @since version 1.0.0
9519     */
operator [](size_type idx) const9520     const_reference operator[](size_type idx) const
9521     {
9522         // const operator[] only works for arrays
9523         if (JSON_LIKELY(is_array()))
9524         {
9525             return m_value.array->operator[](idx);
9526         }
9527 
9528         JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9529     }
9530 
9531     /*!
9532     @brief access specified object element
9533     Returns a reference to the element at with specified key @a key.
9534     @note If @a key is not found in the object, then it is silently added to
9535     the object and filled with a `null` value to make `key` a valid reference.
9536     In case the value was `null` before, it is converted to an object.
9537     @param[in] key  key of the element to access
9538     @return reference to the element at key @a key
9539     @throw type_error.305 if the JSON value is not an object or null; in that
9540     cases, using the [] operator with a key makes no sense.
9541     @complexity Logarithmic in the size of the container.
9542     @liveexample{The example below shows how object elements can be read and
9543     written using the `[]` operator.,operatorarray__key_type}
9544     @sa @ref at(const typename object_t::key_type&) for access by reference
9545     with range checking
9546     @sa @ref value() for access by value with a default value
9547     @since version 1.0.0
9548     */
operator [](const typename object_t::key_type & key)9549     reference operator[](const typename object_t::key_type& key)
9550     {
9551         // implicitly convert null value to an empty object
9552         if (is_null())
9553         {
9554             m_type = value_t::object;
9555             m_value.object = create<object_t>();
9556             assert_invariant();
9557         }
9558 
9559         // operator[] only works for objects
9560         if (JSON_LIKELY(is_object()))
9561         {
9562             return m_value.object->operator[](key);
9563         }
9564 
9565         JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9566     }
9567 
9568     /*!
9569     @brief read-only access specified object element
9570     Returns a const reference to the element at with specified key @a key. No
9571     bounds checking is performed.
9572     @warning If the element with key @a key does not exist, the behavior is
9573     undefined.
9574     @param[in] key  key of the element to access
9575     @return const reference to the element at key @a key
9576     @pre The element with key @a key must exist. **This precondition is
9577          enforced with an assertion.**
9578     @throw type_error.305 if the JSON value is not an object; in that cases,
9579     using the [] operator with a key makes no sense.
9580     @complexity Logarithmic in the size of the container.
9581     @liveexample{The example below shows how object elements can be read using
9582     the `[]` operator.,operatorarray__key_type_const}
9583     @sa @ref at(const typename object_t::key_type&) for access by reference
9584     with range checking
9585     @sa @ref value() for access by value with a default value
9586     @since version 1.0.0
9587     */
operator [](const typename object_t::key_type & key) const9588     const_reference operator[](const typename object_t::key_type& key) const
9589     {
9590         // const operator[] only works for objects
9591         if (JSON_LIKELY(is_object()))
9592         {
9593             assert(m_value.object->find(key) != m_value.object->end());
9594             return m_value.object->find(key)->second;
9595         }
9596 
9597         JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9598     }
9599 
9600     /*!
9601     @brief access specified object element
9602     Returns a reference to the element at with specified key @a key.
9603     @note If @a key is not found in the object, then it is silently added to
9604     the object and filled with a `null` value to make `key` a valid reference.
9605     In case the value was `null` before, it is converted to an object.
9606     @param[in] key  key of the element to access
9607     @return reference to the element at key @a key
9608     @throw type_error.305 if the JSON value is not an object or null; in that
9609     cases, using the [] operator with a key makes no sense.
9610     @complexity Logarithmic in the size of the container.
9611     @liveexample{The example below shows how object elements can be read and
9612     written using the `[]` operator.,operatorarray__key_type}
9613     @sa @ref at(const typename object_t::key_type&) for access by reference
9614     with range checking
9615     @sa @ref value() for access by value with a default value
9616     @since version 1.1.0
9617     */
9618     template<typename T>
operator [](T * key)9619     reference operator[](T* key)
9620     {
9621         // implicitly convert null to object
9622         if (is_null())
9623         {
9624             m_type = value_t::object;
9625             m_value = value_t::object;
9626             assert_invariant();
9627         }
9628 
9629         // at only works for objects
9630         if (JSON_LIKELY(is_object()))
9631         {
9632             return m_value.object->operator[](key);
9633         }
9634 
9635         JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9636     }
9637 
9638     /*!
9639     @brief read-only access specified object element
9640     Returns a const reference to the element at with specified key @a key. No
9641     bounds checking is performed.
9642     @warning If the element with key @a key does not exist, the behavior is
9643     undefined.
9644     @param[in] key  key of the element to access
9645     @return const reference to the element at key @a key
9646     @pre The element with key @a key must exist. **This precondition is
9647          enforced with an assertion.**
9648     @throw type_error.305 if the JSON value is not an object; in that cases,
9649     using the [] operator with a key makes no sense.
9650     @complexity Logarithmic in the size of the container.
9651     @liveexample{The example below shows how object elements can be read using
9652     the `[]` operator.,operatorarray__key_type_const}
9653     @sa @ref at(const typename object_t::key_type&) for access by reference
9654     with range checking
9655     @sa @ref value() for access by value with a default value
9656     @since version 1.1.0
9657     */
9658     template<typename T>
operator [](T * key) const9659     const_reference operator[](T* key) const
9660     {
9661         // at only works for objects
9662         if (JSON_LIKELY(is_object()))
9663         {
9664             assert(m_value.object->find(key) != m_value.object->end());
9665             return m_value.object->find(key)->second;
9666         }
9667 
9668         JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9669     }
9670 
9671     /*!
9672     @brief access specified object element with default value
9673     Returns either a copy of an object's element at the specified key @a key
9674     or a given default value if no element with key @a key exists.
9675     The function is basically equivalent to executing
9676     @code {.cpp}
9677     try {
9678         return at(key);
9679     } catch(out_of_range) {
9680         return default_value;
9681     }
9682     @endcode
9683     @note Unlike @ref at(const typename object_t::key_type&), this function
9684     does not throw if the given key @a key was not found.
9685     @note Unlike @ref operator[](const typename object_t::key_type& key), this
9686     function does not implicitly add an element to the position defined by @a
9687     key. This function is furthermore also applicable to const objects.
9688     @param[in] key  key of the element to access
9689     @param[in] default_value  the value to return if @a key is not found
9690     @tparam ValueType type compatible to JSON values, for instance `int` for
9691     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
9692     JSON arrays. Note the type of the expected value at @a key and the default
9693     value @a default_value must be compatible.
9694     @return copy of the element at key @a key or @a default_value if @a key
9695     is not found
9696     @throw type_error.306 if the JSON value is not an objec; in that cases,
9697     using `value()` with a key makes no sense.
9698     @complexity Logarithmic in the size of the container.
9699     @liveexample{The example below shows how object elements can be queried
9700     with a default value.,basic_json__value}
9701     @sa @ref at(const typename object_t::key_type&) for access by reference
9702     with range checking
9703     @sa @ref operator[](const typename object_t::key_type&) for unchecked
9704     access by reference
9705     @since version 1.0.0
9706     */
9707     template<class ValueType, typename std::enable_if<
9708                  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
9709     ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
9710     {
9711         // at only works for objects
9712         if (JSON_LIKELY(is_object()))
9713         {
9714             // if key is found, return value and given default value otherwise
9715             const auto it = find(key);
9716             if (it != end())
9717             {
9718                 return *it;
9719             }
9720 
9721             return default_value;
9722         }
9723 
9724         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
9725     }
9726 
9727     /*!
9728     @brief overload for a default value of type const char*
9729     @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
9730     */
value(const typename object_t::key_type & key,const char * default_value) const9731     string_t value(const typename object_t::key_type& key, const char* default_value) const
9732     {
9733         return value(key, string_t(default_value));
9734     }
9735 
9736     /*!
9737     @brief access specified object element via JSON Pointer with default value
9738     Returns either a copy of an object's element at the specified key @a key
9739     or a given default value if no element with key @a key exists.
9740     The function is basically equivalent to executing
9741     @code {.cpp}
9742     try {
9743         return at(ptr);
9744     } catch(out_of_range) {
9745         return default_value;
9746     }
9747     @endcode
9748     @note Unlike @ref at(const json_pointer&), this function does not throw
9749     if the given key @a key was not found.
9750     @param[in] ptr  a JSON pointer to the element to access
9751     @param[in] default_value  the value to return if @a ptr found no value
9752     @tparam ValueType type compatible to JSON values, for instance `int` for
9753     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
9754     JSON arrays. Note the type of the expected value at @a key and the default
9755     value @a default_value must be compatible.
9756     @return copy of the element at key @a key or @a default_value if @a key
9757     is not found
9758     @throw type_error.306 if the JSON value is not an objec; in that cases,
9759     using `value()` with a key makes no sense.
9760     @complexity Logarithmic in the size of the container.
9761     @liveexample{The example below shows how object elements can be queried
9762     with a default value.,basic_json__value_ptr}
9763     @sa @ref operator[](const json_pointer&) for unchecked access by reference
9764     @since version 2.0.2
9765     */
9766     template<class ValueType, typename std::enable_if<
9767                  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
9768     ValueType value(const json_pointer& ptr, const ValueType& default_value) const
9769     {
9770         // at only works for objects
9771         if (JSON_LIKELY(is_object()))
9772         {
9773             // if pointer resolves a value, return it or use default value
9774             JSON_TRY
9775             {
9776                 return ptr.get_checked(this);
9777             }
9778             JSON_CATCH (out_of_range&)
9779             {
9780                 return default_value;
9781             }
9782         }
9783 
9784         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
9785     }
9786 
9787     /*!
9788     @brief overload for a default value of type const char*
9789     @copydoc basic_json::value(const json_pointer&, ValueType) const
9790     */
value(const json_pointer & ptr,const char * default_value) const9791     string_t value(const json_pointer& ptr, const char* default_value) const
9792     {
9793         return value(ptr, string_t(default_value));
9794     }
9795 
9796     /*!
9797     @brief access the first element
9798     Returns a reference to the first element in the container. For a JSON
9799     container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
9800     @return In case of a structured type (array or object), a reference to the
9801     first element is returned. In case of number, string, or boolean values, a
9802     reference to the value is returned.
9803     @complexity Constant.
9804     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
9805     or an empty array or object (undefined behavior, **guarded by
9806     assertions**).
9807     @post The JSON value remains unchanged.
9808     @throw invalid_iterator.214 when called on `null` value
9809     @liveexample{The following code shows an example for `front()`.,front}
9810     @sa @ref back() -- access the last element
9811     @since version 1.0.0
9812     */
front()9813     reference front()
9814     {
9815         return *begin();
9816     }
9817 
9818     /*!
9819     @copydoc basic_json::front()
9820     */
front() const9821     const_reference front() const
9822     {
9823         return *cbegin();
9824     }
9825 
9826     /*!
9827     @brief access the last element
9828     Returns a reference to the last element in the container. For a JSON
9829     container `c`, the expression `c.back()` is equivalent to
9830     @code {.cpp}
9831     auto tmp = c.end();
9832     --tmp;
9833     return *tmp;
9834     @endcode
9835     @return In case of a structured type (array or object), a reference to the
9836     last element is returned. In case of number, string, or boolean values, a
9837     reference to the value is returned.
9838     @complexity Constant.
9839     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
9840     or an empty array or object (undefined behavior, **guarded by
9841     assertions**).
9842     @post The JSON value remains unchanged.
9843     @throw invalid_iterator.214 when called on a `null` value. See example
9844     below.
9845     @liveexample{The following code shows an example for `back()`.,back}
9846     @sa @ref front() -- access the first element
9847     @since version 1.0.0
9848     */
back()9849     reference back()
9850     {
9851         auto tmp = end();
9852         --tmp;
9853         return *tmp;
9854     }
9855 
9856     /*!
9857     @copydoc basic_json::back()
9858     */
back() const9859     const_reference back() const
9860     {
9861         auto tmp = cend();
9862         --tmp;
9863         return *tmp;
9864     }
9865 
9866     /*!
9867     @brief remove element given an iterator
9868     Removes the element specified by iterator @a pos. The iterator @a pos must
9869     be valid and dereferenceable. Thus the `end()` iterator (which is valid,
9870     but is not dereferenceable) cannot be used as a value for @a pos.
9871     If called on a primitive type other than `null`, the resulting JSON value
9872     will be `null`.
9873     @param[in] pos iterator to the element to remove
9874     @return Iterator following the last removed element. If the iterator @a
9875     pos refers to the last element, the `end()` iterator is returned.
9876     @tparam IteratorType an @ref iterator or @ref const_iterator
9877     @post Invalidates iterators and references at or after the point of the
9878     erase, including the `end()` iterator.
9879     @throw type_error.307 if called on a `null` value; example: `"cannot use
9880     erase() with null"`
9881     @throw invalid_iterator.202 if called on an iterator which does not belong
9882     to the current JSON value; example: `"iterator does not fit current
9883     value"`
9884     @throw invalid_iterator.205 if called on a primitive type with invalid
9885     iterator (i.e., any iterator which is not `begin()`); example: `"iterator
9886     out of range"`
9887     @complexity The complexity depends on the type:
9888     - objects: amortized constant
9889     - arrays: linear in distance between @a pos and the end of the container
9890     - strings: linear in the length of the string
9891     - other types: constant
9892     @liveexample{The example shows the result of `erase()` for different JSON
9893     types.,erase__IteratorType}
9894     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
9895     the given range
9896     @sa @ref erase(const typename object_t::key_type&) -- removes the element
9897     from an object at the given key
9898     @sa @ref erase(const size_type) -- removes the element from an array at
9899     the given index
9900     @since version 1.0.0
9901     */
9902     template<class IteratorType, typename std::enable_if<
9903                  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
9904                  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
9905              = 0>
9906     IteratorType erase(IteratorType pos)
9907     {
9908         // make sure iterator fits the current value
9909         if (JSON_UNLIKELY(this != pos.m_object))
9910         {
9911             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
9912         }
9913 
9914         IteratorType result = end();
9915 
9916         switch (m_type)
9917         {
9918             case value_t::boolean:
9919             case value_t::number_float:
9920             case value_t::number_integer:
9921             case value_t::number_unsigned:
9922             case value_t::string:
9923             {
9924                 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
9925                 {
9926                     JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
9927                 }
9928 
9929                 if (is_string())
9930                 {
9931                     AllocatorType<string_t> alloc;
9932                     alloc.destroy(m_value.string);
9933                     alloc.deallocate(m_value.string, 1);
9934                     m_value.string = nullptr;
9935                 }
9936 
9937                 m_type = value_t::null;
9938                 assert_invariant();
9939                 break;
9940             }
9941 
9942             case value_t::object:
9943             {
9944                 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
9945                 break;
9946             }
9947 
9948             case value_t::array:
9949             {
9950                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
9951                 break;
9952             }
9953 
9954             default:
9955                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
9956         }
9957 
9958         return result;
9959     }
9960 
9961     /*!
9962     @brief remove elements given an iterator range
9963     Removes the element specified by the range `[first; last)`. The iterator
9964     @a first does not need to be dereferenceable if `first == last`: erasing
9965     an empty range is a no-op.
9966     If called on a primitive type other than `null`, the resulting JSON value
9967     will be `null`.
9968     @param[in] first iterator to the beginning of the range to remove
9969     @param[in] last iterator past the end of the range to remove
9970     @return Iterator following the last removed element. If the iterator @a
9971     second refers to the last element, the `end()` iterator is returned.
9972     @tparam IteratorType an @ref iterator or @ref const_iterator
9973     @post Invalidates iterators and references at or after the point of the
9974     erase, including the `end()` iterator.
9975     @throw type_error.307 if called on a `null` value; example: `"cannot use
9976     erase() with null"`
9977     @throw invalid_iterator.203 if called on iterators which does not belong
9978     to the current JSON value; example: `"iterators do not fit current value"`
9979     @throw invalid_iterator.204 if called on a primitive type with invalid
9980     iterators (i.e., if `first != begin()` and `last != end()`); example:
9981     `"iterators out of range"`
9982     @complexity The complexity depends on the type:
9983     - objects: `log(size()) + std::distance(first, last)`
9984     - arrays: linear in the distance between @a first and @a last, plus linear
9985       in the distance between @a last and end of the container
9986     - strings: linear in the length of the string
9987     - other types: constant
9988     @liveexample{The example shows the result of `erase()` for different JSON
9989     types.,erase__IteratorType_IteratorType}
9990     @sa @ref erase(IteratorType) -- removes the element at a given position
9991     @sa @ref erase(const typename object_t::key_type&) -- removes the element
9992     from an object at the given key
9993     @sa @ref erase(const size_type) -- removes the element from an array at
9994     the given index
9995     @since version 1.0.0
9996     */
9997     template<class IteratorType, typename std::enable_if<
9998                  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
9999                  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
10000              = 0>
10001     IteratorType erase(IteratorType first, IteratorType last)
10002     {
10003         // make sure iterator fits the current value
10004         if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
10005         {
10006             JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
10007         }
10008 
10009         IteratorType result = end();
10010 
10011         switch (m_type)
10012         {
10013             case value_t::boolean:
10014             case value_t::number_float:
10015             case value_t::number_integer:
10016             case value_t::number_unsigned:
10017             case value_t::string:
10018             {
10019                 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
10020                                 or not last.m_it.primitive_iterator.is_end()))
10021                 {
10022                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
10023                 }
10024 
10025                 if (is_string())
10026                 {
10027                     AllocatorType<string_t> alloc;
10028                     alloc.destroy(m_value.string);
10029                     alloc.deallocate(m_value.string, 1);
10030                     m_value.string = nullptr;
10031                 }
10032 
10033                 m_type = value_t::null;
10034                 assert_invariant();
10035                 break;
10036             }
10037 
10038             case value_t::object:
10039             {
10040                 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
10041                                               last.m_it.object_iterator);
10042                 break;
10043             }
10044 
10045             case value_t::array:
10046             {
10047                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
10048                                              last.m_it.array_iterator);
10049                 break;
10050             }
10051 
10052             default:
10053                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10054         }
10055 
10056         return result;
10057     }
10058 
10059     /*!
10060     @brief remove element from a JSON object given a key
10061     Removes elements from a JSON object with the key value @a key.
10062     @param[in] key value of the elements to remove
10063     @return Number of elements removed. If @a ObjectType is the default
10064     `std::map` type, the return value will always be `0` (@a key was not
10065     found) or `1` (@a key was found).
10066     @post References and iterators to the erased elements are invalidated.
10067     Other references and iterators are not affected.
10068     @throw type_error.307 when called on a type other than JSON object;
10069     example: `"cannot use erase() with null"`
10070     @complexity `log(size()) + count(key)`
10071     @liveexample{The example shows the effect of `erase()`.,erase__key_type}
10072     @sa @ref erase(IteratorType) -- removes the element at a given position
10073     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
10074     the given range
10075     @sa @ref erase(const size_type) -- removes the element from an array at
10076     the given index
10077     @since version 1.0.0
10078     */
erase(const typename object_t::key_type & key)10079     size_type erase(const typename object_t::key_type& key)
10080     {
10081         // this erase only works for objects
10082         if (JSON_LIKELY(is_object()))
10083         {
10084             return m_value.object->erase(key);
10085         }
10086 
10087         JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10088     }
10089 
10090     /*!
10091     @brief remove element from a JSON array given an index
10092     Removes element from a JSON array at the index @a idx.
10093     @param[in] idx index of the element to remove
10094     @throw type_error.307 when called on a type other than JSON object;
10095     example: `"cannot use erase() with null"`
10096     @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
10097     is out of range"`
10098     @complexity Linear in distance between @a idx and the end of the container.
10099     @liveexample{The example shows the effect of `erase()`.,erase__size_type}
10100     @sa @ref erase(IteratorType) -- removes the element at a given position
10101     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
10102     the given range
10103     @sa @ref erase(const typename object_t::key_type&) -- removes the element
10104     from an object at the given key
10105     @since version 1.0.0
10106     */
erase(const size_type idx)10107     void erase(const size_type idx)
10108     {
10109         // this erase only works for arrays
10110         if (JSON_LIKELY(is_array()))
10111         {
10112             if (JSON_UNLIKELY(idx >= size()))
10113             {
10114                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
10115             }
10116 
10117             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
10118         }
10119         else
10120         {
10121             JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10122         }
10123     }
10124 
10125     /// @}
10126 
10127 
10128     ////////////
10129     // lookup //
10130     ////////////
10131 
10132     /// @name lookup
10133     /// @{
10134 
10135     /*!
10136     @brief find an element in a JSON object
10137     Finds an element in a JSON object with key equivalent to @a key. If the
10138     element is not found or the JSON value is not an object, end() is
10139     returned.
10140     @note This method always returns @ref end() when executed on a JSON type
10141           that is not an object.
10142     @param[in] key key value of the element to search for.
10143     @return Iterator to an element with key equivalent to @a key. If no such
10144     element is found or the JSON value is not an object, past-the-end (see
10145     @ref end()) iterator is returned.
10146     @complexity Logarithmic in the size of the JSON object.
10147     @liveexample{The example shows how `find()` is used.,find__key_type}
10148     @since version 1.0.0
10149     */
10150     template<typename KeyT>
find(KeyT && key)10151     iterator find(KeyT&& key)
10152     {
10153         auto result = end();
10154 
10155         if (is_object())
10156         {
10157             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10158         }
10159 
10160         return result;
10161     }
10162 
10163     /*!
10164     @brief find an element in a JSON object
10165     @copydoc find(KeyT&&)
10166     */
10167     template<typename KeyT>
find(KeyT && key) const10168     const_iterator find(KeyT&& key) const
10169     {
10170         auto result = cend();
10171 
10172         if (is_object())
10173         {
10174             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10175         }
10176 
10177         return result;
10178     }
10179 
10180     /*!
10181     @brief returns the number of occurrences of a key in a JSON object
10182     Returns the number of elements with key @a key. If ObjectType is the
10183     default `std::map` type, the return value will always be `0` (@a key was
10184     not found) or `1` (@a key was found).
10185     @note This method always returns `0` when executed on a JSON type that is
10186           not an object.
10187     @param[in] key key value of the element to count
10188     @return Number of elements with key @a key. If the JSON value is not an
10189     object, the return value will be `0`.
10190     @complexity Logarithmic in the size of the JSON object.
10191     @liveexample{The example shows how `count()` is used.,count}
10192     @since version 1.0.0
10193     */
10194     template<typename KeyT>
count(KeyT && key) const10195     size_type count(KeyT&& key) const
10196     {
10197         // return 0 for all nonobject types
10198         return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
10199     }
10200 
10201     /// @}
10202 
10203 
10204     ///////////////
10205     // iterators //
10206     ///////////////
10207 
10208     /// @name iterators
10209     /// @{
10210 
10211     /*!
10212     @brief returns an iterator to the first element
10213     Returns an iterator to the first element.
10214     @image html range-begin-end.svg "Illustration from cppreference.com"
10215     @return iterator to the first element
10216     @complexity Constant.
10217     @requirement This function helps `basic_json` satisfying the
10218     [Container](http://en.cppreference.com/w/cpp/concept/Container)
10219     requirements:
10220     - The complexity is constant.
10221     @liveexample{The following code shows an example for `begin()`.,begin}
10222     @sa @ref cbegin() -- returns a const iterator to the beginning
10223     @sa @ref end() -- returns an iterator to the end
10224     @sa @ref cend() -- returns a const iterator to the end
10225     @since version 1.0.0
10226     */
begin()10227     iterator begin() noexcept
10228     {
10229         iterator result(this);
10230         result.set_begin();
10231         return result;
10232     }
10233 
10234     /*!
10235     @copydoc basic_json::cbegin()
10236     */
begin() const10237     const_iterator begin() const noexcept
10238     {
10239         return cbegin();
10240     }
10241 
10242     /*!
10243     @brief returns a const iterator to the first element
10244     Returns a const iterator to the first element.
10245     @image html range-begin-end.svg "Illustration from cppreference.com"
10246     @return const iterator to the first element
10247     @complexity Constant.
10248     @requirement This function helps `basic_json` satisfying the
10249     [Container](http://en.cppreference.com/w/cpp/concept/Container)
10250     requirements:
10251     - The complexity is constant.
10252     - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
10253     @liveexample{The following code shows an example for `cbegin()`.,cbegin}
10254     @sa @ref begin() -- returns an iterator to the beginning
10255     @sa @ref end() -- returns an iterator to the end
10256     @sa @ref cend() -- returns a const iterator to the end
10257     @since version 1.0.0
10258     */
cbegin() const10259     const_iterator cbegin() const noexcept
10260     {
10261         const_iterator result(this);
10262         result.set_begin();
10263         return result;
10264     }
10265 
10266     /*!
10267     @brief returns an iterator to one past the last element
10268     Returns an iterator to one past the last element.
10269     @image html range-begin-end.svg "Illustration from cppreference.com"
10270     @return iterator one past the last element
10271     @complexity Constant.
10272     @requirement This function helps `basic_json` satisfying the
10273     [Container](http://en.cppreference.com/w/cpp/concept/Container)
10274     requirements:
10275     - The complexity is constant.
10276     @liveexample{The following code shows an example for `end()`.,end}
10277     @sa @ref cend() -- returns a const iterator to the end
10278     @sa @ref begin() -- returns an iterator to the beginning
10279     @sa @ref cbegin() -- returns a const iterator to the beginning
10280     @since version 1.0.0
10281     */
end()10282     iterator end() noexcept
10283     {
10284         iterator result(this);
10285         result.set_end();
10286         return result;
10287     }
10288 
10289     /*!
10290     @copydoc basic_json::cend()
10291     */
end() const10292     const_iterator end() const noexcept
10293     {
10294         return cend();
10295     }
10296 
10297     /*!
10298     @brief returns a const iterator to one past the last element
10299     Returns a const iterator to one past the last element.
10300     @image html range-begin-end.svg "Illustration from cppreference.com"
10301     @return const iterator one past the last element
10302     @complexity Constant.
10303     @requirement This function helps `basic_json` satisfying the
10304     [Container](http://en.cppreference.com/w/cpp/concept/Container)
10305     requirements:
10306     - The complexity is constant.
10307     - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
10308     @liveexample{The following code shows an example for `cend()`.,cend}
10309     @sa @ref end() -- returns an iterator to the end
10310     @sa @ref begin() -- returns an iterator to the beginning
10311     @sa @ref cbegin() -- returns a const iterator to the beginning
10312     @since version 1.0.0
10313     */
cend() const10314     const_iterator cend() const noexcept
10315     {
10316         const_iterator result(this);
10317         result.set_end();
10318         return result;
10319     }
10320 
10321     /*!
10322     @brief returns an iterator to the reverse-beginning
10323     Returns an iterator to the reverse-beginning; that is, the last element.
10324     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
10325     @complexity Constant.
10326     @requirement This function helps `basic_json` satisfying the
10327     [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
10328     requirements:
10329     - The complexity is constant.
10330     - Has the semantics of `reverse_iterator(end())`.
10331     @liveexample{The following code shows an example for `rbegin()`.,rbegin}
10332     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
10333     @sa @ref rend() -- returns a reverse iterator to the end
10334     @sa @ref crend() -- returns a const reverse iterator to the end
10335     @since version 1.0.0
10336     */
rbegin()10337     reverse_iterator rbegin() noexcept
10338     {
10339         return reverse_iterator(end());
10340     }
10341 
10342     /*!
10343     @copydoc basic_json::crbegin()
10344     */
rbegin() const10345     const_reverse_iterator rbegin() const noexcept
10346     {
10347         return crbegin();
10348     }
10349 
10350     /*!
10351     @brief returns an iterator to the reverse-end
10352     Returns an iterator to the reverse-end; that is, one before the first
10353     element.
10354     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
10355     @complexity Constant.
10356     @requirement This function helps `basic_json` satisfying the
10357     [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
10358     requirements:
10359     - The complexity is constant.
10360     - Has the semantics of `reverse_iterator(begin())`.
10361     @liveexample{The following code shows an example for `rend()`.,rend}
10362     @sa @ref crend() -- returns a const reverse iterator to the end
10363     @sa @ref rbegin() -- returns a reverse iterator to the beginning
10364     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
10365     @since version 1.0.0
10366     */
rend()10367     reverse_iterator rend() noexcept
10368     {
10369         return reverse_iterator(begin());
10370     }
10371 
10372     /*!
10373     @copydoc basic_json::crend()
10374     */
rend() const10375     const_reverse_iterator rend() const noexcept
10376     {
10377         return crend();
10378     }
10379 
10380     /*!
10381     @brief returns a const reverse iterator to the last element
10382     Returns a const iterator to the reverse-beginning; that is, the last
10383     element.
10384     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
10385     @complexity Constant.
10386     @requirement This function helps `basic_json` satisfying the
10387     [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
10388     requirements:
10389     - The complexity is constant.
10390     - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
10391     @liveexample{The following code shows an example for `crbegin()`.,crbegin}
10392     @sa @ref rbegin() -- returns a reverse iterator to the beginning
10393     @sa @ref rend() -- returns a reverse iterator to the end
10394     @sa @ref crend() -- returns a const reverse iterator to the end
10395     @since version 1.0.0
10396     */
crbegin() const10397     const_reverse_iterator crbegin() const noexcept
10398     {
10399         return const_reverse_iterator(cend());
10400     }
10401 
10402     /*!
10403     @brief returns a const reverse iterator to one before the first
10404     Returns a const reverse iterator to the reverse-end; that is, one before
10405     the first element.
10406     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
10407     @complexity Constant.
10408     @requirement This function helps `basic_json` satisfying the
10409     [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
10410     requirements:
10411     - The complexity is constant.
10412     - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
10413     @liveexample{The following code shows an example for `crend()`.,crend}
10414     @sa @ref rend() -- returns a reverse iterator to the end
10415     @sa @ref rbegin() -- returns a reverse iterator to the beginning
10416     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
10417     @since version 1.0.0
10418     */
crend() const10419     const_reverse_iterator crend() const noexcept
10420     {
10421         return const_reverse_iterator(cbegin());
10422     }
10423 
10424   public:
10425     /*!
10426     @brief wrapper to access iterator member functions in range-based for
10427     This function allows to access @ref iterator::key() and @ref
10428     iterator::value() during range-based for loops. In these loops, a
10429     reference to the JSON values is returned, so there is no access to the
10430     underlying iterator.
10431     @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
10432     @note The name of this function is not yet final and may change in the
10433     future.
10434     */
iterator_wrapper(reference cont)10435     static iteration_proxy<iterator> iterator_wrapper(reference cont)
10436     {
10437         return iteration_proxy<iterator>(cont);
10438     }
10439 
10440     /*!
10441     @copydoc iterator_wrapper(reference)
10442     */
iterator_wrapper(const_reference cont)10443     static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
10444     {
10445         return iteration_proxy<const_iterator>(cont);
10446     }
10447 
10448     /// @}
10449 
10450 
10451     //////////////
10452     // capacity //
10453     //////////////
10454 
10455     /// @name capacity
10456     /// @{
10457 
10458     /*!
10459     @brief checks whether the container is empty.
10460     Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
10461     @return The return value depends on the different types and is
10462             defined as follows:
10463             Value type  | return value
10464             ----------- | -------------
10465             null        | `true`
10466             boolean     | `false`
10467             string      | `false`
10468             number      | `false`
10469             object      | result of function `object_t::empty()`
10470             array       | result of function `array_t::empty()`
10471     @liveexample{The following code uses `empty()` to check if a JSON
10472     object contains any elements.,empty}
10473     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
10474     the Container concept; that is, their `empty()` functions have constant
10475     complexity.
10476     @iterators No changes.
10477     @exceptionsafety No-throw guarantee: this function never throws exceptions.
10478     @note This function does not return whether a string stored as JSON value
10479     is empty - it returns whether the JSON container itself is empty which is
10480     false in the case of a string.
10481     @requirement This function helps `basic_json` satisfying the
10482     [Container](http://en.cppreference.com/w/cpp/concept/Container)
10483     requirements:
10484     - The complexity is constant.
10485     - Has the semantics of `begin() == end()`.
10486     @sa @ref size() -- returns the number of elements
10487     @since version 1.0.0
10488     */
empty() const10489     bool empty() const noexcept
10490     {
10491         switch (m_type)
10492         {
10493             case value_t::null:
10494             {
10495                 // null values are empty
10496                 return true;
10497             }
10498 
10499             case value_t::array:
10500             {
10501                 // delegate call to array_t::empty()
10502                 return m_value.array->empty();
10503             }
10504 
10505             case value_t::object:
10506             {
10507                 // delegate call to object_t::empty()
10508                 return m_value.object->empty();
10509             }
10510 
10511             default:
10512             {
10513                 // all other types are nonempty
10514                 return false;
10515             }
10516         }
10517     }
10518 
10519     /*!
10520     @brief returns the number of elements
10521     Returns the number of elements in a JSON value.
10522     @return The return value depends on the different types and is
10523             defined as follows:
10524             Value type  | return value
10525             ----------- | -------------
10526             null        | `0`
10527             boolean     | `1`
10528             string      | `1`
10529             number      | `1`
10530             object      | result of function object_t::size()
10531             array       | result of function array_t::size()
10532     @liveexample{The following code calls `size()` on the different value
10533     types.,size}
10534     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
10535     the Container concept; that is, their size() functions have constant
10536     complexity.
10537     @iterators No changes.
10538     @exceptionsafety No-throw guarantee: this function never throws exceptions.
10539     @note This function does not return the length of a string stored as JSON
10540     value - it returns the number of elements in the JSON value which is 1 in
10541     the case of a string.
10542     @requirement This function helps `basic_json` satisfying the
10543     [Container](http://en.cppreference.com/w/cpp/concept/Container)
10544     requirements:
10545     - The complexity is constant.
10546     - Has the semantics of `std::distance(begin(), end())`.
10547     @sa @ref empty() -- checks whether the container is empty
10548     @sa @ref max_size() -- returns the maximal number of elements
10549     @since version 1.0.0
10550     */
size() const10551     size_type size() const noexcept
10552     {
10553         switch (m_type)
10554         {
10555             case value_t::null:
10556             {
10557                 // null values are empty
10558                 return 0;
10559             }
10560 
10561             case value_t::array:
10562             {
10563                 // delegate call to array_t::size()
10564                 return m_value.array->size();
10565             }
10566 
10567             case value_t::object:
10568             {
10569                 // delegate call to object_t::size()
10570                 return m_value.object->size();
10571             }
10572 
10573             default:
10574             {
10575                 // all other types have size 1
10576                 return 1;
10577             }
10578         }
10579     }
10580 
10581     /*!
10582     @brief returns the maximum possible number of elements
10583     Returns the maximum number of elements a JSON value is able to hold due to
10584     system or library implementation limitations, i.e. `std::distance(begin(),
10585     end())` for the JSON value.
10586     @return The return value depends on the different types and is
10587             defined as follows:
10588             Value type  | return value
10589             ----------- | -------------
10590             null        | `0` (same as `size()`)
10591             boolean     | `1` (same as `size()`)
10592             string      | `1` (same as `size()`)
10593             number      | `1` (same as `size()`)
10594             object      | result of function `object_t::max_size()`
10595             array       | result of function `array_t::max_size()`
10596     @liveexample{The following code calls `max_size()` on the different value
10597     types. Note the output is implementation specific.,max_size}
10598     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
10599     the Container concept; that is, their `max_size()` functions have constant
10600     complexity.
10601     @iterators No changes.
10602     @exceptionsafety No-throw guarantee: this function never throws exceptions.
10603     @requirement This function helps `basic_json` satisfying the
10604     [Container](http://en.cppreference.com/w/cpp/concept/Container)
10605     requirements:
10606     - The complexity is constant.
10607     - Has the semantics of returning `b.size()` where `b` is the largest
10608       possible JSON value.
10609     @sa @ref size() -- returns the number of elements
10610     @since version 1.0.0
10611     */
max_size() const10612     size_type max_size() const noexcept
10613     {
10614         switch (m_type)
10615         {
10616             case value_t::array:
10617             {
10618                 // delegate call to array_t::max_size()
10619                 return m_value.array->max_size();
10620             }
10621 
10622             case value_t::object:
10623             {
10624                 // delegate call to object_t::max_size()
10625                 return m_value.object->max_size();
10626             }
10627 
10628             default:
10629             {
10630                 // all other types have max_size() == size()
10631                 return size();
10632             }
10633         }
10634     }
10635 
10636     /// @}
10637 
10638 
10639     ///////////////
10640     // modifiers //
10641     ///////////////
10642 
10643     /// @name modifiers
10644     /// @{
10645 
10646     /*!
10647     @brief clears the contents
10648     Clears the content of a JSON value and resets it to the default value as
10649     if @ref basic_json(value_t) would have been called with the current value
10650     type from @ref type():
10651     Value type  | initial value
10652     ----------- | -------------
10653     null        | `null`
10654     boolean     | `false`
10655     string      | `""`
10656     number      | `0`
10657     object      | `{}`
10658     array       | `[]`
10659     @post Has the same effect as calling
10660     @code {.cpp}
10661     *this = basic_json(type());
10662     @endcode
10663     @liveexample{The example below shows the effect of `clear()` to different
10664     JSON types.,clear}
10665     @complexity Linear in the size of the JSON value.
10666     @iterators All iterators, pointers and references related to this container
10667                are invalidated.
10668     @exceptionsafety No-throw guarantee: this function never throws exceptions.
10669     @sa @ref basic_json(value_t) -- constructor that creates an object with the
10670         same value than calling `clear()`
10671     @since version 1.0.0
10672     */
clear()10673     void clear() noexcept
10674     {
10675         switch (m_type)
10676         {
10677             case value_t::number_integer:
10678             {
10679                 m_value.number_integer = 0;
10680                 break;
10681             }
10682 
10683             case value_t::number_unsigned:
10684             {
10685                 m_value.number_unsigned = 0;
10686                 break;
10687             }
10688 
10689             case value_t::number_float:
10690             {
10691                 m_value.number_float = 0.0;
10692                 break;
10693             }
10694 
10695             case value_t::boolean:
10696             {
10697                 m_value.boolean = false;
10698                 break;
10699             }
10700 
10701             case value_t::string:
10702             {
10703                 m_value.string->clear();
10704                 break;
10705             }
10706 
10707             case value_t::array:
10708             {
10709                 m_value.array->clear();
10710                 break;
10711             }
10712 
10713             case value_t::object:
10714             {
10715                 m_value.object->clear();
10716                 break;
10717             }
10718 
10719             default:
10720                 break;
10721         }
10722     }
10723 
10724     /*!
10725     @brief add an object to an array
10726     Appends the given element @a val to the end of the JSON value. If the
10727     function is called on a JSON null value, an empty array is created before
10728     appending @a val.
10729     @param[in] val the value to add to the JSON array
10730     @throw type_error.308 when called on a type other than JSON array or
10731     null; example: `"cannot use push_back() with number"`
10732     @complexity Amortized constant.
10733     @liveexample{The example shows how `push_back()` and `+=` can be used to
10734     add elements to a JSON array. Note how the `null` value was silently
10735     converted to a JSON array.,push_back}
10736     @since version 1.0.0
10737     */
push_back(basic_json && val)10738     void push_back(basic_json&& val)
10739     {
10740         // push_back only works for null objects or arrays
10741         if (JSON_UNLIKELY(not(is_null() or is_array())))
10742         {
10743             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
10744         }
10745 
10746         // transform null object into an array
10747         if (is_null())
10748         {
10749             m_type = value_t::array;
10750             m_value = value_t::array;
10751             assert_invariant();
10752         }
10753 
10754         // add element to array (move semantics)
10755         m_value.array->push_back(std::move(val));
10756         // invalidate object
10757         val.m_type = value_t::null;
10758     }
10759 
10760     /*!
10761     @brief add an object to an array
10762     @copydoc push_back(basic_json&&)
10763     */
operator +=(basic_json && val)10764     reference operator+=(basic_json&& val)
10765     {
10766         push_back(std::move(val));
10767         return *this;
10768     }
10769 
10770     /*!
10771     @brief add an object to an array
10772     @copydoc push_back(basic_json&&)
10773     */
push_back(const basic_json & val)10774     void push_back(const basic_json& val)
10775     {
10776         // push_back only works for null objects or arrays
10777         if (JSON_UNLIKELY(not(is_null() or is_array())))
10778         {
10779             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
10780         }
10781 
10782         // transform null object into an array
10783         if (is_null())
10784         {
10785             m_type = value_t::array;
10786             m_value = value_t::array;
10787             assert_invariant();
10788         }
10789 
10790         // add element to array
10791         m_value.array->push_back(val);
10792     }
10793 
10794     /*!
10795     @brief add an object to an array
10796     @copydoc push_back(basic_json&&)
10797     */
operator +=(const basic_json & val)10798     reference operator+=(const basic_json& val)
10799     {
10800         push_back(val);
10801         return *this;
10802     }
10803 
10804     /*!
10805     @brief add an object to an object
10806     Inserts the given element @a val to the JSON object. If the function is
10807     called on a JSON null value, an empty object is created before inserting
10808     @a val.
10809     @param[in] val the value to add to the JSON object
10810     @throw type_error.308 when called on a type other than JSON object or
10811     null; example: `"cannot use push_back() with number"`
10812     @complexity Logarithmic in the size of the container, O(log(`size()`)).
10813     @liveexample{The example shows how `push_back()` and `+=` can be used to
10814     add elements to a JSON object. Note how the `null` value was silently
10815     converted to a JSON object.,push_back__object_t__value}
10816     @since version 1.0.0
10817     */
push_back(const typename object_t::value_type & val)10818     void push_back(const typename object_t::value_type& val)
10819     {
10820         // push_back only works for null objects or objects
10821         if (JSON_UNLIKELY(not(is_null() or is_object())))
10822         {
10823             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
10824         }
10825 
10826         // transform null object into an object
10827         if (is_null())
10828         {
10829             m_type = value_t::object;
10830             m_value = value_t::object;
10831             assert_invariant();
10832         }
10833 
10834         // add element to array
10835         m_value.object->insert(val);
10836     }
10837 
10838     /*!
10839     @brief add an object to an object
10840     @copydoc push_back(const typename object_t::value_type&)
10841     */
operator +=(const typename object_t::value_type & val)10842     reference operator+=(const typename object_t::value_type& val)
10843     {
10844         push_back(val);
10845         return *this;
10846     }
10847 
10848     /*!
10849     @brief add an object to an object
10850     This function allows to use `push_back` with an initializer list. In case
10851     1. the current value is an object,
10852     2. the initializer list @a init contains only two elements, and
10853     3. the first element of @a init is a string,
10854     @a init is converted into an object element and added using
10855     @ref push_back(const typename object_t::value_type&). Otherwise, @a init
10856     is converted to a JSON value and added using @ref push_back(basic_json&&).
10857     @param[in] init  an initializer list
10858     @complexity Linear in the size of the initializer list @a init.
10859     @note This function is required to resolve an ambiguous overload error,
10860           because pairs like `{"key", "value"}` can be both interpreted as
10861           `object_t::value_type` or `std::initializer_list<basic_json>`, see
10862           https://github.com/nlohmann/json/issues/235 for more information.
10863     @liveexample{The example shows how initializer lists are treated as
10864     objects when possible.,push_back__initializer_list}
10865     */
push_back(initializer_list_t init)10866     void push_back(initializer_list_t init)
10867     {
10868         if (is_object() and init.size() == 2 and (*init.begin())->is_string())
10869         {
10870             basic_json&& key = init.begin()->moved_or_copied();
10871             push_back(typename object_t::value_type(
10872                           std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
10873         }
10874         else
10875         {
10876             push_back(basic_json(init));
10877         }
10878     }
10879 
10880     /*!
10881     @brief add an object to an object
10882     @copydoc push_back(initializer_list_t)
10883     */
operator +=(initializer_list_t init)10884     reference operator+=(initializer_list_t init)
10885     {
10886         push_back(init);
10887         return *this;
10888     }
10889 
10890     /*!
10891     @brief add an object to an array
10892     Creates a JSON value from the passed parameters @a args to the end of the
10893     JSON value. If the function is called on a JSON null value, an empty array
10894     is created before appending the value created from @a args.
10895     @param[in] args arguments to forward to a constructor of @ref basic_json
10896     @tparam Args compatible types to create a @ref basic_json object
10897     @throw type_error.311 when called on a type other than JSON array or
10898     null; example: `"cannot use emplace_back() with number"`
10899     @complexity Amortized constant.
10900     @liveexample{The example shows how `push_back()` can be used to add
10901     elements to a JSON array. Note how the `null` value was silently converted
10902     to a JSON array.,emplace_back}
10903     @since version 2.0.8
10904     */
10905     template<class... Args>
emplace_back(Args &&...args)10906     void emplace_back(Args&& ... args)
10907     {
10908         // emplace_back only works for null objects or arrays
10909         if (JSON_UNLIKELY(not(is_null() or is_array())))
10910         {
10911             JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
10912         }
10913 
10914         // transform null object into an array
10915         if (is_null())
10916         {
10917             m_type = value_t::array;
10918             m_value = value_t::array;
10919             assert_invariant();
10920         }
10921 
10922         // add element to array (perfect forwarding)
10923         m_value.array->emplace_back(std::forward<Args>(args)...);
10924     }
10925 
10926     /*!
10927     @brief add an object to an object if key does not exist
10928     Inserts a new element into a JSON object constructed in-place with the
10929     given @a args if there is no element with the key in the container. If the
10930     function is called on a JSON null value, an empty object is created before
10931     appending the value created from @a args.
10932     @param[in] args arguments to forward to a constructor of @ref basic_json
10933     @tparam Args compatible types to create a @ref basic_json object
10934     @return a pair consisting of an iterator to the inserted element, or the
10935             already-existing element if no insertion happened, and a bool
10936             denoting whether the insertion took place.
10937     @throw type_error.311 when called on a type other than JSON object or
10938     null; example: `"cannot use emplace() with number"`
10939     @complexity Logarithmic in the size of the container, O(log(`size()`)).
10940     @liveexample{The example shows how `emplace()` can be used to add elements
10941     to a JSON object. Note how the `null` value was silently converted to a
10942     JSON object. Further note how no value is added if there was already one
10943     value stored with the same key.,emplace}
10944     @since version 2.0.8
10945     */
10946     template<class... Args>
emplace(Args &&...args)10947     std::pair<iterator, bool> emplace(Args&& ... args)
10948     {
10949         // emplace only works for null objects or arrays
10950         if (JSON_UNLIKELY(not(is_null() or is_object())))
10951         {
10952             JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
10953         }
10954 
10955         // transform null object into an object
10956         if (is_null())
10957         {
10958             m_type = value_t::object;
10959             m_value = value_t::object;
10960             assert_invariant();
10961         }
10962 
10963         // add element to array (perfect forwarding)
10964         auto res = m_value.object->emplace(std::forward<Args>(args)...);
10965         // create result iterator and set iterator to the result of emplace
10966         auto it = begin();
10967         it.m_it.object_iterator = res.first;
10968 
10969         // return pair of iterator and boolean
10970         return {it, res.second};
10971     }
10972 
10973     /*!
10974     @brief inserts element
10975     Inserts element @a val before iterator @a pos.
10976     @param[in] pos iterator before which the content will be inserted; may be
10977     the end() iterator
10978     @param[in] val element to insert
10979     @return iterator pointing to the inserted @a val.
10980     @throw type_error.309 if called on JSON values other than arrays;
10981     example: `"cannot use insert() with string"`
10982     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
10983     example: `"iterator does not fit current value"`
10984     @complexity Constant plus linear in the distance between @a pos and end of
10985     the container.
10986     @liveexample{The example shows how `insert()` is used.,insert}
10987     @since version 1.0.0
10988     */
insert(const_iterator pos,const basic_json & val)10989     iterator insert(const_iterator pos, const basic_json& val)
10990     {
10991         // insert only works for arrays
10992         if (JSON_LIKELY(is_array()))
10993         {
10994             // check if iterator pos fits to this JSON value
10995             if (JSON_UNLIKELY(pos.m_object != this))
10996             {
10997                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
10998             }
10999 
11000             // insert to array and return iterator
11001             iterator result(this);
11002             result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
11003             return result;
11004         }
11005 
11006         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11007     }
11008 
11009     /*!
11010     @brief inserts element
11011     @copydoc insert(const_iterator, const basic_json&)
11012     */
insert(const_iterator pos,basic_json && val)11013     iterator insert(const_iterator pos, basic_json&& val)
11014     {
11015         return insert(pos, val);
11016     }
11017 
11018     /*!
11019     @brief inserts elements
11020     Inserts @a cnt copies of @a val before iterator @a pos.
11021     @param[in] pos iterator before which the content will be inserted; may be
11022     the end() iterator
11023     @param[in] cnt number of copies of @a val to insert
11024     @param[in] val element to insert
11025     @return iterator pointing to the first element inserted, or @a pos if
11026     `cnt==0`
11027     @throw type_error.309 if called on JSON values other than arrays; example:
11028     `"cannot use insert() with string"`
11029     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11030     example: `"iterator does not fit current value"`
11031     @complexity Linear in @a cnt plus linear in the distance between @a pos
11032     and end of the container.
11033     @liveexample{The example shows how `insert()` is used.,insert__count}
11034     @since version 1.0.0
11035     */
insert(const_iterator pos,size_type cnt,const basic_json & val)11036     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
11037     {
11038         // insert only works for arrays
11039         if (JSON_LIKELY(is_array()))
11040         {
11041             // check if iterator pos fits to this JSON value
11042             if (JSON_UNLIKELY(pos.m_object != this))
11043             {
11044                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11045             }
11046 
11047             // insert to array and return iterator
11048             iterator result(this);
11049             result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
11050             return result;
11051         }
11052 
11053         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11054     }
11055 
11056     /*!
11057     @brief inserts elements
11058     Inserts elements from range `[first, last)` before iterator @a pos.
11059     @param[in] pos iterator before which the content will be inserted; may be
11060     the end() iterator
11061     @param[in] first begin of the range of elements to insert
11062     @param[in] last end of the range of elements to insert
11063     @throw type_error.309 if called on JSON values other than arrays; example:
11064     `"cannot use insert() with string"`
11065     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11066     example: `"iterator does not fit current value"`
11067     @throw invalid_iterator.210 if @a first and @a last do not belong to the
11068     same JSON value; example: `"iterators do not fit"`
11069     @throw invalid_iterator.211 if @a first or @a last are iterators into
11070     container for which insert is called; example: `"passed iterators may not
11071     belong to container"`
11072     @return iterator pointing to the first element inserted, or @a pos if
11073     `first==last`
11074     @complexity Linear in `std::distance(first, last)` plus linear in the
11075     distance between @a pos and end of the container.
11076     @liveexample{The example shows how `insert()` is used.,insert__range}
11077     @since version 1.0.0
11078     */
insert(const_iterator pos,const_iterator first,const_iterator last)11079     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
11080     {
11081         // insert only works for arrays
11082         if (JSON_UNLIKELY(not is_array()))
11083         {
11084             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11085         }
11086 
11087         // check if iterator pos fits to this JSON value
11088         if (JSON_UNLIKELY(pos.m_object != this))
11089         {
11090             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11091         }
11092 
11093         // check if range iterators belong to the same JSON object
11094         if (JSON_UNLIKELY(first.m_object != last.m_object))
11095         {
11096             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
11097         }
11098 
11099         if (JSON_UNLIKELY(first.m_object == this))
11100         {
11101             JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
11102         }
11103 
11104         // insert to array and return iterator
11105         iterator result(this);
11106         result.m_it.array_iterator = m_value.array->insert(
11107                                          pos.m_it.array_iterator,
11108                                          first.m_it.array_iterator,
11109                                          last.m_it.array_iterator);
11110         return result;
11111     }
11112 
11113     /*!
11114     @brief inserts elements
11115     Inserts elements from initializer list @a ilist before iterator @a pos.
11116     @param[in] pos iterator before which the content will be inserted; may be
11117     the end() iterator
11118     @param[in] ilist initializer list to insert the values from
11119     @throw type_error.309 if called on JSON values other than arrays; example:
11120     `"cannot use insert() with string"`
11121     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11122     example: `"iterator does not fit current value"`
11123     @return iterator pointing to the first element inserted, or @a pos if
11124     `ilist` is empty
11125     @complexity Linear in `ilist.size()` plus linear in the distance between
11126     @a pos and end of the container.
11127     @liveexample{The example shows how `insert()` is used.,insert__ilist}
11128     @since version 1.0.0
11129     */
insert(const_iterator pos,initializer_list_t ilist)11130     iterator insert(const_iterator pos, initializer_list_t ilist)
11131     {
11132         // insert only works for arrays
11133         if (JSON_UNLIKELY(not is_array()))
11134         {
11135             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11136         }
11137 
11138         // check if iterator pos fits to this JSON value
11139         if (JSON_UNLIKELY(pos.m_object != this))
11140         {
11141             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11142         }
11143 
11144         // insert to array and return iterator
11145         iterator result(this);
11146         result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
11147         return result;
11148     }
11149 
11150     /*!
11151     @brief inserts elements
11152     Inserts elements from range `[first, last)`.
11153     @param[in] first begin of the range of elements to insert
11154     @param[in] last end of the range of elements to insert
11155     @throw type_error.309 if called on JSON values other than objects; example:
11156     `"cannot use insert() with string"`
11157     @throw invalid_iterator.202 if iterator @a first or @a last does does not
11158     point to an object; example: `"iterators first and last must point to
11159     objects"`
11160     @throw invalid_iterator.210 if @a first and @a last do not belong to the
11161     same JSON value; example: `"iterators do not fit"`
11162     @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
11163     of elements to insert.
11164     @liveexample{The example shows how `insert()` is used.,insert__range_object}
11165     @since version 3.0.0
11166     */
insert(const_iterator first,const_iterator last)11167     void insert(const_iterator first, const_iterator last)
11168     {
11169         // insert only works for objects
11170         if (JSON_UNLIKELY(not is_object()))
11171         {
11172             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11173         }
11174 
11175         // check if range iterators belong to the same JSON object
11176         if (JSON_UNLIKELY(first.m_object != last.m_object))
11177         {
11178             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
11179         }
11180 
11181         // passed iterators must belong to objects
11182         if (JSON_UNLIKELY(not first.m_object->is_object()))
11183         {
11184             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
11185         }
11186 
11187         m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
11188     }
11189 
11190     /*!
11191     @brief updates a JSON object from another object, overwriting existing keys
11192     Inserts all values from JSON object @a j and overwrites existing keys.
11193     @param[in] j  JSON object to read values from
11194     @throw type_error.312 if called on JSON values other than objects; example:
11195     `"cannot use update() with string"`
11196     @complexity O(N*log(size() + N)), where N is the number of elements to
11197                 insert.
11198     @liveexample{The example shows how `update()` is used.,update}
11199     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
11200     @since version 3.0.0
11201     */
update(const_reference j)11202     void update(const_reference j)
11203     {
11204         // implicitly convert null value to an empty object
11205         if (is_null())
11206         {
11207             m_type = value_t::object;
11208             m_value.object = create<object_t>();
11209             assert_invariant();
11210         }
11211 
11212         if (JSON_UNLIKELY(not is_object()))
11213         {
11214             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
11215         }
11216         if (JSON_UNLIKELY(not j.is_object()))
11217         {
11218             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
11219         }
11220 
11221         for (auto it = j.begin(); it != j.end(); ++it)
11222         {
11223             m_value.object->operator[](it.key()) = it.value();
11224         }
11225     }
11226 
11227     /*!
11228     @brief updates a JSON object from another object, overwriting existing keys
11229     Inserts all values from from range `[first, last)` and overwrites existing
11230     keys.
11231     @param[in] first begin of the range of elements to insert
11232     @param[in] last end of the range of elements to insert
11233     @throw type_error.312 if called on JSON values other than objects; example:
11234     `"cannot use update() with string"`
11235     @throw invalid_iterator.202 if iterator @a first or @a last does does not
11236     point to an object; example: `"iterators first and last must point to
11237     objects"`
11238     @throw invalid_iterator.210 if @a first and @a last do not belong to the
11239     same JSON value; example: `"iterators do not fit"`
11240     @complexity O(N*log(size() + N)), where N is the number of elements to
11241                 insert.
11242     @liveexample{The example shows how `update()` is used__range.,update}
11243     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
11244     @since version 3.0.0
11245     */
update(const_iterator first,const_iterator last)11246     void update(const_iterator first, const_iterator last)
11247     {
11248         // implicitly convert null value to an empty object
11249         if (is_null())
11250         {
11251             m_type = value_t::object;
11252             m_value.object = create<object_t>();
11253             assert_invariant();
11254         }
11255 
11256         if (JSON_UNLIKELY(not is_object()))
11257         {
11258             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
11259         }
11260 
11261         // check if range iterators belong to the same JSON object
11262         if (JSON_UNLIKELY(first.m_object != last.m_object))
11263         {
11264             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
11265         }
11266 
11267         // passed iterators must belong to objects
11268         if (JSON_UNLIKELY(not first.m_object->is_object()
11269                           or not first.m_object->is_object()))
11270         {
11271             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
11272         }
11273 
11274         for (auto it = first; it != last; ++it)
11275         {
11276             m_value.object->operator[](it.key()) = it.value();
11277         }
11278     }
11279 
11280     /*!
11281     @brief exchanges the values
11282     Exchanges the contents of the JSON value with those of @a other. Does not
11283     invoke any move, copy, or swap operations on individual elements. All
11284     iterators and references remain valid. The past-the-end iterator is
11285     invalidated.
11286     @param[in,out] other JSON value to exchange the contents with
11287     @complexity Constant.
11288     @liveexample{The example below shows how JSON values can be swapped with
11289     `swap()`.,swap__reference}
11290     @since version 1.0.0
11291     */
swap(reference other)11292     void swap(reference other) noexcept (
11293         std::is_nothrow_move_constructible<value_t>::value and
11294         std::is_nothrow_move_assignable<value_t>::value and
11295         std::is_nothrow_move_constructible<json_value>::value and
11296         std::is_nothrow_move_assignable<json_value>::value
11297     )
11298     {
11299         std::swap(m_type, other.m_type);
11300         std::swap(m_value, other.m_value);
11301         assert_invariant();
11302     }
11303 
11304     /*!
11305     @brief exchanges the values
11306     Exchanges the contents of a JSON array with those of @a other. Does not
11307     invoke any move, copy, or swap operations on individual elements. All
11308     iterators and references remain valid. The past-the-end iterator is
11309     invalidated.
11310     @param[in,out] other array to exchange the contents with
11311     @throw type_error.310 when JSON value is not an array; example: `"cannot
11312     use swap() with string"`
11313     @complexity Constant.
11314     @liveexample{The example below shows how arrays can be swapped with
11315     `swap()`.,swap__array_t}
11316     @since version 1.0.0
11317     */
swap(array_t & other)11318     void swap(array_t& other)
11319     {
11320         // swap only works for arrays
11321         if (JSON_LIKELY(is_array()))
11322         {
11323             std::swap(*(m_value.array), other);
11324         }
11325         else
11326         {
11327             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
11328         }
11329     }
11330 
11331     /*!
11332     @brief exchanges the values
11333     Exchanges the contents of a JSON object with those of @a other. Does not
11334     invoke any move, copy, or swap operations on individual elements. All
11335     iterators and references remain valid. The past-the-end iterator is
11336     invalidated.
11337     @param[in,out] other object to exchange the contents with
11338     @throw type_error.310 when JSON value is not an object; example:
11339     `"cannot use swap() with string"`
11340     @complexity Constant.
11341     @liveexample{The example below shows how objects can be swapped with
11342     `swap()`.,swap__object_t}
11343     @since version 1.0.0
11344     */
swap(object_t & other)11345     void swap(object_t& other)
11346     {
11347         // swap only works for objects
11348         if (JSON_LIKELY(is_object()))
11349         {
11350             std::swap(*(m_value.object), other);
11351         }
11352         else
11353         {
11354             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
11355         }
11356     }
11357 
11358     /*!
11359     @brief exchanges the values
11360     Exchanges the contents of a JSON string with those of @a other. Does not
11361     invoke any move, copy, or swap operations on individual elements. All
11362     iterators and references remain valid. The past-the-end iterator is
11363     invalidated.
11364     @param[in,out] other string to exchange the contents with
11365     @throw type_error.310 when JSON value is not a string; example: `"cannot
11366     use swap() with boolean"`
11367     @complexity Constant.
11368     @liveexample{The example below shows how strings can be swapped with
11369     `swap()`.,swap__string_t}
11370     @since version 1.0.0
11371     */
swap(string_t & other)11372     void swap(string_t& other)
11373     {
11374         // swap only works for strings
11375         if (JSON_LIKELY(is_string()))
11376         {
11377             std::swap(*(m_value.string), other);
11378         }
11379         else
11380         {
11381             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
11382         }
11383     }
11384 
11385     /// @}
11386 
11387   public:
11388     //////////////////////////////////////////
11389     // lexicographical comparison operators //
11390     //////////////////////////////////////////
11391 
11392     /// @name lexicographical comparison operators
11393     /// @{
11394 
11395     /*!
11396     @brief comparison: equal
11397     Compares two JSON values for equality according to the following rules:
11398     - Two JSON values are equal if (1) they are from the same type and (2)
11399       their stored values are the same according to their respective
11400       `operator==`.
11401     - Integer and floating-point numbers are automatically converted before
11402       comparison. Note than two NaN values are always treated as unequal.
11403     - Two JSON null values are equal.
11404     @note Floating-point inside JSON values numbers are compared with
11405     `json::number_float_t::operator==` which is `double::operator==` by
11406     default. To compare floating-point while respecting an epsilon, an alternative
11407     [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
11408     could be used, for instance
11409     @code {.cpp}
11410     template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
11411     inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
11412     {
11413         return std::abs(a - b) <= epsilon;
11414     }
11415     @endcode
11416     @note NaN values never compare equal to themselves or to other NaN values.
11417     @param[in] lhs  first JSON value to consider
11418     @param[in] rhs  second JSON value to consider
11419     @return whether the values @a lhs and @a rhs are equal
11420     @exceptionsafety No-throw guarantee: this function never throws exceptions.
11421     @complexity Linear.
11422     @liveexample{The example demonstrates comparing several JSON
11423     types.,operator__equal}
11424     @since version 1.0.0
11425     */
operator ==(const_reference lhs,const_reference rhs)11426     friend bool operator==(const_reference lhs, const_reference rhs) noexcept
11427     {
11428         const auto lhs_type = lhs.type();
11429         const auto rhs_type = rhs.type();
11430 
11431         if (lhs_type == rhs_type)
11432         {
11433             switch (lhs_type)
11434             {
11435                 case value_t::array:
11436                     return (*lhs.m_value.array == *rhs.m_value.array);
11437 
11438                 case value_t::object:
11439                     return (*lhs.m_value.object == *rhs.m_value.object);
11440 
11441                 case value_t::null:
11442                     return true;
11443 
11444                 case value_t::string:
11445                     return (*lhs.m_value.string == *rhs.m_value.string);
11446 
11447                 case value_t::boolean:
11448                     return (lhs.m_value.boolean == rhs.m_value.boolean);
11449 
11450                 case value_t::number_integer:
11451                     return (lhs.m_value.number_integer == rhs.m_value.number_integer);
11452 
11453                 case value_t::number_unsigned:
11454                     return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
11455 
11456                 case value_t::number_float:
11457                     return (lhs.m_value.number_float == rhs.m_value.number_float);
11458 
11459                 default:
11460                     return false;
11461             }
11462         }
11463         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
11464         {
11465             return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
11466         }
11467         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
11468         {
11469             return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
11470         }
11471         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
11472         {
11473             return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
11474         }
11475         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
11476         {
11477             return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
11478         }
11479         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
11480         {
11481             return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
11482         }
11483         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
11484         {
11485             return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
11486         }
11487 
11488         return false;
11489     }
11490 
11491     /*!
11492     @brief comparison: equal
11493     @copydoc operator==(const_reference, const_reference)
11494     */
11495     template<typename ScalarType, typename std::enable_if<
11496                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)11497     friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
11498     {
11499         return (lhs == basic_json(rhs));
11500     }
11501 
11502     /*!
11503     @brief comparison: equal
11504     @copydoc operator==(const_reference, const_reference)
11505     */
11506     template<typename ScalarType, typename std::enable_if<
11507                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)11508     friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
11509     {
11510         return (basic_json(lhs) == rhs);
11511     }
11512 
11513     /*!
11514     @brief comparison: not equal
11515     Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
11516     @param[in] lhs  first JSON value to consider
11517     @param[in] rhs  second JSON value to consider
11518     @return whether the values @a lhs and @a rhs are not equal
11519     @complexity Linear.
11520     @exceptionsafety No-throw guarantee: this function never throws exceptions.
11521     @liveexample{The example demonstrates comparing several JSON
11522     types.,operator__notequal}
11523     @since version 1.0.0
11524     */
operator !=(const_reference lhs,const_reference rhs)11525     friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
11526     {
11527         return not (lhs == rhs);
11528     }
11529 
11530     /*!
11531     @brief comparison: not equal
11532     @copydoc operator!=(const_reference, const_reference)
11533     */
11534     template<typename ScalarType, typename std::enable_if<
11535                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)11536     friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
11537     {
11538         return (lhs != basic_json(rhs));
11539     }
11540 
11541     /*!
11542     @brief comparison: not equal
11543     @copydoc operator!=(const_reference, const_reference)
11544     */
11545     template<typename ScalarType, typename std::enable_if<
11546                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)11547     friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
11548     {
11549         return (basic_json(lhs) != rhs);
11550     }
11551 
11552     /*!
11553     @brief comparison: less than
11554     Compares whether one JSON value @a lhs is less than another JSON value @a
11555     rhs according to the following rules:
11556     - If @a lhs and @a rhs have the same type, the values are compared using
11557       the default `<` operator.
11558     - Integer and floating-point numbers are automatically converted before
11559       comparison
11560     - In case @a lhs and @a rhs have different types, the values are ignored
11561       and the order of the types is considered, see
11562       @ref operator<(const value_t, const value_t).
11563     @param[in] lhs  first JSON value to consider
11564     @param[in] rhs  second JSON value to consider
11565     @return whether @a lhs is less than @a rhs
11566     @complexity Linear.
11567     @exceptionsafety No-throw guarantee: this function never throws exceptions.
11568     @liveexample{The example demonstrates comparing several JSON
11569     types.,operator__less}
11570     @since version 1.0.0
11571     */
operator <(const_reference lhs,const_reference rhs)11572     friend bool operator<(const_reference lhs, const_reference rhs) noexcept
11573     {
11574         const auto lhs_type = lhs.type();
11575         const auto rhs_type = rhs.type();
11576 
11577         if (lhs_type == rhs_type)
11578         {
11579             switch (lhs_type)
11580             {
11581                 case value_t::array:
11582                     return (*lhs.m_value.array) < (*rhs.m_value.array);
11583 
11584                 case value_t::object:
11585                     return *lhs.m_value.object < *rhs.m_value.object;
11586 
11587                 case value_t::null:
11588                     return false;
11589 
11590                 case value_t::string:
11591                     return *lhs.m_value.string < *rhs.m_value.string;
11592 
11593                 case value_t::boolean:
11594                     return lhs.m_value.boolean < rhs.m_value.boolean;
11595 
11596                 case value_t::number_integer:
11597                     return lhs.m_value.number_integer < rhs.m_value.number_integer;
11598 
11599                 case value_t::number_unsigned:
11600                     return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
11601 
11602                 case value_t::number_float:
11603                     return lhs.m_value.number_float < rhs.m_value.number_float;
11604 
11605                 default:
11606                     return false;
11607             }
11608         }
11609         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
11610         {
11611             return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
11612         }
11613         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
11614         {
11615             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
11616         }
11617         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
11618         {
11619             return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
11620         }
11621         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
11622         {
11623             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
11624         }
11625         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
11626         {
11627             return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
11628         }
11629         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
11630         {
11631             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
11632         }
11633 
11634         // We only reach this line if we cannot compare values. In that case,
11635         // we compare types. Note we have to call the operator explicitly,
11636         // because MSVC has problems otherwise.
11637         return operator<(lhs_type, rhs_type);
11638     }
11639 
11640     /*!
11641     @brief comparison: less than
11642     @copydoc operator<(const_reference, const_reference)
11643     */
11644     template<typename ScalarType, typename std::enable_if<
11645                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)11646     friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
11647     {
11648         return (lhs < basic_json(rhs));
11649     }
11650 
11651     /*!
11652     @brief comparison: less than
11653     @copydoc operator<(const_reference, const_reference)
11654     */
11655     template<typename ScalarType, typename std::enable_if<
11656                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)11657     friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
11658     {
11659         return (basic_json(lhs) < rhs);
11660     }
11661 
11662     /*!
11663     @brief comparison: less than or equal
11664     Compares whether one JSON value @a lhs is less than or equal to another
11665     JSON value by calculating `not (rhs < lhs)`.
11666     @param[in] lhs  first JSON value to consider
11667     @param[in] rhs  second JSON value to consider
11668     @return whether @a lhs is less than or equal to @a rhs
11669     @complexity Linear.
11670     @exceptionsafety No-throw guarantee: this function never throws exceptions.
11671     @liveexample{The example demonstrates comparing several JSON
11672     types.,operator__greater}
11673     @since version 1.0.0
11674     */
operator <=(const_reference lhs,const_reference rhs)11675     friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
11676     {
11677         return not (rhs < lhs);
11678     }
11679 
11680     /*!
11681     @brief comparison: less than or equal
11682     @copydoc operator<=(const_reference, const_reference)
11683     */
11684     template<typename ScalarType, typename std::enable_if<
11685                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)11686     friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
11687     {
11688         return (lhs <= basic_json(rhs));
11689     }
11690 
11691     /*!
11692     @brief comparison: less than or equal
11693     @copydoc operator<=(const_reference, const_reference)
11694     */
11695     template<typename ScalarType, typename std::enable_if<
11696                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)11697     friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
11698     {
11699         return (basic_json(lhs) <= rhs);
11700     }
11701 
11702     /*!
11703     @brief comparison: greater than
11704     Compares whether one JSON value @a lhs is greater than another
11705     JSON value by calculating `not (lhs <= rhs)`.
11706     @param[in] lhs  first JSON value to consider
11707     @param[in] rhs  second JSON value to consider
11708     @return whether @a lhs is greater than to @a rhs
11709     @complexity Linear.
11710     @exceptionsafety No-throw guarantee: this function never throws exceptions.
11711     @liveexample{The example demonstrates comparing several JSON
11712     types.,operator__lessequal}
11713     @since version 1.0.0
11714     */
operator >(const_reference lhs,const_reference rhs)11715     friend bool operator>(const_reference lhs, const_reference rhs) noexcept
11716     {
11717         return not (lhs <= rhs);
11718     }
11719 
11720     /*!
11721     @brief comparison: greater than
11722     @copydoc operator>(const_reference, const_reference)
11723     */
11724     template<typename ScalarType, typename std::enable_if<
11725                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)11726     friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
11727     {
11728         return (lhs > basic_json(rhs));
11729     }
11730 
11731     /*!
11732     @brief comparison: greater than
11733     @copydoc operator>(const_reference, const_reference)
11734     */
11735     template<typename ScalarType, typename std::enable_if<
11736                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)11737     friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
11738     {
11739         return (basic_json(lhs) > rhs);
11740     }
11741 
11742     /*!
11743     @brief comparison: greater than or equal
11744     Compares whether one JSON value @a lhs is greater than or equal to another
11745     JSON value by calculating `not (lhs < rhs)`.
11746     @param[in] lhs  first JSON value to consider
11747     @param[in] rhs  second JSON value to consider
11748     @return whether @a lhs is greater than or equal to @a rhs
11749     @complexity Linear.
11750     @exceptionsafety No-throw guarantee: this function never throws exceptions.
11751     @liveexample{The example demonstrates comparing several JSON
11752     types.,operator__greaterequal}
11753     @since version 1.0.0
11754     */
operator >=(const_reference lhs,const_reference rhs)11755     friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
11756     {
11757         return not (lhs < rhs);
11758     }
11759 
11760     /*!
11761     @brief comparison: greater than or equal
11762     @copydoc operator>=(const_reference, const_reference)
11763     */
11764     template<typename ScalarType, typename std::enable_if<
11765                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)11766     friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
11767     {
11768         return (lhs >= basic_json(rhs));
11769     }
11770 
11771     /*!
11772     @brief comparison: greater than or equal
11773     @copydoc operator>=(const_reference, const_reference)
11774     */
11775     template<typename ScalarType, typename std::enable_if<
11776                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)11777     friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
11778     {
11779         return (basic_json(lhs) >= rhs);
11780     }
11781 
11782     /// @}
11783 
11784     ///////////////////
11785     // serialization //
11786     ///////////////////
11787 
11788     /// @name serialization
11789     /// @{
11790 
11791     /*!
11792     @brief serialize to stream
11793     Serialize the given JSON value @a j to the output stream @a o. The JSON
11794     value will be serialized using the @ref dump member function.
11795     - The indentation of the output can be controlled with the member variable
11796       `width` of the output stream @a o. For instance, using the manipulator
11797       `std::setw(4)` on @a o sets the indentation level to `4` and the
11798       serialization result is the same as calling `dump(4)`.
11799     - The indentation characrer can be controlled with the member variable
11800       `fill` of the output stream @a o. For instance, the manipulator
11801       `std::setfill('\\t')` sets indentation to use a tab character rather than
11802       the default space character.
11803     @param[in,out] o  stream to serialize to
11804     @param[in] j  JSON value to serialize
11805     @return the stream @a o
11806     @complexity Linear.
11807     @liveexample{The example below shows the serialization with different
11808     parameters to `width` to adjust the indentation level.,operator_serialize}
11809     @since version 1.0.0; indentaction character added in version 3.0.0
11810     */
operator <<(std::ostream & o,const basic_json & j)11811     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
11812     {
11813         // read width member and use it as indentation parameter if nonzero
11814         const bool pretty_print = (o.width() > 0);
11815         const auto indentation = (pretty_print ? o.width() : 0);
11816 
11817         // reset width to 0 for subsequent calls to this stream
11818         o.width(0);
11819 
11820         // do the actual serialization
11821         serializer s(detail::output_adapter<char>(o), o.fill());
11822         s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
11823         return o;
11824     }
11825 
11826     /*!
11827     @brief serialize to stream
11828     @deprecated This stream operator is deprecated and will be removed in a
11829                 future version of the library. Please use
11830                 @ref operator<<(std::ostream&, const basic_json&)
11831                 instead; that is, replace calls like `j >> o;` with `o << j;`.
11832     @since version 1.0.0; deprecated since version 3.0.0
11833     */
11834     JSON_DEPRECATED
operator >>(const basic_json & j,std::ostream & o)11835     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
11836     {
11837         return o << j;
11838     }
11839 
11840     /// @}
11841 
11842 
11843     /////////////////////
11844     // deserialization //
11845     /////////////////////
11846 
11847     /// @name deserialization
11848     /// @{
11849 
11850     /*!
11851     @brief deserialize from a compatible input
11852     This function reads from a compatible input. Examples are:
11853     - an array of 1-byte values
11854     - strings with character/literal type with size of 1 byte
11855     - input streams
11856     - container with contiguous storage of 1-byte values. Compatible container
11857       types include `std::vector`, `std::string`, `std::array`,
11858       `std::valarray`, and `std::initializer_list`. Furthermore, C-style
11859       arrays can be used with `std::begin()`/`std::end()`. User-defined
11860       containers can be used as long as they implement random-access iterators
11861       and a contiguous storage.
11862     @pre Each element of the container has a size of 1 byte. Violating this
11863     precondition yields undefined behavior. **This precondition is enforced
11864     with a static assertion.**
11865     @pre The container storage is contiguous. Violating this precondition
11866     yields undefined behavior. **This precondition is enforced with an
11867     assertion.**
11868     @pre Each element of the container has a size of 1 byte. Violating this
11869     precondition yields undefined behavior. **This precondition is enforced
11870     with a static assertion.**
11871     @warning There is no way to enforce all preconditions at compile-time. If
11872              the function is called with a noncompliant container and with
11873              assertions switched off, the behavior is undefined and will most
11874              likely yield segmentation violation.
11875     @param[in] i  input to read from
11876     @param[in] cb  a parser callback function of type @ref parser_callback_t
11877     which is used to control the deserialization by filtering unwanted values
11878     (optional)
11879     @return result of the deserialization
11880     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
11881     of input; expected string literal""`
11882     @throw parse_error.102 if to_unicode fails or surrogate error
11883     @throw parse_error.103 if to_unicode fails
11884     @complexity Linear in the length of the input. The parser is a predictive
11885     LL(1) parser. The complexity can be higher if the parser callback function
11886     @a cb has a super-linear complexity.
11887     @note A UTF-8 byte order mark is silently ignored.
11888     @liveexample{The example below demonstrates the `parse()` function reading
11889     from an array.,parse__array__parser_callback_t}
11890     @liveexample{The example below demonstrates the `parse()` function with
11891     and without callback function.,parse__string__parser_callback_t}
11892     @liveexample{The example below demonstrates the `parse()` function with
11893     and without callback function.,parse__istream__parser_callback_t}
11894     @liveexample{The example below demonstrates the `parse()` function reading
11895     from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
11896     @since version 2.0.3 (contiguous containers)
11897     */
parse(detail::input_adapter i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)11898     static basic_json parse(detail::input_adapter i,
11899                             const parser_callback_t cb = nullptr,
11900                             const bool allow_exceptions = true)
11901     {
11902         basic_json result;
11903         parser(i, cb, allow_exceptions).parse(true, result);
11904         return result;
11905     }
11906 
11907     /*!
11908     @copydoc basic_json parse(detail::input_adapter, const parser_callback_t)
11909     */
parse(detail::input_adapter & i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)11910     static basic_json parse(detail::input_adapter& i,
11911                             const parser_callback_t cb = nullptr,
11912                             const bool allow_exceptions = true)
11913     {
11914         basic_json result;
11915         parser(i, cb, allow_exceptions).parse(true, result);
11916         return result;
11917     }
11918 
accept(detail::input_adapter i)11919     static bool accept(detail::input_adapter i)
11920     {
11921         return parser(i).accept(true);
11922     }
11923 
accept(detail::input_adapter & i)11924     static bool accept(detail::input_adapter& i)
11925     {
11926         return parser(i).accept(true);
11927     }
11928 
11929     /*!
11930     @brief deserialize from an iterator range with contiguous storage
11931     This function reads from an iterator range of a container with contiguous
11932     storage of 1-byte values. Compatible container types include
11933     `std::vector`, `std::string`, `std::array`, `std::valarray`, and
11934     `std::initializer_list`. Furthermore, C-style arrays can be used with
11935     `std::begin()`/`std::end()`. User-defined containers can be used as long
11936     as they implement random-access iterators and a contiguous storage.
11937     @pre The iterator range is contiguous. Violating this precondition yields
11938     undefined behavior. **This precondition is enforced with an assertion.**
11939     @pre Each element in the range has a size of 1 byte. Violating this
11940     precondition yields undefined behavior. **This precondition is enforced
11941     with a static assertion.**
11942     @warning There is no way to enforce all preconditions at compile-time. If
11943              the function is called with noncompliant iterators and with
11944              assertions switched off, the behavior is undefined and will most
11945              likely yield segmentation violation.
11946     @tparam IteratorType iterator of container with contiguous storage
11947     @param[in] first  begin of the range to parse (included)
11948     @param[in] last  end of the range to parse (excluded)
11949     @param[in] cb  a parser callback function of type @ref parser_callback_t
11950     which is used to control the deserialization by filtering unwanted values
11951     (optional)
11952     @param[in] allow_exceptions  whether to throw exceptions in case of a
11953     parse error (optional, true by default)
11954     @return result of the deserialization
11955     @throw parse_error.101 in case of an unexpected token
11956     @throw parse_error.102 if to_unicode fails or surrogate error
11957     @throw parse_error.103 if to_unicode fails
11958     @complexity Linear in the length of the input. The parser is a predictive
11959     LL(1) parser. The complexity can be higher if the parser callback function
11960     @a cb has a super-linear complexity.
11961     @note A UTF-8 byte order mark is silently ignored.
11962     @liveexample{The example below demonstrates the `parse()` function reading
11963     from an iterator range.,parse__iteratortype__parser_callback_t}
11964     @since version 2.0.3
11965     */
11966     template<class IteratorType, typename std::enable_if<
11967                  std::is_base_of<
11968                      std::random_access_iterator_tag,
11969                      typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
parse(IteratorType first,IteratorType last,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)11970     static basic_json parse(IteratorType first, IteratorType last,
11971                             const parser_callback_t cb = nullptr,
11972                             const bool allow_exceptions = true)
11973     {
11974         basic_json result;
11975         parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
11976         return result;
11977     }
11978 
11979     template<class IteratorType, typename std::enable_if<
11980                  std::is_base_of<
11981                      std::random_access_iterator_tag,
11982                      typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
accept(IteratorType first,IteratorType last)11983     static bool accept(IteratorType first, IteratorType last)
11984     {
11985         return parser(detail::input_adapter(first, last)).accept(true);
11986     }
11987 
11988     /*!
11989     @brief deserialize from stream
11990     @deprecated This stream operator is deprecated and will be removed in a
11991                 future version of the library. Please use
11992                 @ref operator>>(std::istream&, basic_json&)
11993                 instead; that is, replace calls like `j << i;` with `i >> j;`.
11994     @since version 1.0.0; deprecated since version 3.0.0
11995     */
11996     JSON_DEPRECATED
operator <<(basic_json & j,std::istream & i)11997     friend std::istream& operator<<(basic_json& j, std::istream& i)
11998     {
11999         return operator>>(i, j);
12000     }
12001 
12002     /*!
12003     @brief deserialize from stream
12004     Deserializes an input stream to a JSON value.
12005     @param[in,out] i  input stream to read a serialized JSON value from
12006     @param[in,out] j  JSON value to write the deserialized input to
12007     @throw parse_error.101 in case of an unexpected token
12008     @throw parse_error.102 if to_unicode fails or surrogate error
12009     @throw parse_error.103 if to_unicode fails
12010     @complexity Linear in the length of the input. The parser is a predictive
12011     LL(1) parser.
12012     @note A UTF-8 byte order mark is silently ignored.
12013     @liveexample{The example below shows how a JSON value is constructed by
12014     reading a serialization from a stream.,operator_deserialize}
12015     @sa parse(std::istream&, const parser_callback_t) for a variant with a
12016     parser callback function to filter values while parsing
12017     @since version 1.0.0
12018     */
operator >>(std::istream & i,basic_json & j)12019     friend std::istream& operator>>(std::istream& i, basic_json& j)
12020     {
12021         parser(detail::input_adapter(i)).parse(false, j);
12022         return i;
12023     }
12024 
12025     /// @}
12026 
12027     ///////////////////////////
12028     // convenience functions //
12029     ///////////////////////////
12030 
12031     /*!
12032     @brief return the type as string
12033     Returns the type name as string to be used in error messages - usually to
12034     indicate that a function was called on a wrong JSON type.
12035     @return a string representation of a the @a m_type member:
12036             Value type  | return value
12037             ----------- | -------------
12038             null        | `"null"`
12039             boolean     | `"boolean"`
12040             string      | `"string"`
12041             number      | `"number"` (for all number types)
12042             object      | `"object"`
12043             array       | `"array"`
12044             discarded   | `"discarded"`
12045     @exceptionsafety No-throw guarantee: this function never throws exceptions.
12046     @complexity Constant.
12047     @liveexample{The following code exemplifies `type_name()` for all JSON
12048     types.,type_name}
12049     @sa @ref type() -- return the type of the JSON value
12050     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
12051     @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
12052     since 3.0.0
12053     */
type_name() const12054     const char* type_name() const noexcept
12055     {
12056         {
12057             switch (m_type)
12058             {
12059                 case value_t::null:
12060                     return "null";
12061                 case value_t::object:
12062                     return "object";
12063                 case value_t::array:
12064                     return "array";
12065                 case value_t::string:
12066                     return "string";
12067                 case value_t::boolean:
12068                     return "boolean";
12069                 case value_t::discarded:
12070                     return "discarded";
12071                 default:
12072                     return "number";
12073             }
12074         }
12075     }
12076 
12077 
12078   private:
12079     //////////////////////
12080     // member variables //
12081     //////////////////////
12082 
12083     /// the type of the current element
12084     value_t m_type = value_t::null;
12085 
12086     /// the value of the current element
12087     json_value m_value = {};
12088 
12089     //////////////////////////////////////////
12090     // binary serialization/deserialization //
12091     //////////////////////////////////////////
12092 
12093     /// @name binary serialization/deserialization support
12094     /// @{
12095 
12096   public:
12097     /*!
12098     @brief create a CBOR serialization of a given JSON value
12099     Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
12100     Binary Object Representation) serialization format. CBOR is a binary
12101     serialization format which aims to be more compact than JSON itself, yet
12102     more efficient to parse.
12103     The library uses the following mapping from JSON values types to
12104     CBOR types according to the CBOR specification (RFC 7049):
12105     JSON value type | value/range                                | CBOR type                          | first byte
12106     --------------- | ------------------------------------------ | ---------------------------------- | ---------------
12107     null            | `null`                                     | Null                               | 0xf6
12108     boolean         | `true`                                     | True                               | 0xf5
12109     boolean         | `false`                                    | False                              | 0xf4
12110     number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3b
12111     number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3a
12112     number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
12113     number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
12114     number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
12115     number_integer  | 0..23                                      | Integer                            | 0x00..0x17
12116     number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
12117     number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
12118     number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1a
12119     number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1b
12120     number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
12121     number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
12122     number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
12123     number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1a
12124     number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1b
12125     number_float    | *any value*                                | Double-Precision Float             | 0xfb
12126     string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
12127     string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
12128     string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
12129     string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7a
12130     string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7b
12131     array           | *size*: 0..23                              | array                              | 0x80..0x97
12132     array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
12133     array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
12134     array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9a
12135     array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9b
12136     object          | *size*: 0..23                              | map                                | 0xa0..0xb7
12137     object          | *size*: 23..255                            | map (1 byte follow)                | 0xb8
12138     object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xb9
12139     object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xba
12140     object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xbb
12141     @note The mapping is **complete** in the sense that any JSON value type
12142           can be converted to a CBOR value.
12143     @note If NaN or Infinity are stored inside a JSON number, they are
12144           serialized properly. This behavior differs from the @ref dump()
12145           function which serializes NaN or Infinity to `null`.
12146     @note The following CBOR types are not used in the conversion:
12147           - byte strings (0x40..0x5f)
12148           - UTF-8 strings terminated by "break" (0x7f)
12149           - arrays terminated by "break" (0x9f)
12150           - maps terminated by "break" (0xbf)
12151           - date/time (0xc0..0xc1)
12152           - bignum (0xc2..0xc3)
12153           - decimal fraction (0xc4)
12154           - bigfloat (0xc5)
12155           - tagged items (0xc6..0xd4, 0xd8..0xdb)
12156           - expected conversions (0xd5..0xd7)
12157           - simple values (0xe0..0xf3, 0xf8)
12158           - undefined (0xf7)
12159           - half and single-precision floats (0xf9-0xfa)
12160           - break (0xff)
12161     @param[in] j  JSON value to serialize
12162     @return MessagePack serialization as byte vector
12163     @complexity Linear in the size of the JSON value @a j.
12164     @liveexample{The example shows the serialization of a JSON value to a byte
12165     vector in CBOR format.,to_cbor}
12166     @sa http://cbor.io
12167     @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
12168         analogous deserialization
12169     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
12170     @since version 2.0.9
12171     */
to_cbor(const basic_json & j)12172     static std::vector<uint8_t> to_cbor(const basic_json& j)
12173     {
12174         std::vector<uint8_t> result;
12175         to_cbor(j, result);
12176         return result;
12177     }
12178 
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)12179     static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
12180     {
12181         binary_writer<uint8_t>(o).write_cbor(j);
12182     }
12183 
to_cbor(const basic_json & j,detail::output_adapter<char> o)12184     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
12185     {
12186         binary_writer<char>(o).write_cbor(j);
12187     }
12188 
12189     /*!
12190     @brief create a MessagePack serialization of a given JSON value
12191     Serializes a given JSON value @a j to a byte vector using the MessagePack
12192     serialization format. MessagePack is a binary serialization format which
12193     aims to be more compact than JSON itself, yet more efficient to parse.
12194     The library uses the following mapping from JSON values types to
12195     MessagePack types according to the MessagePack specification:
12196     JSON value type | value/range                       | MessagePack type | first byte
12197     --------------- | --------------------------------- | ---------------- | ----------
12198     null            | `null`                            | nil              | 0xc0
12199     boolean         | `true`                            | true             | 0xc3
12200     boolean         | `false`                           | false            | 0xc2
12201     number_integer  | -9223372036854775808..-2147483649 | int64            | 0xd3
12202     number_integer  | -2147483648..-32769               | int32            | 0xd2
12203     number_integer  | -32768..-129                      | int16            | 0xd1
12204     number_integer  | -128..-33                         | int8             | 0xd0
12205     number_integer  | -32..-1                           | negative fixint  | 0xe0..0xff
12206     number_integer  | 0..127                            | positive fixint  | 0x00..0x7f
12207     number_integer  | 128..255                          | uint 8           | 0xcc
12208     number_integer  | 256..65535                        | uint 16          | 0xcd
12209     number_integer  | 65536..4294967295                 | uint 32          | 0xce
12210     number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xcf
12211     number_unsigned | 0..127                            | positive fixint  | 0x00..0x7f
12212     number_unsigned | 128..255                          | uint 8           | 0xcc
12213     number_unsigned | 256..65535                        | uint 16          | 0xcd
12214     number_unsigned | 65536..4294967295                 | uint 32          | 0xce
12215     number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xcf
12216     number_float    | *any value*                       | float 64         | 0xcb
12217     string          | *length*: 0..31                   | fixstr           | 0xa0..0xbf
12218     string          | *length*: 32..255                 | str 8            | 0xd9
12219     string          | *length*: 256..65535              | str 16           | 0xda
12220     string          | *length*: 65536..4294967295       | str 32           | 0xdb
12221     array           | *size*: 0..15                     | fixarray         | 0x90..0x9f
12222     array           | *size*: 16..65535                 | array 16         | 0xdc
12223     array           | *size*: 65536..4294967295         | array 32         | 0xdd
12224     object          | *size*: 0..15                     | fix map          | 0x80..0x8f
12225     object          | *size*: 16..65535                 | map 16           | 0xde
12226     object          | *size*: 65536..4294967295         | map 32           | 0xdf
12227     @note The mapping is **complete** in the sense that any JSON value type
12228           can be converted to a MessagePack value.
12229     @note The following values can **not** be converted to a MessagePack value:
12230           - strings with more than 4294967295 bytes
12231           - arrays with more than 4294967295 elements
12232           - objects with more than 4294967295 elements
12233     @note The following MessagePack types are not used in the conversion:
12234           - bin 8 - bin 32 (0xc4..0xc6)
12235           - ext 8 - ext 32 (0xc7..0xc9)
12236           - float 32 (0xca)
12237           - fixext 1 - fixext 16 (0xd4..0xd8)
12238     @note Any MessagePack output created @ref to_msgpack can be successfully
12239           parsed by @ref from_msgpack.
12240     @note If NaN or Infinity are stored inside a JSON number, they are
12241           serialized properly. This behavior differs from the @ref dump()
12242           function which serializes NaN or Infinity to `null`.
12243     @param[in] j  JSON value to serialize
12244     @return MessagePack serialization as byte vector
12245     @complexity Linear in the size of the JSON value @a j.
12246     @liveexample{The example shows the serialization of a JSON value to a byte
12247     vector in MessagePack format.,to_msgpack}
12248     @sa http://msgpack.org
12249     @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
12250         analogous deserialization
12251     @sa @ref to_cbor(const basic_json& for the related CBOR format
12252     @since version 2.0.9
12253     */
to_msgpack(const basic_json & j)12254     static std::vector<uint8_t> to_msgpack(const basic_json& j)
12255     {
12256         std::vector<uint8_t> result;
12257         to_msgpack(j, result);
12258         return result;
12259     }
12260 
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)12261     static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
12262     {
12263         binary_writer<uint8_t>(o).write_msgpack(j);
12264     }
12265 
to_msgpack(const basic_json & j,detail::output_adapter<char> o)12266     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
12267     {
12268         binary_writer<char>(o).write_msgpack(j);
12269     }
12270 
12271     /*!
12272     @brief create a JSON value from an input in CBOR format
12273     Deserializes a given input @a i to a JSON value using the CBOR (Concise
12274     Binary Object Representation) serialization format.
12275     The library maps CBOR types to JSON value types as follows:
12276     CBOR type              | JSON value type | first byte
12277     ---------------------- | --------------- | ----------
12278     Integer                | number_unsigned | 0x00..0x17
12279     Unsigned integer       | number_unsigned | 0x18
12280     Unsigned integer       | number_unsigned | 0x19
12281     Unsigned integer       | number_unsigned | 0x1a
12282     Unsigned integer       | number_unsigned | 0x1b
12283     Negative integer       | number_integer  | 0x20..0x37
12284     Negative integer       | number_integer  | 0x38
12285     Negative integer       | number_integer  | 0x39
12286     Negative integer       | number_integer  | 0x3a
12287     Negative integer       | number_integer  | 0x3b
12288     Negative integer       | number_integer  | 0x40..0x57
12289     UTF-8 string           | string          | 0x60..0x77
12290     UTF-8 string           | string          | 0x78
12291     UTF-8 string           | string          | 0x79
12292     UTF-8 string           | string          | 0x7a
12293     UTF-8 string           | string          | 0x7b
12294     UTF-8 string           | string          | 0x7f
12295     array                  | array           | 0x80..0x97
12296     array                  | array           | 0x98
12297     array                  | array           | 0x99
12298     array                  | array           | 0x9a
12299     array                  | array           | 0x9b
12300     array                  | array           | 0x9f
12301     map                    | object          | 0xa0..0xb7
12302     map                    | object          | 0xb8
12303     map                    | object          | 0xb9
12304     map                    | object          | 0xba
12305     map                    | object          | 0xbb
12306     map                    | object          | 0xbf
12307     False                  | `false`         | 0xf4
12308     True                   | `true`          | 0xf5
12309     Nill                   | `null`          | 0xf6
12310     Half-Precision Float   | number_float    | 0xf9
12311     Single-Precision Float | number_float    | 0xfa
12312     Double-Precision Float | number_float    | 0xfb
12313     @warning The mapping is **incomplete** in the sense that not all CBOR
12314              types can be converted to a JSON value. The following CBOR types
12315              are not supported and will yield parse errors (parse_error.112):
12316              - byte strings (0x40..0x5f)
12317              - date/time (0xc0..0xc1)
12318              - bignum (0xc2..0xc3)
12319              - decimal fraction (0xc4)
12320              - bigfloat (0xc5)
12321              - tagged items (0xc6..0xd4, 0xd8..0xdb)
12322              - expected conversions (0xd5..0xd7)
12323              - simple values (0xe0..0xf3, 0xf8)
12324              - undefined (0xf7)
12325     @warning CBOR allows map keys of any type, whereas JSON only allows
12326              strings as keys in object values. Therefore, CBOR maps with keys
12327              other than UTF-8 strings are rejected (parse_error.113).
12328     @note Any CBOR output created @ref to_cbor can be successfully parsed by
12329           @ref from_cbor.
12330     @param[in] i  an input in CBOR format convertible to an input adapter
12331     @param[in] strict  whether to expect the input to be consumed until EOF
12332                        (true by default)
12333     @return deserialized JSON value
12334     @throw parse_error.110 if the given input ends prematurely or the end of
12335     file was not reached when @a strict was set to true
12336     @throw parse_error.112 if unsupported features from CBOR were
12337     used in the given input @a v or if the input is not valid CBOR
12338     @throw parse_error.113 if a string was expected as map key, but not found
12339     @complexity Linear in the size of the input @a i.
12340     @liveexample{The example shows the deserialization of a byte vector in CBOR
12341     format to a JSON value.,from_cbor}
12342     @sa http://cbor.io
12343     @sa @ref to_cbor(const basic_json&) for the analogous serialization
12344     @sa @ref from_msgpack(detail::input_adapter, const bool) for the
12345         related MessagePack format
12346     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
12347            consume input adapters, removed start_index parameter, and added
12348            @a strict parameter since 3.0.0
12349     */
from_cbor(detail::input_adapter i,const bool strict=true)12350     static basic_json from_cbor(detail::input_adapter i,
12351                                 const bool strict = true)
12352     {
12353         return binary_reader(i).parse_cbor(strict);
12354     }
12355 
12356     /*!
12357     @copydoc from_cbor(detail::input_adapter, const bool)
12358     */
12359     template<typename A1, typename A2,
12360              detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
from_cbor(A1 && a1,A2 && a2,const bool strict=true)12361     static basic_json from_cbor(A1 && a1, A2 && a2, const bool strict = true)
12362     {
12363         return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
12364     }
12365 
12366     /*!
12367     @brief create a JSON value from an input in MessagePack format
12368     Deserializes a given input @a i to a JSON value using the MessagePack
12369     serialization format.
12370     The library maps MessagePack types to JSON value types as follows:
12371     MessagePack type | JSON value type | first byte
12372     ---------------- | --------------- | ----------
12373     positive fixint  | number_unsigned | 0x00..0x7f
12374     fixmap           | object          | 0x80..0x8f
12375     fixarray         | array           | 0x90..0x9f
12376     fixstr           | string          | 0xa0..0xbf
12377     nil              | `null`          | 0xc0
12378     false            | `false`         | 0xc2
12379     true             | `true`          | 0xc3
12380     float 32         | number_float    | 0xca
12381     float 64         | number_float    | 0xcb
12382     uint 8           | number_unsigned | 0xcc
12383     uint 16          | number_unsigned | 0xcd
12384     uint 32          | number_unsigned | 0xce
12385     uint 64          | number_unsigned | 0xcf
12386     int 8            | number_integer  | 0xd0
12387     int 16           | number_integer  | 0xd1
12388     int 32           | number_integer  | 0xd2
12389     int 64           | number_integer  | 0xd3
12390     str 8            | string          | 0xd9
12391     str 16           | string          | 0xda
12392     str 32           | string          | 0xdb
12393     array 16         | array           | 0xdc
12394     array 32         | array           | 0xdd
12395     map 16           | object          | 0xde
12396     map 32           | object          | 0xdf
12397     negative fixint  | number_integer  | 0xe0-0xff
12398     @warning The mapping is **incomplete** in the sense that not all
12399              MessagePack types can be converted to a JSON value. The following
12400              MessagePack types are not supported and will yield parse errors:
12401               - bin 8 - bin 32 (0xc4..0xc6)
12402               - ext 8 - ext 32 (0xc7..0xc9)
12403               - fixext 1 - fixext 16 (0xd4..0xd8)
12404     @note Any MessagePack output created @ref to_msgpack can be successfully
12405           parsed by @ref from_msgpack.
12406     @param[in] i  an input in MessagePack format convertible to an input
12407                   adapter
12408     @param[in] strict  whether to expect the input to be consumed until EOF
12409                        (true by default)
12410     @throw parse_error.110 if the given input ends prematurely or the end of
12411     file was not reached when @a strict was set to true
12412     @throw parse_error.112 if unsupported features from MessagePack were
12413     used in the given input @a i or if the input is not valid MessagePack
12414     @throw parse_error.113 if a string was expected as map key, but not found
12415     @complexity Linear in the size of the input @a i.
12416     @liveexample{The example shows the deserialization of a byte vector in
12417     MessagePack format to a JSON value.,from_msgpack}
12418     @sa http://msgpack.org
12419     @sa @ref to_msgpack(const basic_json&) for the analogous serialization
12420     @sa @ref from_cbor(detail::input_adapter, const bool) for the related CBOR
12421         format
12422     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
12423            consume input adapters, removed start_index parameter, and added
12424            @a strict parameter since 3.0.0
12425     */
from_msgpack(detail::input_adapter i,const bool strict=true)12426     static basic_json from_msgpack(detail::input_adapter i,
12427                                    const bool strict = true)
12428     {
12429         return binary_reader(i).parse_msgpack(strict);
12430     }
12431 
12432     /*!
12433     @copydoc from_msgpack(detail::input_adapter, const bool)
12434     */
12435     template<typename A1, typename A2,
12436              detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
from_msgpack(A1 && a1,A2 && a2,const bool strict=true)12437     static basic_json from_msgpack(A1 && a1, A2 && a2, const bool strict = true)
12438     {
12439         return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
12440     }
12441 
12442     /// @}
12443 
12444     //////////////////////////
12445     // JSON Pointer support //
12446     //////////////////////////
12447 
12448     /// @name JSON Pointer functions
12449     /// @{
12450 
12451     /*!
12452     @brief access specified element via JSON Pointer
12453     Uses a JSON pointer to retrieve a reference to the respective JSON value.
12454     No bound checking is performed. Similar to @ref operator[](const typename
12455     object_t::key_type&), `null` values are created in arrays and objects if
12456     necessary.
12457     In particular:
12458     - If the JSON pointer points to an object key that does not exist, it
12459       is created an filled with a `null` value before a reference to it
12460       is returned.
12461     - If the JSON pointer points to an array index that does not exist, it
12462       is created an filled with a `null` value before a reference to it
12463       is returned. All indices between the current maximum and the given
12464       index are also filled with `null`.
12465     - The special value `-` is treated as a synonym for the index past the
12466       end.
12467     @param[in] ptr  a JSON pointer
12468     @return reference to the element pointed to by @a ptr
12469     @complexity Constant.
12470     @throw parse_error.106   if an array index begins with '0'
12471     @throw parse_error.109   if an array index was not a number
12472     @throw out_of_range.404  if the JSON pointer can not be resolved
12473     @liveexample{The behavior is shown in the example.,operatorjson_pointer}
12474     @since version 2.0.0
12475     */
operator [](const json_pointer & ptr)12476     reference operator[](const json_pointer& ptr)
12477     {
12478         return ptr.get_unchecked(this);
12479     }
12480 
12481     /*!
12482     @brief access specified element via JSON Pointer
12483     Uses a JSON pointer to retrieve a reference to the respective JSON value.
12484     No bound checking is performed. The function does not change the JSON
12485     value; no `null` values are created. In particular, the the special value
12486     `-` yields an exception.
12487     @param[in] ptr  JSON pointer to the desired element
12488     @return const reference to the element pointed to by @a ptr
12489     @complexity Constant.
12490     @throw parse_error.106   if an array index begins with '0'
12491     @throw parse_error.109   if an array index was not a number
12492     @throw out_of_range.402  if the array index '-' is used
12493     @throw out_of_range.404  if the JSON pointer can not be resolved
12494     @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
12495     @since version 2.0.0
12496     */
operator [](const json_pointer & ptr) const12497     const_reference operator[](const json_pointer& ptr) const
12498     {
12499         return ptr.get_unchecked(this);
12500     }
12501 
12502     /*!
12503     @brief access specified element via JSON Pointer
12504     Returns a reference to the element at with specified JSON pointer @a ptr,
12505     with bounds checking.
12506     @param[in] ptr  JSON pointer to the desired element
12507     @return reference to the element pointed to by @a ptr
12508     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
12509     begins with '0'. See example below.
12510     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
12511     is not a number. See example below.
12512     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
12513     is out of range. See example below.
12514     @throw out_of_range.402 if the array index '-' is used in the passed JSON
12515     pointer @a ptr. As `at` provides checked access (and no elements are
12516     implicitly inserted), the index '-' is always invalid. See example below.
12517     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
12518     See example below.
12519     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12520     changes in the JSON value.
12521     @complexity Constant.
12522     @since version 2.0.0
12523     @liveexample{The behavior is shown in the example.,at_json_pointer}
12524     */
at(const json_pointer & ptr)12525     reference at(const json_pointer& ptr)
12526     {
12527         return ptr.get_checked(this);
12528     }
12529 
12530     /*!
12531     @brief access specified element via JSON Pointer
12532     Returns a const reference to the element at with specified JSON pointer @a
12533     ptr, with bounds checking.
12534     @param[in] ptr  JSON pointer to the desired element
12535     @return reference to the element pointed to by @a ptr
12536     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
12537     begins with '0'. See example below.
12538     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
12539     is not a number. See example below.
12540     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
12541     is out of range. See example below.
12542     @throw out_of_range.402 if the array index '-' is used in the passed JSON
12543     pointer @a ptr. As `at` provides checked access (and no elements are
12544     implicitly inserted), the index '-' is always invalid. See example below.
12545     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
12546     See example below.
12547     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12548     changes in the JSON value.
12549     @complexity Constant.
12550     @since version 2.0.0
12551     @liveexample{The behavior is shown in the example.,at_json_pointer_const}
12552     */
at(const json_pointer & ptr) const12553     const_reference at(const json_pointer& ptr) const
12554     {
12555         return ptr.get_checked(this);
12556     }
12557 
12558     /*!
12559     @brief return flattened JSON value
12560     The function creates a JSON object whose keys are JSON pointers (see [RFC
12561     6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
12562     primitive. The original JSON value can be restored using the @ref
12563     unflatten() function.
12564     @return an object that maps JSON pointers to primitive values
12565     @note Empty objects and arrays are flattened to `null` and will not be
12566           reconstructed correctly by the @ref unflatten() function.
12567     @complexity Linear in the size the JSON value.
12568     @liveexample{The following code shows how a JSON object is flattened to an
12569     object whose keys consist of JSON pointers.,flatten}
12570     @sa @ref unflatten() for the reverse function
12571     @since version 2.0.0
12572     */
flatten() const12573     basic_json flatten() const
12574     {
12575         basic_json result(value_t::object);
12576         json_pointer::flatten("", *this, result);
12577         return result;
12578     }
12579 
12580     /*!
12581     @brief unflatten a previously flattened JSON value
12582     The function restores the arbitrary nesting of a JSON value that has been
12583     flattened before using the @ref flatten() function. The JSON value must
12584     meet certain constraints:
12585     1. The value must be an object.
12586     2. The keys must be JSON pointers (see
12587        [RFC 6901](https://tools.ietf.org/html/rfc6901))
12588     3. The mapped values must be primitive JSON types.
12589     @return the original JSON from a flattened version
12590     @note Empty objects and arrays are flattened by @ref flatten() to `null`
12591           values and can not unflattened to their original type. Apart from
12592           this example, for a JSON value `j`, the following is always true:
12593           `j == j.flatten().unflatten()`.
12594     @complexity Linear in the size the JSON value.
12595     @throw type_error.314  if value is not an object
12596     @throw type_error.315  if object values are not primitive
12597     @liveexample{The following code shows how a flattened JSON object is
12598     unflattened into the original nested JSON object.,unflatten}
12599     @sa @ref flatten() for the reverse function
12600     @since version 2.0.0
12601     */
unflatten() const12602     basic_json unflatten() const
12603     {
12604         return json_pointer::unflatten(*this);
12605     }
12606 
12607     /// @}
12608 
12609     //////////////////////////
12610     // JSON Patch functions //
12611     //////////////////////////
12612 
12613     /// @name JSON Patch functions
12614     /// @{
12615 
12616     /*!
12617     @brief applies a JSON patch
12618     [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
12619     expressing a sequence of operations to apply to a JSON) document. With
12620     this function, a JSON Patch is applied to the current JSON value by
12621     executing all operations from the patch.
12622     @param[in] json_patch  JSON patch document
12623     @return patched document
12624     @note The application of a patch is atomic: Either all operations succeed
12625           and the patched document is returned or an exception is thrown. In
12626           any case, the original value is not changed: the patch is applied
12627           to a copy of the value.
12628     @throw parse_error.104 if the JSON patch does not consist of an array of
12629     objects
12630     @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
12631     attributes are missing); example: `"operation add must have member path"`
12632     @throw out_of_range.401 if an array index is out of range.
12633     @throw out_of_range.403 if a JSON pointer inside the patch could not be
12634     resolved successfully in the current JSON value; example: `"key baz not
12635     found"`
12636     @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
12637     "move")
12638     @throw other_error.501 if "test" operation was unsuccessful
12639     @complexity Linear in the size of the JSON value and the length of the
12640     JSON patch. As usually only a fraction of the JSON value is affected by
12641     the patch, the complexity can usually be neglected.
12642     @liveexample{The following code shows how a JSON patch is applied to a
12643     value.,patch}
12644     @sa @ref diff -- create a JSON patch by comparing two JSON values
12645     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
12646     @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
12647     @since version 2.0.0
12648     */
patch(const basic_json & json_patch) const12649     basic_json patch(const basic_json& json_patch) const
12650     {
12651         // make a working copy to apply the patch to
12652         basic_json result = *this;
12653 
12654         // the valid JSON Patch operations
12655         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
12656 
12657         const auto get_op = [](const std::string & op)
12658         {
12659             if (op == "add")
12660             {
12661                 return patch_operations::add;
12662             }
12663             if (op == "remove")
12664             {
12665                 return patch_operations::remove;
12666             }
12667             if (op == "replace")
12668             {
12669                 return patch_operations::replace;
12670             }
12671             if (op == "move")
12672             {
12673                 return patch_operations::move;
12674             }
12675             if (op == "copy")
12676             {
12677                 return patch_operations::copy;
12678             }
12679             if (op == "test")
12680             {
12681                 return patch_operations::test;
12682             }
12683 
12684             return patch_operations::invalid;
12685         };
12686 
12687         // wrapper for "add" operation; add value at ptr
12688         const auto operation_add = [&result](json_pointer & ptr, basic_json val)
12689         {
12690             // adding to the root of the target document means replacing it
12691             if (ptr.is_root())
12692             {
12693                 result = val;
12694             }
12695             else
12696             {
12697                 // make sure the top element of the pointer exists
12698                 json_pointer top_pointer = ptr.top();
12699                 if (top_pointer != ptr)
12700                 {
12701                     result.at(top_pointer);
12702                 }
12703 
12704                 // get reference to parent of JSON pointer ptr
12705                 const auto last_path = ptr.pop_back();
12706                 basic_json& parent = result[ptr];
12707 
12708                 switch (parent.m_type)
12709                 {
12710                     case value_t::null:
12711                     case value_t::object:
12712                     {
12713                         // use operator[] to add value
12714                         parent[last_path] = val;
12715                         break;
12716                     }
12717 
12718                     case value_t::array:
12719                     {
12720                         if (last_path == "-")
12721                         {
12722                             // special case: append to back
12723                             parent.push_back(val);
12724                         }
12725                         else
12726                         {
12727                             const auto idx = std::stoi(last_path);
12728                             if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
12729                             {
12730                                 // avoid undefined behavior
12731                                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
12732                             }
12733                             else
12734                             {
12735                                 // default case: insert add offset
12736                                 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
12737                             }
12738                         }
12739                         break;
12740                     }
12741 
12742                     default:
12743                     {
12744                         // if there exists a parent it cannot be primitive
12745                         assert(false);  // LCOV_EXCL_LINE
12746                     }
12747                 }
12748             }
12749         };
12750 
12751         // wrapper for "remove" operation; remove value at ptr
12752         const auto operation_remove = [&result](json_pointer & ptr)
12753         {
12754             // get reference to parent of JSON pointer ptr
12755             const auto last_path = ptr.pop_back();
12756             basic_json& parent = result.at(ptr);
12757 
12758             // remove child
12759             if (parent.is_object())
12760             {
12761                 // perform range check
12762                 auto it = parent.find(last_path);
12763                 if (JSON_LIKELY(it != parent.end()))
12764                 {
12765                     parent.erase(it);
12766                 }
12767                 else
12768                 {
12769                     JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
12770                 }
12771             }
12772             else if (parent.is_array())
12773             {
12774                 // note erase performs range check
12775                 parent.erase(static_cast<size_type>(std::stoi(last_path)));
12776             }
12777         };
12778 
12779         // type check: top level value must be an array
12780         if (JSON_UNLIKELY(not json_patch.is_array()))
12781         {
12782             JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
12783         }
12784 
12785         // iterate and apply the operations
12786         for (const auto& val : json_patch)
12787         {
12788             // wrapper to get a value for an operation
12789             const auto get_value = [&val](const std::string & op,
12790                                           const std::string & member,
12791                                           bool string_type) -> basic_json&
12792             {
12793                 // find value
12794                 auto it = val.m_value.object->find(member);
12795 
12796                 // context-sensitive error message
12797                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
12798 
12799                 // check if desired value is present
12800                 if (JSON_UNLIKELY(it == val.m_value.object->end()))
12801                 {
12802                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
12803                 }
12804 
12805                 // check if result is of type string
12806                 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
12807                 {
12808                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
12809                 }
12810 
12811                 // no error: return value
12812                 return it->second;
12813             };
12814 
12815             // type check: every element of the array must be an object
12816             if (JSON_UNLIKELY(not val.is_object()))
12817             {
12818                 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
12819             }
12820 
12821             // collect mandatory members
12822             const std::string op = get_value("op", "op", true);
12823             const std::string path = get_value(op, "path", true);
12824             json_pointer ptr(path);
12825 
12826             switch (get_op(op))
12827             {
12828                 case patch_operations::add:
12829                 {
12830                     operation_add(ptr, get_value("add", "value", false));
12831                     break;
12832                 }
12833 
12834                 case patch_operations::remove:
12835                 {
12836                     operation_remove(ptr);
12837                     break;
12838                 }
12839 
12840                 case patch_operations::replace:
12841                 {
12842                     // the "path" location must exist - use at()
12843                     result.at(ptr) = get_value("replace", "value", false);
12844                     break;
12845                 }
12846 
12847                 case patch_operations::move:
12848                 {
12849                     const std::string from_path = get_value("move", "from", true);
12850                     json_pointer from_ptr(from_path);
12851 
12852                     // the "from" location must exist - use at()
12853                     basic_json v = result.at(from_ptr);
12854 
12855                     // The move operation is functionally identical to a
12856                     // "remove" operation on the "from" location, followed
12857                     // immediately by an "add" operation at the target
12858                     // location with the value that was just removed.
12859                     operation_remove(from_ptr);
12860                     operation_add(ptr, v);
12861                     break;
12862                 }
12863 
12864                 case patch_operations::copy:
12865                 {
12866                     const std::string from_path = get_value("copy", "from", true);
12867                     const json_pointer from_ptr(from_path);
12868 
12869                     // the "from" location must exist - use at()
12870                     result[ptr] = result.at(from_ptr);
12871                     break;
12872                 }
12873 
12874                 case patch_operations::test:
12875                 {
12876                     bool success = false;
12877                     JSON_TRY
12878                     {
12879                         // check if "value" matches the one at "path"
12880                         // the "path" location must exist - use at()
12881                         success = (result.at(ptr) == get_value("test", "value", false));
12882                     }
12883                     JSON_CATCH (out_of_range&)
12884                     {
12885                         // ignore out of range errors: success remains false
12886                     }
12887 
12888                     // throw an exception if test fails
12889                     if (JSON_UNLIKELY(not success))
12890                     {
12891                         JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
12892                     }
12893 
12894                     break;
12895                 }
12896 
12897                 case patch_operations::invalid:
12898                 {
12899                     // op must be "add", "remove", "replace", "move", "copy", or
12900                     // "test"
12901                     JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
12902                 }
12903             }
12904         }
12905 
12906         return result;
12907     }
12908 
12909     /*!
12910     @brief creates a diff as a JSON patch
12911     Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
12912     be changed into the value @a target by calling @ref patch function.
12913     @invariant For two JSON values @a source and @a target, the following code
12914     yields always `true`:
12915     @code {.cpp}
12916     source.patch(diff(source, target)) == target;
12917     @endcode
12918     @note Currently, only `remove`, `add`, and `replace` operations are
12919           generated.
12920     @param[in] source  JSON value to compare from
12921     @param[in] target  JSON value to compare against
12922     @param[in] path    helper value to create JSON pointers
12923     @return a JSON patch to convert the @a source to @a target
12924     @complexity Linear in the lengths of @a source and @a target.
12925     @liveexample{The following code shows how a JSON patch is created as a
12926     diff for two JSON values.,diff}
12927     @sa @ref patch -- apply a JSON patch
12928     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
12929     @since version 2.0.0
12930     */
diff(const basic_json & source,const basic_json & target,const std::string & path="")12931     static basic_json diff(const basic_json& source, const basic_json& target,
12932                            const std::string& path = "")
12933     {
12934         // the patch
12935         basic_json result(value_t::array);
12936 
12937         // if the values are the same, return empty patch
12938         if (source == target)
12939         {
12940             return result;
12941         }
12942 
12943         if (source.type() != target.type())
12944         {
12945             // different types: replace value
12946             result.push_back(
12947             {
12948                 {"op", "replace"}, {"path", path}, {"value", target}
12949             });
12950         }
12951         else
12952         {
12953             switch (source.type())
12954             {
12955                 case value_t::array:
12956                 {
12957                     // first pass: traverse common elements
12958                     std::size_t i = 0;
12959                     while (i < source.size() and i < target.size())
12960                     {
12961                         // recursive call to compare array values at index i
12962                         auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
12963                         result.insert(result.end(), temp_diff.begin(), temp_diff.end());
12964                         ++i;
12965                     }
12966 
12967                     // i now reached the end of at least one array
12968                     // in a second pass, traverse the remaining elements
12969 
12970                     // remove my remaining elements
12971                     const auto end_index = static_cast<difference_type>(result.size());
12972                     while (i < source.size())
12973                     {
12974                         // add operations in reverse order to avoid invalid
12975                         // indices
12976                         result.insert(result.begin() + end_index, object(
12977                         {
12978                             {"op", "remove"},
12979                             {"path", path + "/" + std::to_string(i)}
12980                         }));
12981                         ++i;
12982                     }
12983 
12984                     // add other remaining elements
12985                     while (i < target.size())
12986                     {
12987                         result.push_back(
12988                         {
12989                             {"op", "add"},
12990                             {"path", path + "/" + std::to_string(i)},
12991                             {"value", target[i]}
12992                         });
12993                         ++i;
12994                     }
12995 
12996                     break;
12997                 }
12998 
12999                 case value_t::object:
13000                 {
13001                     // first pass: traverse this object's elements
13002                     for (auto it = source.begin(); it != source.end(); ++it)
13003                     {
13004                         // escape the key name to be used in a JSON patch
13005                         const auto key = json_pointer::escape(it.key());
13006 
13007                         if (target.find(it.key()) != target.end())
13008                         {
13009                             // recursive call to compare object values at key it
13010                             auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
13011                             result.insert(result.end(), temp_diff.begin(), temp_diff.end());
13012                         }
13013                         else
13014                         {
13015                             // found a key that is not in o -> remove it
13016                             result.push_back(object(
13017                             {
13018                                 {"op", "remove"}, {"path", path + "/" + key}
13019                             }));
13020                         }
13021                     }
13022 
13023                     // second pass: traverse other object's elements
13024                     for (auto it = target.begin(); it != target.end(); ++it)
13025                     {
13026                         if (source.find(it.key()) == source.end())
13027                         {
13028                             // found a key that is not in this -> add it
13029                             const auto key = json_pointer::escape(it.key());
13030                             result.push_back(
13031                             {
13032                                 {"op", "add"}, {"path", path + "/" + key},
13033                                 {"value", it.value()}
13034                             });
13035                         }
13036                     }
13037 
13038                     break;
13039                 }
13040 
13041                 default:
13042                 {
13043                     // both primitive type: replace value
13044                     result.push_back(
13045                     {
13046                         {"op", "replace"}, {"path", path}, {"value", target}
13047                     });
13048                     break;
13049                 }
13050             }
13051         }
13052 
13053         return result;
13054     }
13055 
13056     /// @}
13057 };
13058 
13059 /////////////
13060 // presets //
13061 /////////////
13062 
13063 /*!
13064 @brief default JSON class
13065 This type is the default specialization of the @ref basic_json class which
13066 uses the standard template types.
13067 @since version 1.0.0
13068 */
13069 using json = basic_json<>;
13070 
13071 //////////////////
13072 // json_pointer //
13073 //////////////////
13074 
13075 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13076 NLOHMANN_BASIC_JSON_TPL&
get_and_create(NLOHMANN_BASIC_JSON_TPL & j) const13077 json_pointer::get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const
13078 {
13079     using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13080     auto result = &j;
13081 
13082     // in case no reference tokens exist, return a reference to the JSON value
13083     // j which will be overwritten by a primitive value
13084     for (const auto& reference_token : reference_tokens)
13085     {
13086         switch (result->m_type)
13087         {
13088             case detail::value_t::null:
13089             {
13090                 if (reference_token == "0")
13091                 {
13092                     // start a new array if reference token is 0
13093                     result = &result->operator[](0);
13094                 }
13095                 else
13096                 {
13097                     // start a new object otherwise
13098                     result = &result->operator[](reference_token);
13099                 }
13100                 break;
13101             }
13102 
13103             case detail::value_t::object:
13104             {
13105                 // create an entry in the object
13106                 result = &result->operator[](reference_token);
13107                 break;
13108             }
13109 
13110             case detail::value_t::array:
13111             {
13112                 // create an entry in the array
13113                 JSON_TRY
13114                 {
13115                     result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
13116                 }
13117                 JSON_CATCH(std::invalid_argument&)
13118                 {
13119                     JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13120                 }
13121                 break;
13122             }
13123 
13124             /*
13125             The following code is only reached if there exists a reference
13126             token _and_ the current value is primitive. In this case, we have
13127             an error situation, because primitive values may only occur as
13128             single value; that is, with an empty list of reference tokens.
13129             */
13130             default:
13131                 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
13132         }
13133     }
13134 
13135     return *result;
13136 }
13137 
13138 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13139 NLOHMANN_BASIC_JSON_TPL&
get_unchecked(NLOHMANN_BASIC_JSON_TPL * ptr) const13140 json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
13141 {
13142     using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13143     for (const auto& reference_token : reference_tokens)
13144     {
13145         // convert null values to arrays or objects before continuing
13146         if (ptr->m_type == detail::value_t::null)
13147         {
13148             // check if reference token is a number
13149             const bool nums =
13150                 std::all_of(reference_token.begin(), reference_token.end(),
13151                             [](const char x)
13152             {
13153                 return (x >= '0' and x <= '9');
13154             });
13155 
13156             // change value to array for numbers or "-" or to object otherwise
13157             *ptr = (nums or reference_token == "-")
13158                    ? detail::value_t::array
13159                    : detail::value_t::object;
13160         }
13161 
13162         switch (ptr->m_type)
13163         {
13164             case detail::value_t::object:
13165             {
13166                 // use unchecked object access
13167                 ptr = &ptr->operator[](reference_token);
13168                 break;
13169             }
13170 
13171             case detail::value_t::array:
13172             {
13173                 // error condition (cf. RFC 6901, Sect. 4)
13174                 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
13175                 {
13176                     JSON_THROW(detail::parse_error::create(106, 0,
13177                                                            "array index '" + reference_token +
13178                                                            "' must not begin with '0'"));
13179                 }
13180 
13181                 if (reference_token == "-")
13182                 {
13183                     // explicitly treat "-" as index beyond the end
13184                     ptr = &ptr->operator[](ptr->m_value.array->size());
13185                 }
13186                 else
13187                 {
13188                     // convert array index to number; unchecked access
13189                     JSON_TRY
13190                     {
13191                         ptr = &ptr->operator[](
13192                             static_cast<size_type>(std::stoi(reference_token)));
13193                     }
13194                     JSON_CATCH(std::invalid_argument&)
13195                     {
13196                         JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13197                     }
13198                 }
13199                 break;
13200             }
13201 
13202             default:
13203                 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13204         }
13205     }
13206 
13207     return *ptr;
13208 }
13209 
13210 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13211 NLOHMANN_BASIC_JSON_TPL&
get_checked(NLOHMANN_BASIC_JSON_TPL * ptr) const13212 json_pointer::get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const
13213 {
13214     using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13215     for (const auto& reference_token : reference_tokens)
13216     {
13217         switch (ptr->m_type)
13218         {
13219             case detail::value_t::object:
13220             {
13221                 // note: at performs range check
13222                 ptr = &ptr->at(reference_token);
13223                 break;
13224             }
13225 
13226             case detail::value_t::array:
13227             {
13228                 if (JSON_UNLIKELY(reference_token == "-"))
13229                 {
13230                     // "-" always fails the range check
13231                     JSON_THROW(detail::out_of_range::create(402,
13232                                                             "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13233                                                             ") is out of range"));
13234                 }
13235 
13236                 // error condition (cf. RFC 6901, Sect. 4)
13237                 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
13238                 {
13239                     JSON_THROW(detail::parse_error::create(106, 0,
13240                                                            "array index '" + reference_token +
13241                                                            "' must not begin with '0'"));
13242                 }
13243 
13244                 // note: at performs range check
13245                 JSON_TRY
13246                 {
13247                     ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
13248                 }
13249                 JSON_CATCH(std::invalid_argument&)
13250                 {
13251                     JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13252                 }
13253                 break;
13254             }
13255 
13256             default:
13257                 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13258         }
13259     }
13260 
13261     return *ptr;
13262 }
13263 
13264 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13265 const NLOHMANN_BASIC_JSON_TPL&
get_unchecked(const NLOHMANN_BASIC_JSON_TPL * ptr) const13266 json_pointer::get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
13267 {
13268     using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13269     for (const auto& reference_token : reference_tokens)
13270     {
13271         switch (ptr->m_type)
13272         {
13273             case detail::value_t::object:
13274             {
13275                 // use unchecked object access
13276                 ptr = &ptr->operator[](reference_token);
13277                 break;
13278             }
13279 
13280             case detail::value_t::array:
13281             {
13282                 if (JSON_UNLIKELY(reference_token == "-"))
13283                 {
13284                     // "-" cannot be used for const access
13285                     JSON_THROW(detail::out_of_range::create(402,
13286                                                             "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13287                                                             ") is out of range"));
13288                 }
13289 
13290                 // error condition (cf. RFC 6901, Sect. 4)
13291                 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
13292                 {
13293                     JSON_THROW(detail::parse_error::create(106, 0,
13294                                                            "array index '" + reference_token +
13295                                                            "' must not begin with '0'"));
13296                 }
13297 
13298                 // use unchecked array access
13299                 JSON_TRY
13300                 {
13301                     ptr = &ptr->operator[](
13302                         static_cast<size_type>(std::stoi(reference_token)));
13303                 }
13304                 JSON_CATCH(std::invalid_argument&)
13305                 {
13306                     JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13307                 }
13308                 break;
13309             }
13310 
13311             default:
13312                 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13313         }
13314     }
13315 
13316     return *ptr;
13317 }
13318 
13319 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13320 const NLOHMANN_BASIC_JSON_TPL&
get_checked(const NLOHMANN_BASIC_JSON_TPL * ptr) const13321 json_pointer::get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
13322 {
13323     using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13324     for (const auto& reference_token : reference_tokens)
13325     {
13326         switch (ptr->m_type)
13327         {
13328             case detail::value_t::object:
13329             {
13330                 // note: at performs range check
13331                 ptr = &ptr->at(reference_token);
13332                 break;
13333             }
13334 
13335             case detail::value_t::array:
13336             {
13337                 if (JSON_UNLIKELY(reference_token == "-"))
13338                 {
13339                     // "-" always fails the range check
13340                     JSON_THROW(detail::out_of_range::create(402,
13341                                                             "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13342                                                             ") is out of range"));
13343                 }
13344 
13345                 // error condition (cf. RFC 6901, Sect. 4)
13346                 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
13347                 {
13348                     JSON_THROW(detail::parse_error::create(106, 0,
13349                                                            "array index '" + reference_token +
13350                                                            "' must not begin with '0'"));
13351                 }
13352 
13353                 // note: at performs range check
13354                 JSON_TRY
13355                 {
13356                     ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
13357                 }
13358                 JSON_CATCH(std::invalid_argument&)
13359                 {
13360                     JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13361                 }
13362                 break;
13363             }
13364 
13365             default:
13366                 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13367         }
13368     }
13369 
13370     return *ptr;
13371 }
13372 
13373 NLOHMANN_BASIC_JSON_TPL_DECLARATION
flatten(const std::string & reference_string,const NLOHMANN_BASIC_JSON_TPL & value,NLOHMANN_BASIC_JSON_TPL & result)13374 void json_pointer::flatten(const std::string& reference_string,
13375                            const NLOHMANN_BASIC_JSON_TPL& value,
13376                            NLOHMANN_BASIC_JSON_TPL& result)
13377 {
13378     switch (value.m_type)
13379     {
13380         case detail::value_t::array:
13381         {
13382             if (value.m_value.array->empty())
13383             {
13384                 // flatten empty array as null
13385                 result[reference_string] = nullptr;
13386             }
13387             else
13388             {
13389                 // iterate array and use index as reference string
13390                 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13391                 {
13392                     flatten(reference_string + "/" + std::to_string(i),
13393                             value.m_value.array->operator[](i), result);
13394                 }
13395             }
13396             break;
13397         }
13398 
13399         case detail::value_t::object:
13400         {
13401             if (value.m_value.object->empty())
13402             {
13403                 // flatten empty object as null
13404                 result[reference_string] = nullptr;
13405             }
13406             else
13407             {
13408                 // iterate object and use keys as reference string
13409                 for (const auto& element : *value.m_value.object)
13410                 {
13411                     flatten(reference_string + "/" + escape(element.first), element.second, result);
13412                 }
13413             }
13414             break;
13415         }
13416 
13417         default:
13418         {
13419             // add primitive value with its reference string
13420             result[reference_string] = value;
13421             break;
13422         }
13423     }
13424 }
13425 
13426 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13427 NLOHMANN_BASIC_JSON_TPL
unflatten(const NLOHMANN_BASIC_JSON_TPL & value)13428 json_pointer::unflatten(const NLOHMANN_BASIC_JSON_TPL& value)
13429 {
13430     if (JSON_UNLIKELY(not value.is_object()))
13431     {
13432         JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
13433     }
13434 
13435     NLOHMANN_BASIC_JSON_TPL result;
13436 
13437     // iterate the JSON object values
13438     for (const auto& element : *value.m_value.object)
13439     {
13440         if (JSON_UNLIKELY(not element.second.is_primitive()))
13441         {
13442             JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
13443         }
13444 
13445         // assign value to reference pointed to by JSON pointer; Note that if
13446         // the JSON pointer is "" (i.e., points to the whole value), function
13447         // get_and_create returns a reference to result itself. An assignment
13448         // will then create a primitive value.
13449         json_pointer(element.first).get_and_create(result) = element.second;
13450     }
13451 
13452     return result;
13453 }
13454 
operator ==(json_pointer const & lhs,json_pointer const & rhs)13455 inline bool operator==(json_pointer const& lhs, json_pointer const& rhs) noexcept
13456 {
13457     return (lhs.reference_tokens == rhs.reference_tokens);
13458 }
13459 
operator !=(json_pointer const & lhs,json_pointer const & rhs)13460 inline bool operator!=(json_pointer const& lhs, json_pointer const& rhs) noexcept
13461 {
13462     return not (lhs == rhs);
13463 }
13464 } // namespace nlohmann
13465 
13466 
13467 ///////////////////////
13468 // nonmember support //
13469 ///////////////////////
13470 
13471 // specialization of std::swap, and std::hash
13472 namespace std
13473 {
13474 /*!
13475 @brief exchanges the values of two JSON objects
13476 @since version 1.0.0
13477 */
13478 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)13479 inline void swap(nlohmann::json& j1,
13480                  nlohmann::json& j2) noexcept(
13481                      is_nothrow_move_constructible<nlohmann::json>::value and
13482                      is_nothrow_move_assignable<nlohmann::json>::value
13483                  )
13484 {
13485     j1.swap(j2);
13486 }
13487 
13488 /// hash value for JSON objects
13489 template<>
13490 struct hash<nlohmann::json>
13491 {
13492     /*!
13493     @brief return a hash value for a JSON object
13494     @since version 1.0.0
13495     */
operator ()std::hash13496     std::size_t operator()(const nlohmann::json& j) const
13497     {
13498         // a naive hashing via the string representation
13499         const auto& h = hash<nlohmann::json::string_t>();
13500         return h(j.dump());
13501     }
13502 };
13503 
13504 /// specialization for std::less<value_t>
13505 /// @note: do not remove the space after '<',
13506 ///        see https://github.com/nlohmann/json/pull/679
13507 template<>
13508 struct less< ::nlohmann::detail::value_t>
13509 {
13510     /*!
13511     @brief compare two value_t enum values
13512     @since version 3.0.0
13513     */
operator ()std::less13514     bool operator()(nlohmann::detail::value_t lhs,
13515                     nlohmann::detail::value_t rhs) const noexcept
13516     {
13517         return nlohmann::detail::operator<(lhs, rhs);
13518     }
13519 };
13520 
13521 } // namespace std
13522 
13523 /*!
13524 @brief user-defined string literal for JSON values
13525 This operator implements a user-defined string literal for JSON objects. It
13526 can be used by adding `"_json"` to a string literal and returns a JSON object
13527 if no parse error occurred.
13528 @param[in] s  a string representation of a JSON object
13529 @param[in] n  the length of string @a s
13530 @return a JSON object
13531 @since version 1.0.0
13532 */
operator ""_json(const char * s,std::size_t n)13533 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
13534 {
13535     return nlohmann::json::parse(s, s + n);
13536 }
13537 
13538 /*!
13539 @brief user-defined string literal for JSON pointer
13540 This operator implements a user-defined string literal for JSON Pointers. It
13541 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
13542 object if no parse error occurred.
13543 @param[in] s  a string representation of a JSON Pointer
13544 @param[in] n  the length of string @a s
13545 @return a JSON pointer object
13546 @since version 2.0.0
13547 */
operator ""_json_pointer(const char * s,std::size_t n)13548 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
13549 {
13550     return nlohmann::json::json_pointer(std::string(s, n));
13551 }
13552 
13553 // restore GCC/clang diagnostic settings
13554 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
13555     #pragma GCC diagnostic pop
13556 #endif
13557 #if defined(__clang__)
13558     #pragma GCC diagnostic pop
13559 #endif
13560 
13561 // clean up
13562 #undef JSON_CATCH
13563 #undef JSON_THROW
13564 #undef JSON_TRY
13565 #undef JSON_LIKELY
13566 #undef JSON_UNLIKELY
13567 #undef JSON_DEPRECATED
13568 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
13569 #undef NLOHMANN_BASIC_JSON_TPL
13570 
13571 #endif
13572