1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++
4 |  |  |__   |  |  | | | |  version 3.6.1
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32 
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 6
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cassert> // assert
39 #include <ciso646> // and, not, or
40 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
41 #include <functional> // hash, less
42 #include <initializer_list> // initializer_list
43 #include <iosfwd> // istream, ostream
44 #include <iterator> // random_access_iterator_tag
45 #include <memory> // unique_ptr
46 #include <numeric> // accumulate
47 #include <string> // string, stoi, to_string
48 #include <utility> // declval, forward, move, pair, swap
49 #include <vector> // vector
50 
51 // #include <nlohmann/adl_serializer.hpp>
52 
53 
54 #include <utility>
55 
56 // #include <nlohmann/detail/conversions/from_json.hpp>
57 
58 
59 #include <algorithm> // transform
60 #include <array> // array
61 #include <ciso646> // and, not
62 #include <forward_list> // forward_list
63 #include <iterator> // inserter, front_inserter, end
64 #include <map> // map
65 #include <string> // string
66 #include <tuple> // tuple, make_tuple
67 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68 #include <unordered_map> // unordered_map
69 #include <utility> // pair, declval
70 #include <valarray> // valarray
71 
72 // #include <nlohmann/detail/exceptions.hpp>
73 
74 
75 #include <exception> // exception
76 #include <stdexcept> // runtime_error
77 #include <string> // to_string
78 
79 // #include <nlohmann/detail/input/position_t.hpp>
80 
81 
82 #include <cstddef> // size_t
83 
84 namespace nlohmann
85 {
86 namespace detail
87 {
88 /// struct to capture the start position of the current token
89 struct position_t
90 {
91     /// the total number of characters read
92     std::size_t chars_read_total = 0;
93     /// the number of characters read in the current line
94     std::size_t chars_read_current_line = 0;
95     /// the number of lines read
96     std::size_t lines_read = 0;
97 
98     /// conversion to size_t to preserve SAX interface
operator size_tnlohmann::detail::position_t99     constexpr operator size_t() const
100     {
101         return chars_read_total;
102     }
103 };
104 
105 } // namespace detail
106 } // namespace nlohmann
107 
108 
109 namespace nlohmann
110 {
111 namespace detail
112 {
113 ////////////////
114 // exceptions //
115 ////////////////
116 
117 /*!
118 @brief general exception of the @ref basic_json class
119 
120 This class is an extension of `std::exception` objects with a member @a id for
121 exception ids. It is used as the base class for all exceptions thrown by the
122 @ref basic_json class. This class can hence be used as "wildcard" to catch
123 exceptions.
124 
125 Subclasses:
126 - @ref parse_error for exceptions indicating a parse error
127 - @ref invalid_iterator for exceptions indicating errors with iterators
128 - @ref type_error for exceptions indicating executing a member function with
129                   a wrong type
130 - @ref out_of_range for exceptions indicating access out of the defined range
131 - @ref other_error for exceptions indicating other library errors
132 
133 @internal
134 @note To have nothrow-copy-constructible exceptions, we internally use
135       `std::runtime_error` which can cope with arbitrary-length error messages.
136       Intermediate strings are built with static functions and then passed to
137       the actual constructor.
138 @endinternal
139 
140 @liveexample{The following code shows how arbitrary library exceptions can be
141 caught.,exception}
142 
143 @since version 3.0.0
144 */
145 class exception : public std::exception
146 {
147   public:
148     /// returns the explanatory string
what() const149     const char* what() const noexcept override
150     {
151         return m.what();
152     }
153 
154     /// the id of the exception
155     const int id;
156 
157   protected:
exception(int id_,const char * what_arg)158     exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
159 
name(const std::string & ename,int id_)160     static std::string name(const std::string& ename, int id_)
161     {
162         return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
163     }
164 
165   private:
166     /// an exception object as storage for error messages
167     std::runtime_error m;
168 };
169 
170 /*!
171 @brief exception indicating a parse error
172 
173 This exception is thrown by the library when a parse error occurs. Parse errors
174 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
175 as when using JSON Patch.
176 
177 Member @a byte holds the byte index of the last read character in the input
178 file.
179 
180 Exceptions have ids 1xx.
181 
182 name / id                      | example message | description
183 ------------------------------ | --------------- | -------------------------
184 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.
185 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.
186 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.
187 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.
188 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.
189 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 without a leading `0`.
190 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.
191 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.
192 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
193 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.
194 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.
195 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.
196 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
197 
198 @note For an input with n bytes, 1 is the index of the first character and n+1
199       is the index of the terminating null byte or the end of file. This also
200       holds true when reading a byte vector (CBOR or MessagePack).
201 
202 @liveexample{The following code shows how a `parse_error` exception can be
203 caught.,parse_error}
204 
205 @sa - @ref exception for the base class of the library exceptions
206 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
207 @sa - @ref type_error for exceptions indicating executing a member function with
208                     a wrong type
209 @sa - @ref out_of_range for exceptions indicating access out of the defined range
210 @sa - @ref other_error for exceptions indicating other library errors
211 
212 @since version 3.0.0
213 */
214 class parse_error : public exception
215 {
216   public:
217     /*!
218     @brief create a parse error exception
219     @param[in] id_       the id of the exception
220     @param[in] pos       the position where the error occurred (or with
221                          chars_read_total=0 if the position cannot be
222                          determined)
223     @param[in] what_arg  the explanatory string
224     @return parse_error object
225     */
create(int id_,const position_t & pos,const std::string & what_arg)226     static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
227     {
228         std::string w = exception::name("parse_error", id_) + "parse error" +
229                         position_string(pos) + ": " + what_arg;
230         return parse_error(id_, pos.chars_read_total, w.c_str());
231     }
232 
create(int id_,std::size_t byte_,const std::string & what_arg)233     static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
234     {
235         std::string w = exception::name("parse_error", id_) + "parse error" +
236                         (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
237                         ": " + what_arg;
238         return parse_error(id_, byte_, w.c_str());
239     }
240 
241     /*!
242     @brief byte index of the parse error
243 
244     The byte index of the last read character in the input file.
245 
246     @note For an input with n bytes, 1 is the index of the first character and
247           n+1 is the index of the terminating null byte or the end of file.
248           This also holds true when reading a byte vector (CBOR or MessagePack).
249     */
250     const std::size_t byte;
251 
252   private:
parse_error(int id_,std::size_t byte_,const char * what_arg)253     parse_error(int id_, std::size_t byte_, const char* what_arg)
254         : exception(id_, what_arg), byte(byte_) {}
255 
position_string(const position_t & pos)256     static std::string position_string(const position_t& pos)
257     {
258         return " at line " + std::to_string(pos.lines_read + 1) +
259                ", column " + std::to_string(pos.chars_read_current_line);
260     }
261 };
262 
263 /*!
264 @brief exception indicating errors with iterators
265 
266 This exception is thrown if iterators passed to a library function do not match
267 the expected semantics.
268 
269 Exceptions have ids 2xx.
270 
271 name / id                           | example message | description
272 ----------------------------------- | --------------- | -------------------------
273 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.
274 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.
275 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.
276 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.
277 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.
278 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.
279 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.
280 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.
281 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.
282 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.
283 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.
284 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
285 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
286 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().
287 
288 @liveexample{The following code shows how an `invalid_iterator` exception can be
289 caught.,invalid_iterator}
290 
291 @sa - @ref exception for the base class of the library exceptions
292 @sa - @ref parse_error for exceptions indicating a parse error
293 @sa - @ref type_error for exceptions indicating executing a member function with
294                     a wrong type
295 @sa - @ref out_of_range for exceptions indicating access out of the defined range
296 @sa - @ref other_error for exceptions indicating other library errors
297 
298 @since version 3.0.0
299 */
300 class invalid_iterator : public exception
301 {
302   public:
create(int id_,const std::string & what_arg)303     static invalid_iterator create(int id_, const std::string& what_arg)
304     {
305         std::string w = exception::name("invalid_iterator", id_) + what_arg;
306         return invalid_iterator(id_, w.c_str());
307     }
308 
309   private:
invalid_iterator(int id_,const char * what_arg)310     invalid_iterator(int id_, const char* what_arg)
311         : exception(id_, what_arg) {}
312 };
313 
314 /*!
315 @brief exception indicating executing a member function with a wrong type
316 
317 This exception is thrown in case of a type error; that is, a library function is
318 executed on a JSON value whose type does not match the expected semantics.
319 
320 Exceptions have ids 3xx.
321 
322 name / id                     | example message | description
323 ----------------------------- | --------------- | -------------------------
324 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.
325 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.
326 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 &.
327 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
328 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
329 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
330 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
331 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.
332 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
333 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
334 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.
335 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
336 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.
337 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
338 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.
339 json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
340 json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |
341 
342 @liveexample{The following code shows how a `type_error` exception can be
343 caught.,type_error}
344 
345 @sa - @ref exception for the base class of the library exceptions
346 @sa - @ref parse_error for exceptions indicating a parse error
347 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
348 @sa - @ref out_of_range for exceptions indicating access out of the defined range
349 @sa - @ref other_error for exceptions indicating other library errors
350 
351 @since version 3.0.0
352 */
353 class type_error : public exception
354 {
355   public:
create(int id_,const std::string & what_arg)356     static type_error create(int id_, const std::string& what_arg)
357     {
358         std::string w = exception::name("type_error", id_) + what_arg;
359         return type_error(id_, w.c_str());
360     }
361 
362   private:
type_error(int id_,const char * what_arg)363     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
364 };
365 
366 /*!
367 @brief exception indicating access out of the defined range
368 
369 This exception is thrown in case a library function is called on an input
370 parameter that exceeds the expected range, for instance in case of array
371 indices or nonexisting object keys.
372 
373 Exceptions have ids 4xx.
374 
375 name / id                       | example message | description
376 ------------------------------- | --------------- | -------------------------
377 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.
378 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.
379 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
380 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
381 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.
382 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.
383 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. |
384 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
385 json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |
386 
387 @liveexample{The following code shows how an `out_of_range` exception can be
388 caught.,out_of_range}
389 
390 @sa - @ref exception for the base class of the library exceptions
391 @sa - @ref parse_error for exceptions indicating a parse error
392 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
393 @sa - @ref type_error for exceptions indicating executing a member function with
394                     a wrong type
395 @sa - @ref other_error for exceptions indicating other library errors
396 
397 @since version 3.0.0
398 */
399 class out_of_range : public exception
400 {
401   public:
create(int id_,const std::string & what_arg)402     static out_of_range create(int id_, const std::string& what_arg)
403     {
404         std::string w = exception::name("out_of_range", id_) + what_arg;
405         return out_of_range(id_, w.c_str());
406     }
407 
408   private:
out_of_range(int id_,const char * what_arg)409     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
410 };
411 
412 /*!
413 @brief exception indicating other library errors
414 
415 This exception is thrown in case of errors that cannot be classified with the
416 other exception types.
417 
418 Exceptions have ids 5xx.
419 
420 name / id                      | example message | description
421 ------------------------------ | --------------- | -------------------------
422 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
423 
424 @sa - @ref exception for the base class of the library exceptions
425 @sa - @ref parse_error for exceptions indicating a parse error
426 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
427 @sa - @ref type_error for exceptions indicating executing a member function with
428                     a wrong type
429 @sa - @ref out_of_range for exceptions indicating access out of the defined range
430 
431 @liveexample{The following code shows how an `other_error` exception can be
432 caught.,other_error}
433 
434 @since version 3.0.0
435 */
436 class other_error : public exception
437 {
438   public:
create(int id_,const std::string & what_arg)439     static other_error create(int id_, const std::string& what_arg)
440     {
441         std::string w = exception::name("other_error", id_) + what_arg;
442         return other_error(id_, w.c_str());
443     }
444 
445   private:
other_error(int id_,const char * what_arg)446     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
447 };
448 }  // namespace detail
449 }  // namespace nlohmann
450 
451 // #include <nlohmann/detail/macro_scope.hpp>
452 
453 
454 #include <utility> // pair
455 
456 // This file contains all internal macro definitions
457 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
458 
459 // exclude unsupported compilers
460 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
461     #if defined(__clang__)
462         #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
463             #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
464         #endif
465     #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
466         #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
467             #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
468         #endif
469     #endif
470 #endif
471 
472 // disable float-equal warnings on GCC/clang
473 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
474     #pragma GCC diagnostic push
475     #pragma GCC diagnostic ignored "-Wfloat-equal"
476 #endif
477 
478 // disable documentation warnings on clang
479 #if defined(__clang__)
480     #pragma GCC diagnostic push
481     #pragma GCC diagnostic ignored "-Wdocumentation"
482 #endif
483 
484 // allow for portable deprecation warnings
485 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
486     #define JSON_DEPRECATED __attribute__((deprecated))
487 #elif defined(_MSC_VER)
488     #define JSON_DEPRECATED __declspec(deprecated)
489 #else
490     #define JSON_DEPRECATED
491 #endif
492 
493 // allow for portable nodiscard warnings
494 #if defined(__has_cpp_attribute)
495     #if __has_cpp_attribute(nodiscard)
496         #define JSON_NODISCARD [[nodiscard]]
497     #elif __has_cpp_attribute(gnu::warn_unused_result)
498         #define JSON_NODISCARD [[gnu::warn_unused_result]]
499     #else
500         #define JSON_NODISCARD
501     #endif
502 #else
503     #define JSON_NODISCARD
504 #endif
505 
506 // allow to disable exceptions
507 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
508     #define JSON_THROW(exception) throw exception
509     #define JSON_TRY try
510     #define JSON_CATCH(exception) catch(exception)
511     #define JSON_INTERNAL_CATCH(exception) catch(exception)
512 #else
513     #include <cstdlib>
514     #define JSON_THROW(exception) std::abort()
515     #define JSON_TRY if(true)
516     #define JSON_CATCH(exception) if(false)
517     #define JSON_INTERNAL_CATCH(exception) if(false)
518 #endif
519 
520 // override exception macros
521 #if defined(JSON_THROW_USER)
522     #undef JSON_THROW
523     #define JSON_THROW JSON_THROW_USER
524 #endif
525 #if defined(JSON_TRY_USER)
526     #undef JSON_TRY
527     #define JSON_TRY JSON_TRY_USER
528 #endif
529 #if defined(JSON_CATCH_USER)
530     #undef JSON_CATCH
531     #define JSON_CATCH JSON_CATCH_USER
532     #undef JSON_INTERNAL_CATCH
533     #define JSON_INTERNAL_CATCH JSON_CATCH_USER
534 #endif
535 #if defined(JSON_INTERNAL_CATCH_USER)
536     #undef JSON_INTERNAL_CATCH
537     #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
538 #endif
539 
540 // manual branch prediction
541 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
542     #define JSON_LIKELY(x)      __builtin_expect(x, 1)
543     #define JSON_UNLIKELY(x)    __builtin_expect(x, 0)
544 #else
545     #define JSON_LIKELY(x)      x
546     #define JSON_UNLIKELY(x)    x
547 #endif
548 
549 // C++ language standard detection
550 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
551     #define JSON_HAS_CPP_17
552     #define JSON_HAS_CPP_14
553 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
554     #define JSON_HAS_CPP_14
555 #endif
556 
557 /*!
558 @brief macro to briefly define a mapping between an enum and JSON
559 @def NLOHMANN_JSON_SERIALIZE_ENUM
560 @since version 3.4.0
561 */
562 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                           \
563     template<typename BasicJsonType>                                                           \
564     inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                  \
565     {                                                                                          \
566         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");         \
567         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                    \
568         auto it = std::find_if(std::begin(m), std::end(m),                                     \
569                                [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
570         {                                                                                      \
571             return ej_pair.first == e;                                                         \
572         });                                                                                    \
573         j = ((it != std::end(m)) ? it : std::begin(m))->second;                                \
574     }                                                                                          \
575     template<typename BasicJsonType>                                                           \
576     inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                \
577     {                                                                                          \
578         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");         \
579         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                    \
580         auto it = std::find_if(std::begin(m), std::end(m),                                     \
581                                [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
582         {                                                                                      \
583             return ej_pair.second == j;                                                        \
584         });                                                                                    \
585         e = ((it != std::end(m)) ? it : std::begin(m))->first;                                 \
586     }
587 
588 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
589 // may be removed in the future once the class is split.
590 
591 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
592     template<template<typename, typename, typename...> class ObjectType,   \
593              template<typename, typename...> class ArrayType,              \
594              class StringType, class BooleanType, class NumberIntegerType, \
595              class NumberUnsignedType, class NumberFloatType,              \
596              template<typename> class AllocatorType,                       \
597              template<typename, typename = void> class JSONSerializer>
598 
599 #define NLOHMANN_BASIC_JSON_TPL                                            \
600     basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
601     NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
602     AllocatorType, JSONSerializer>
603 
604 // #include <nlohmann/detail/meta/cpp_future.hpp>
605 
606 
607 #include <ciso646> // not
608 #include <cstddef> // size_t
609 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
610 
611 namespace nlohmann
612 {
613 namespace detail
614 {
615 // alias templates to reduce boilerplate
616 template<bool B, typename T = void>
617 using enable_if_t = typename std::enable_if<B, T>::type;
618 
619 template<typename T>
620 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
621 
622 // implementation of C++14 index_sequence and affiliates
623 // source: https://stackoverflow.com/a/32223343
624 template<std::size_t... Ints>
625 struct index_sequence
626 {
627     using type = index_sequence;
628     using value_type = std::size_t;
sizenlohmann::detail::index_sequence629     static constexpr std::size_t size() noexcept
630     {
631         return sizeof...(Ints);
632     }
633 };
634 
635 template<class Sequence1, class Sequence2>
636 struct merge_and_renumber;
637 
638 template<std::size_t... I1, std::size_t... I2>
639 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
640         : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
641 
642 template<std::size_t N>
643 struct make_index_sequence
644     : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
645       typename make_index_sequence < N - N / 2 >::type > {};
646 
647 template<> struct make_index_sequence<0> : index_sequence<> {};
648 template<> struct make_index_sequence<1> : index_sequence<0> {};
649 
650 template<typename... Ts>
651 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
652 
653 // dispatch utility (taken from ranges-v3)
654 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
655 template<> struct priority_tag<0> {};
656 
657 // taken from ranges-v3
658 template<typename T>
659 struct static_const
660 {
661     static constexpr T value{};
662 };
663 
664 template<typename T>
665 constexpr T static_const<T>::value;
666 }  // namespace detail
667 }  // namespace nlohmann
668 
669 // #include <nlohmann/detail/meta/type_traits.hpp>
670 
671 
672 #include <ciso646> // not
673 #include <limits> // numeric_limits
674 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
675 #include <utility> // declval
676 
677 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
678 
679 
680 #include <iterator> // random_access_iterator_tag
681 
682 // #include <nlohmann/detail/meta/void_t.hpp>
683 
684 
685 namespace nlohmann
686 {
687 namespace detail
688 {
689 template <typename ...Ts> struct make_void
690 {
691     using type = void;
692 };
693 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
694 } // namespace detail
695 }  // namespace nlohmann
696 
697 // #include <nlohmann/detail/meta/cpp_future.hpp>
698 
699 
700 namespace nlohmann
701 {
702 namespace detail
703 {
704 template <typename It, typename = void>
705 struct iterator_types {};
706 
707 template <typename It>
708 struct iterator_types <
709     It,
710     void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
711     typename It::reference, typename It::iterator_category >>
712 {
713     using difference_type = typename It::difference_type;
714     using value_type = typename It::value_type;
715     using pointer = typename It::pointer;
716     using reference = typename It::reference;
717     using iterator_category = typename It::iterator_category;
718 };
719 
720 // This is required as some compilers implement std::iterator_traits in a way that
721 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
722 template <typename T, typename = void>
723 struct iterator_traits
724 {
725 };
726 
727 template <typename T>
728 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
729             : iterator_types<T>
730 {
731 };
732 
733 template <typename T>
734 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
735 {
736     using iterator_category = std::random_access_iterator_tag;
737     using value_type = T;
738     using difference_type = ptrdiff_t;
739     using pointer = T*;
740     using reference = T&;
741 };
742 } // namespace detail
743 } // namespace nlohmann
744 
745 // #include <nlohmann/detail/macro_scope.hpp>
746 
747 // #include <nlohmann/detail/meta/cpp_future.hpp>
748 
749 // #include <nlohmann/detail/meta/detected.hpp>
750 
751 
752 #include <type_traits>
753 
754 // #include <nlohmann/detail/meta/void_t.hpp>
755 
756 
757 // http://en.cppreference.com/w/cpp/experimental/is_detected
758 namespace nlohmann
759 {
760 namespace detail
761 {
762 struct nonesuch
763 {
764     nonesuch() = delete;
765     ~nonesuch() = delete;
766     nonesuch(nonesuch const&) = delete;
767     nonesuch(nonesuch const&&) = delete;
768     void operator=(nonesuch const&) = delete;
769     void operator=(nonesuch&&) = delete;
770 };
771 
772 template <class Default,
773           class AlwaysVoid,
774           template <class...> class Op,
775           class... Args>
776 struct detector
777 {
778     using value_t = std::false_type;
779     using type = Default;
780 };
781 
782 template <class Default, template <class...> class Op, class... Args>
783 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
784 {
785     using value_t = std::true_type;
786     using type = Op<Args...>;
787 };
788 
789 template <template <class...> class Op, class... Args>
790 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
791 
792 template <template <class...> class Op, class... Args>
793 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
794 
795 template <class Default, template <class...> class Op, class... Args>
796 using detected_or = detector<Default, void, Op, Args...>;
797 
798 template <class Default, template <class...> class Op, class... Args>
799 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
800 
801 template <class Expected, template <class...> class Op, class... Args>
802 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
803 
804 template <class To, template <class...> class Op, class... Args>
805 using is_detected_convertible =
806     std::is_convertible<detected_t<Op, Args...>, To>;
807 }  // namespace detail
808 }  // namespace nlohmann
809 
810 // #include <nlohmann/json_fwd.hpp>
811 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
812 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
813 
814 #include <cstdint> // int64_t, uint64_t
815 #include <map> // map
816 #include <memory> // allocator
817 #include <string> // string
818 #include <vector> // vector
819 
820 /*!
821 @brief namespace for Niels Lohmann
822 @see https://github.com/nlohmann
823 @since version 1.0.0
824 */
825 namespace nlohmann
826 {
827 /*!
828 @brief default JSONSerializer template argument
829 
830 This serializer ignores the template arguments and uses ADL
831 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
832 for serialization.
833 */
834 template<typename T = void, typename SFINAE = void>
835 struct adl_serializer;
836 
837 template<template<typename U, typename V, typename... Args> class ObjectType =
838          std::map,
839          template<typename U, typename... Args> class ArrayType = std::vector,
840          class StringType = std::string, class BooleanType = bool,
841          class NumberIntegerType = std::int64_t,
842          class NumberUnsignedType = std::uint64_t,
843          class NumberFloatType = double,
844          template<typename U> class AllocatorType = std::allocator,
845          template<typename T, typename SFINAE = void> class JSONSerializer =
846          adl_serializer>
847 class basic_json;
848 
849 /*!
850 @brief JSON Pointer
851 
852 A JSON pointer defines a string syntax for identifying a specific value
853 within a JSON document. It can be used with functions `at` and
854 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
855 
856 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
857 
858 @since version 2.0.0
859 */
860 template<typename BasicJsonType>
861 class json_pointer;
862 
863 /*!
864 @brief default JSON class
865 
866 This type is the default specialization of the @ref basic_json class which
867 uses the standard template types.
868 
869 @since version 1.0.0
870 */
871 using json = basic_json<>;
872 }  // namespace nlohmann
873 
874 #endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
875 
876 
877 namespace nlohmann
878 {
879 /*!
880 @brief detail namespace with internal helper functions
881 
882 This namespace collects functions that should not be exposed,
883 implementations of some @ref basic_json methods, and meta-programming helpers.
884 
885 @since version 2.1.0
886 */
887 namespace detail
888 {
889 /////////////
890 // helpers //
891 /////////////
892 
893 // Note to maintainers:
894 //
895 // Every trait in this file expects a non CV-qualified type.
896 // The only exceptions are in the 'aliases for detected' section
897 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
898 //
899 // In this case, T has to be properly CV-qualified to constraint the function arguments
900 // (e.g. to_json(BasicJsonType&, const T&))
901 
902 template<typename> struct is_basic_json : std::false_type {};
903 
904 NLOHMANN_BASIC_JSON_TPL_DECLARATION
905 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
906 
907 //////////////////////////
908 // aliases for detected //
909 //////////////////////////
910 
911 template <typename T>
912 using mapped_type_t = typename T::mapped_type;
913 
914 template <typename T>
915 using key_type_t = typename T::key_type;
916 
917 template <typename T>
918 using value_type_t = typename T::value_type;
919 
920 template <typename T>
921 using difference_type_t = typename T::difference_type;
922 
923 template <typename T>
924 using pointer_t = typename T::pointer;
925 
926 template <typename T>
927 using reference_t = typename T::reference;
928 
929 template <typename T>
930 using iterator_category_t = typename T::iterator_category;
931 
932 template <typename T>
933 using iterator_t = typename T::iterator;
934 
935 template <typename T, typename... Args>
936 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
937 
938 template <typename T, typename... Args>
939 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
940 
941 template <typename T, typename U>
942 using get_template_function = decltype(std::declval<T>().template get<U>());
943 
944 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
945 template <typename BasicJsonType, typename T, typename = void>
946 struct has_from_json : std::false_type {};
947 
948 template <typename BasicJsonType, typename T>
949 struct has_from_json<BasicJsonType, T,
950            enable_if_t<not is_basic_json<T>::value>>
951 {
952     using serializer = typename BasicJsonType::template json_serializer<T, void>;
953 
954     static constexpr bool value =
955         is_detected_exact<void, from_json_function, serializer,
956         const BasicJsonType&, T&>::value;
957 };
958 
959 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
960 // this overload is used for non-default-constructible user-defined-types
961 template <typename BasicJsonType, typename T, typename = void>
962 struct has_non_default_from_json : std::false_type {};
963 
964 template<typename BasicJsonType, typename T>
965 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
966 {
967     using serializer = typename BasicJsonType::template json_serializer<T, void>;
968 
969     static constexpr bool value =
970         is_detected_exact<T, from_json_function, serializer,
971         const BasicJsonType&>::value;
972 };
973 
974 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
975 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
976 template <typename BasicJsonType, typename T, typename = void>
977 struct has_to_json : std::false_type {};
978 
979 template <typename BasicJsonType, typename T>
980 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
981 {
982     using serializer = typename BasicJsonType::template json_serializer<T, void>;
983 
984     static constexpr bool value =
985         is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
986         T>::value;
987 };
988 
989 
990 ///////////////////
991 // is_ functions //
992 ///////////////////
993 
994 template <typename T, typename = void>
995 struct is_iterator_traits : std::false_type {};
996 
997 template <typename T>
998 struct is_iterator_traits<iterator_traits<T>>
999 {
1000   private:
1001     using traits = iterator_traits<T>;
1002 
1003   public:
1004     static constexpr auto value =
1005         is_detected<value_type_t, traits>::value &&
1006         is_detected<difference_type_t, traits>::value &&
1007         is_detected<pointer_t, traits>::value &&
1008         is_detected<iterator_category_t, traits>::value &&
1009         is_detected<reference_t, traits>::value;
1010 };
1011 
1012 // source: https://stackoverflow.com/a/37193089/4116453
1013 
1014 template <typename T, typename = void>
1015 struct is_complete_type : std::false_type {};
1016 
1017 template <typename T>
1018 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
1019 
1020 template <typename BasicJsonType, typename CompatibleObjectType,
1021           typename = void>
1022 struct is_compatible_object_type_impl : std::false_type {};
1023 
1024 template <typename BasicJsonType, typename CompatibleObjectType>
1025 struct is_compatible_object_type_impl <
1026     BasicJsonType, CompatibleObjectType,
1027     enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
1028     is_detected<key_type_t, CompatibleObjectType>::value >>
1029 {
1030 
1031     using object_t = typename BasicJsonType::object_t;
1032 
1033     // macOS's is_constructible does not play well with nonesuch...
1034     static constexpr bool value =
1035         std::is_constructible<typename object_t::key_type,
1036         typename CompatibleObjectType::key_type>::value and
1037         std::is_constructible<typename object_t::mapped_type,
1038         typename CompatibleObjectType::mapped_type>::value;
1039 };
1040 
1041 template <typename BasicJsonType, typename CompatibleObjectType>
1042 struct is_compatible_object_type
1043     : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
1044 
1045 template <typename BasicJsonType, typename ConstructibleObjectType,
1046           typename = void>
1047 struct is_constructible_object_type_impl : std::false_type {};
1048 
1049 template <typename BasicJsonType, typename ConstructibleObjectType>
1050 struct is_constructible_object_type_impl <
1051     BasicJsonType, ConstructibleObjectType,
1052     enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
1053     is_detected<key_type_t, ConstructibleObjectType>::value >>
1054 {
1055     using object_t = typename BasicJsonType::object_t;
1056 
1057     static constexpr bool value =
1058         (std::is_constructible<typename ConstructibleObjectType::key_type, typename object_t::key_type>::value and
1059          std::is_same<typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type>::value) or
1060         (has_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value or
1061          has_non_default_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type >::value);
1062 };
1063 
1064 template <typename BasicJsonType, typename ConstructibleObjectType>
1065 struct is_constructible_object_type
1066     : is_constructible_object_type_impl<BasicJsonType,
1067       ConstructibleObjectType> {};
1068 
1069 template <typename BasicJsonType, typename CompatibleStringType,
1070           typename = void>
1071 struct is_compatible_string_type_impl : std::false_type {};
1072 
1073 template <typename BasicJsonType, typename CompatibleStringType>
1074 struct is_compatible_string_type_impl <
1075     BasicJsonType, CompatibleStringType,
1076     enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
1077     value_type_t, CompatibleStringType>::value >>
1078 {
1079     static constexpr auto value =
1080         std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
1081 };
1082 
1083 template <typename BasicJsonType, typename ConstructibleStringType>
1084 struct is_compatible_string_type
1085     : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
1086 
1087 template <typename BasicJsonType, typename ConstructibleStringType,
1088           typename = void>
1089 struct is_constructible_string_type_impl : std::false_type {};
1090 
1091 template <typename BasicJsonType, typename ConstructibleStringType>
1092 struct is_constructible_string_type_impl <
1093     BasicJsonType, ConstructibleStringType,
1094     enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
1095     value_type_t, ConstructibleStringType>::value >>
1096 {
1097     static constexpr auto value =
1098         std::is_constructible<ConstructibleStringType,
1099         typename BasicJsonType::string_t>::value;
1100 };
1101 
1102 template <typename BasicJsonType, typename ConstructibleStringType>
1103 struct is_constructible_string_type
1104     : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
1105 
1106 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
1107 struct is_compatible_array_type_impl : std::false_type {};
1108 
1109 template <typename BasicJsonType, typename CompatibleArrayType>
1110 struct is_compatible_array_type_impl <
1111     BasicJsonType, CompatibleArrayType,
1112     enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
1113     is_detected<iterator_t, CompatibleArrayType>::value and
1114 // This is needed because json_reverse_iterator has a ::iterator type...
1115 // Therefore it is detected as a CompatibleArrayType.
1116 // The real fix would be to have an Iterable concept.
1117     not is_iterator_traits<
1118     iterator_traits<CompatibleArrayType>>::value >>
1119 {
1120     static constexpr bool value =
1121         std::is_constructible<BasicJsonType,
1122         typename CompatibleArrayType::value_type>::value;
1123 };
1124 
1125 template <typename BasicJsonType, typename CompatibleArrayType>
1126 struct is_compatible_array_type
1127     : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
1128 
1129 template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
1130 struct is_constructible_array_type_impl : std::false_type {};
1131 
1132 template <typename BasicJsonType, typename ConstructibleArrayType>
1133 struct is_constructible_array_type_impl <
1134     BasicJsonType, ConstructibleArrayType,
1135     enable_if_t<std::is_same<ConstructibleArrayType,
1136     typename BasicJsonType::value_type>::value >>
1137             : std::true_type {};
1138 
1139 template <typename BasicJsonType, typename ConstructibleArrayType>
1140 struct is_constructible_array_type_impl <
1141     BasicJsonType, ConstructibleArrayType,
1142     enable_if_t<not std::is_same<ConstructibleArrayType,
1143     typename BasicJsonType::value_type>::value and
1144     is_detected<value_type_t, ConstructibleArrayType>::value and
1145     is_detected<iterator_t, ConstructibleArrayType>::value and
1146     is_complete_type<
1147     detected_t<value_type_t, ConstructibleArrayType>>::value >>
1148 {
1149     static constexpr bool value =
1150         // This is needed because json_reverse_iterator has a ::iterator type,
1151         // furthermore, std::back_insert_iterator (and other iterators) have a base class `iterator`...
1152         // Therefore it is detected as a ConstructibleArrayType.
1153         // The real fix would be to have an Iterable concept.
1154         not is_iterator_traits <
1155         iterator_traits<ConstructibleArrayType >>::value and
1156 
1157         (std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
1158          has_from_json<BasicJsonType,
1159          typename ConstructibleArrayType::value_type>::value or
1160          has_non_default_from_json <
1161          BasicJsonType, typename ConstructibleArrayType::value_type >::value);
1162 };
1163 
1164 template <typename BasicJsonType, typename ConstructibleArrayType>
1165 struct is_constructible_array_type
1166     : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
1167 
1168 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
1169           typename = void>
1170 struct is_compatible_integer_type_impl : std::false_type {};
1171 
1172 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
1173 struct is_compatible_integer_type_impl <
1174     RealIntegerType, CompatibleNumberIntegerType,
1175     enable_if_t<std::is_integral<RealIntegerType>::value and
1176     std::is_integral<CompatibleNumberIntegerType>::value and
1177     not std::is_same<bool, CompatibleNumberIntegerType>::value >>
1178 {
1179     // is there an assert somewhere on overflows?
1180     using RealLimits = std::numeric_limits<RealIntegerType>;
1181     using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
1182 
1183     static constexpr auto value =
1184         std::is_constructible<RealIntegerType,
1185         CompatibleNumberIntegerType>::value and
1186         CompatibleLimits::is_integer and
1187         RealLimits::is_signed == CompatibleLimits::is_signed;
1188 };
1189 
1190 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
1191 struct is_compatible_integer_type
1192     : is_compatible_integer_type_impl<RealIntegerType,
1193       CompatibleNumberIntegerType> {};
1194 
1195 template <typename BasicJsonType, typename CompatibleType, typename = void>
1196 struct is_compatible_type_impl: std::false_type {};
1197 
1198 template <typename BasicJsonType, typename CompatibleType>
1199 struct is_compatible_type_impl <
1200     BasicJsonType, CompatibleType,
1201     enable_if_t<is_complete_type<CompatibleType>::value >>
1202 {
1203     static constexpr bool value =
1204         has_to_json<BasicJsonType, CompatibleType>::value;
1205 };
1206 
1207 template <typename BasicJsonType, typename CompatibleType>
1208 struct is_compatible_type
1209     : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
1210 }  // namespace detail
1211 }  // namespace nlohmann
1212 
1213 // #include <nlohmann/detail/value_t.hpp>
1214 
1215 
1216 #include <array> // array
1217 #include <ciso646> // and
1218 #include <cstddef> // size_t
1219 #include <cstdint> // uint8_t
1220 #include <string> // string
1221 
1222 namespace nlohmann
1223 {
1224 namespace detail
1225 {
1226 ///////////////////////////
1227 // JSON type enumeration //
1228 ///////////////////////////
1229 
1230 /*!
1231 @brief the JSON type enumeration
1232 
1233 This enumeration collects the different JSON types. It is internally used to
1234 distinguish the stored values, and the functions @ref basic_json::is_null(),
1235 @ref basic_json::is_object(), @ref basic_json::is_array(),
1236 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
1237 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
1238 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
1239 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
1240 @ref basic_json::is_structured() rely on it.
1241 
1242 @note There are three enumeration entries (number_integer, number_unsigned, and
1243 number_float), because the library distinguishes these three types for numbers:
1244 @ref basic_json::number_unsigned_t is used for unsigned integers,
1245 @ref basic_json::number_integer_t is used for signed integers, and
1246 @ref basic_json::number_float_t is used for floating-point numbers or to
1247 approximate integers which do not fit in the limits of their respective type.
1248 
1249 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
1250 value with the default value for a given type
1251 
1252 @since version 1.0.0
1253 */
1254 enum class value_t : std::uint8_t
1255 {
1256     null,             ///< null value
1257     object,           ///< object (unordered set of name/value pairs)
1258     array,            ///< array (ordered collection of values)
1259     string,           ///< string value
1260     boolean,          ///< boolean value
1261     number_integer,   ///< number value (signed integer)
1262     number_unsigned,  ///< number value (unsigned integer)
1263     number_float,     ///< number value (floating-point)
1264     discarded         ///< discarded by the the parser callback function
1265 };
1266 
1267 /*!
1268 @brief comparison operator for JSON types
1269 
1270 Returns an ordering that is similar to Python:
1271 - order: null < boolean < number < object < array < string
1272 - furthermore, each type is not smaller than itself
1273 - discarded values are not comparable
1274 
1275 @since version 1.0.0
1276 */
operator <(const value_t lhs,const value_t rhs)1277 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
1278 {
1279     static constexpr std::array<std::uint8_t, 8> order = {{
1280             0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
1281             1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
1282         }
1283     };
1284 
1285     const auto l_index = static_cast<std::size_t>(lhs);
1286     const auto r_index = static_cast<std::size_t>(rhs);
1287     return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1288 }
1289 }  // namespace detail
1290 }  // namespace nlohmann
1291 
1292 
1293 namespace nlohmann
1294 {
1295 namespace detail
1296 {
1297 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)1298 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
1299 {
1300     if (JSON_UNLIKELY(not j.is_null()))
1301     {
1302         JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
1303     }
1304     n = nullptr;
1305 }
1306 
1307 // overloads for basic_json template parameters
1308 template<typename BasicJsonType, typename ArithmeticType,
1309          enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1310                      not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1311                      int> = 0>
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)1312 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1313 {
1314     switch (static_cast<value_t>(j))
1315     {
1316         case value_t::number_unsigned:
1317         {
1318             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1319             break;
1320         }
1321         case value_t::number_integer:
1322         {
1323             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1324             break;
1325         }
1326         case value_t::number_float:
1327         {
1328             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1329             break;
1330         }
1331 
1332         default:
1333             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1334     }
1335 }
1336 
1337 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)1338 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1339 {
1340     if (JSON_UNLIKELY(not j.is_boolean()))
1341     {
1342         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1343     }
1344     b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1345 }
1346 
1347 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)1348 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1349 {
1350     if (JSON_UNLIKELY(not j.is_string()))
1351     {
1352         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1353     }
1354     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1355 }
1356 
1357 template <
1358     typename BasicJsonType, typename ConstructibleStringType,
1359     enable_if_t <
1360         is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
1361         not std::is_same<typename BasicJsonType::string_t,
1362                          ConstructibleStringType>::value,
1363         int > = 0 >
from_json(const BasicJsonType & j,ConstructibleStringType & s)1364 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
1365 {
1366     if (JSON_UNLIKELY(not j.is_string()))
1367     {
1368         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1369     }
1370 
1371     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1372 }
1373 
1374 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)1375 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1376 {
1377     get_arithmetic_value(j, val);
1378 }
1379 
1380 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)1381 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1382 {
1383     get_arithmetic_value(j, val);
1384 }
1385 
1386 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)1387 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1388 {
1389     get_arithmetic_value(j, val);
1390 }
1391 
1392 template<typename BasicJsonType, typename EnumType,
1393          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)1394 void from_json(const BasicJsonType& j, EnumType& e)
1395 {
1396     typename std::underlying_type<EnumType>::type val;
1397     get_arithmetic_value(j, val);
1398     e = static_cast<EnumType>(val);
1399 }
1400 
1401 // forward_list doesn't have an insert method
1402 template<typename BasicJsonType, typename T, typename Allocator,
1403          enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)1404 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1405 {
1406     if (JSON_UNLIKELY(not j.is_array()))
1407     {
1408         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1409     }
1410     std::transform(j.rbegin(), j.rend(),
1411                    std::front_inserter(l), [](const BasicJsonType & i)
1412     {
1413         return i.template get<T>();
1414     });
1415 }
1416 
1417 // valarray doesn't have an insert method
1418 template<typename BasicJsonType, typename T,
1419          enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)1420 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1421 {
1422     if (JSON_UNLIKELY(not j.is_array()))
1423     {
1424         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1425     }
1426     l.resize(j.size());
1427     std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1428 }
1429 
1430 template<typename BasicJsonType>
from_json_array_impl(const BasicJsonType & j,typename BasicJsonType::array_t & arr,priority_tag<3>)1431 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
1432 {
1433     arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1434 }
1435 
1436 template <typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)1437 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
1438                           priority_tag<2> /*unused*/)
1439 -> decltype(j.template get<T>(), void())
1440 {
1441     for (std::size_t i = 0; i < N; ++i)
1442     {
1443         arr[i] = j.at(i).template get<T>();
1444     }
1445 }
1446 
1447 template<typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<1>)1448 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
1449 -> decltype(
1450     arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
1451     j.template get<typename ConstructibleArrayType::value_type>(),
1452     void())
1453 {
1454     using std::end;
1455 
1456     arr.reserve(j.size());
1457     std::transform(j.begin(), j.end(),
1458                    std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1459     {
1460         // get<BasicJsonType>() returns *this, this won't call a from_json
1461         // method when value_type is BasicJsonType
1462         return i.template get<typename ConstructibleArrayType::value_type>();
1463     });
1464 }
1465 
1466 template <typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<0>)1467 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
1468                           priority_tag<0> /*unused*/)
1469 {
1470     using std::end;
1471 
1472     std::transform(
1473         j.begin(), j.end(), std::inserter(arr, end(arr)),
1474         [](const BasicJsonType & i)
1475     {
1476         // get<BasicJsonType>() returns *this, this won't call a from_json
1477         // method when value_type is BasicJsonType
1478         return i.template get<typename ConstructibleArrayType::value_type>();
1479     });
1480 }
1481 
1482 template <typename BasicJsonType, typename ConstructibleArrayType,
1483           enable_if_t <
1484               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
1485               not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
1486               not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
1487               not is_basic_json<ConstructibleArrayType>::value,
1488               int > = 0 >
1489 
from_json(const BasicJsonType & j,ConstructibleArrayType & arr)1490 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
1491 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
1492 j.template get<typename ConstructibleArrayType::value_type>(),
1493 void())
1494 {
1495     if (JSON_UNLIKELY(not j.is_array()))
1496     {
1497         JSON_THROW(type_error::create(302, "type must be array, but is " +
1498                                       std::string(j.type_name())));
1499     }
1500 
1501     from_json_array_impl(j, arr, priority_tag<3> {});
1502 }
1503 
1504 template<typename BasicJsonType, typename ConstructibleObjectType,
1505          enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,ConstructibleObjectType & obj)1506 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
1507 {
1508     if (JSON_UNLIKELY(not j.is_object()))
1509     {
1510         JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1511     }
1512 
1513     auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1514     using value_type = typename ConstructibleObjectType::value_type;
1515     std::transform(
1516         inner_object->begin(), inner_object->end(),
1517         std::inserter(obj, obj.begin()),
1518         [](typename BasicJsonType::object_t::value_type const & p)
1519     {
1520         return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
1521     });
1522 }
1523 
1524 // overload for arithmetic types, not chosen for basic_json template arguments
1525 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1526 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1527 // an arithmetic type?
1528 template<typename BasicJsonType, typename ArithmeticType,
1529          enable_if_t <
1530              std::is_arithmetic<ArithmeticType>::value and
1531              not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1532              not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1533              not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1534              not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1535              int> = 0>
from_json(const BasicJsonType & j,ArithmeticType & val)1536 void from_json(const BasicJsonType& j, ArithmeticType& val)
1537 {
1538     switch (static_cast<value_t>(j))
1539     {
1540         case value_t::number_unsigned:
1541         {
1542             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1543             break;
1544         }
1545         case value_t::number_integer:
1546         {
1547             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1548             break;
1549         }
1550         case value_t::number_float:
1551         {
1552             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1553             break;
1554         }
1555         case value_t::boolean:
1556         {
1557             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1558             break;
1559         }
1560 
1561         default:
1562             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1563     }
1564 }
1565 
1566 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)1567 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1568 {
1569     p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1570 }
1571 
1572 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)1573 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
1574 {
1575     t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1576 }
1577 
1578 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)1579 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1580 {
1581     from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1582 }
1583 
1584 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
1585           typename = enable_if_t<not std::is_constructible<
1586                                      typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)1587 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1588 {
1589     if (JSON_UNLIKELY(not j.is_array()))
1590     {
1591         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1592     }
1593     for (const auto& p : j)
1594     {
1595         if (JSON_UNLIKELY(not p.is_array()))
1596         {
1597             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1598         }
1599         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1600     }
1601 }
1602 
1603 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
1604           typename = enable_if_t<not std::is_constructible<
1605                                      typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)1606 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1607 {
1608     if (JSON_UNLIKELY(not j.is_array()))
1609     {
1610         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1611     }
1612     for (const auto& p : j)
1613     {
1614         if (JSON_UNLIKELY(not p.is_array()))
1615         {
1616             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1617         }
1618         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1619     }
1620 }
1621 
1622 struct from_json_fn
1623 {
1624     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn1625     auto operator()(const BasicJsonType& j, T& val) const
1626     noexcept(noexcept(from_json(j, val)))
1627     -> decltype(from_json(j, val), void())
1628     {
1629         return from_json(j, val);
1630     }
1631 };
1632 }  // namespace detail
1633 
1634 /// namespace to hold default `from_json` function
1635 /// to see why this is required:
1636 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
1637 namespace
1638 {
1639 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1640 } // namespace
1641 }  // namespace nlohmann
1642 
1643 // #include <nlohmann/detail/conversions/to_json.hpp>
1644 
1645 
1646 #include <algorithm> // copy
1647 #include <ciso646> // or, and, not
1648 #include <iterator> // begin, end
1649 #include <string> // string
1650 #include <tuple> // tuple, get
1651 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1652 #include <utility> // move, forward, declval, pair
1653 #include <valarray> // valarray
1654 #include <vector> // vector
1655 
1656 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
1657 
1658 
1659 #include <cstddef> // size_t
1660 #include <iterator> // input_iterator_tag
1661 #include <string> // string, to_string
1662 #include <tuple> // tuple_size, get, tuple_element
1663 
1664 // #include <nlohmann/detail/meta/type_traits.hpp>
1665 
1666 // #include <nlohmann/detail/value_t.hpp>
1667 
1668 
1669 namespace nlohmann
1670 {
1671 namespace detail
1672 {
1673 template <typename IteratorType> class iteration_proxy_value
1674 {
1675   public:
1676     using difference_type = std::ptrdiff_t;
1677     using value_type = iteration_proxy_value;
1678     using pointer = value_type * ;
1679     using reference = value_type & ;
1680     using iterator_category = std::input_iterator_tag;
1681 
1682   private:
1683     /// the iterator
1684     IteratorType anchor;
1685     /// an index for arrays (used to create key names)
1686     std::size_t array_index = 0;
1687     /// last stringified array index
1688     mutable std::size_t array_index_last = 0;
1689     /// a string representation of the array index
1690     mutable std::string array_index_str = "0";
1691     /// an empty string (to return a reference for primitive values)
1692     const std::string empty_str = "";
1693 
1694   public:
iteration_proxy_value(IteratorType it)1695     explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
1696 
1697     /// dereference operator (needed for range-based for)
operator *()1698     iteration_proxy_value& operator*()
1699     {
1700         return *this;
1701     }
1702 
1703     /// increment operator (needed for range-based for)
operator ++()1704     iteration_proxy_value& operator++()
1705     {
1706         ++anchor;
1707         ++array_index;
1708 
1709         return *this;
1710     }
1711 
1712     /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_value & o) const1713     bool operator==(const iteration_proxy_value& o) const
1714     {
1715         return anchor == o.anchor;
1716     }
1717 
1718     /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_value & o) const1719     bool operator!=(const iteration_proxy_value& o) const
1720     {
1721         return anchor != o.anchor;
1722     }
1723 
1724     /// return key of the iterator
key() const1725     const std::string& key() const
1726     {
1727         assert(anchor.m_object != nullptr);
1728 
1729         switch (anchor.m_object->type())
1730         {
1731             // use integer array index as key
1732             case value_t::array:
1733             {
1734                 if (array_index != array_index_last)
1735                 {
1736                     array_index_str = std::to_string(array_index);
1737                     array_index_last = array_index;
1738                 }
1739                 return array_index_str;
1740             }
1741 
1742             // use key from the object
1743             case value_t::object:
1744                 return anchor.key();
1745 
1746             // use an empty key for all primitive types
1747             default:
1748                 return empty_str;
1749         }
1750     }
1751 
1752     /// return value of the iterator
value() const1753     typename IteratorType::reference value() const
1754     {
1755         return anchor.value();
1756     }
1757 };
1758 
1759 /// proxy class for the items() function
1760 template<typename IteratorType> class iteration_proxy
1761 {
1762   private:
1763     /// the container to iterate
1764     typename IteratorType::reference container;
1765 
1766   public:
1767     /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)1768     explicit iteration_proxy(typename IteratorType::reference cont) noexcept
1769         : container(cont) {}
1770 
1771     /// return iterator begin (needed for range-based for)
begin()1772     iteration_proxy_value<IteratorType> begin() noexcept
1773     {
1774         return iteration_proxy_value<IteratorType>(container.begin());
1775     }
1776 
1777     /// return iterator end (needed for range-based for)
end()1778     iteration_proxy_value<IteratorType> end() noexcept
1779     {
1780         return iteration_proxy_value<IteratorType>(container.end());
1781     }
1782 };
1783 // Structured Bindings Support
1784 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1785 // And see https://github.com/nlohmann/json/pull/1391
1786 template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)1787 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
1788 {
1789     return i.key();
1790 }
1791 // Structured Bindings Support
1792 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1793 // And see https://github.com/nlohmann/json/pull/1391
1794 template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)1795 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
1796 {
1797     return i.value();
1798 }
1799 }  // namespace detail
1800 }  // namespace nlohmann
1801 
1802 // The Addition to the STD Namespace is required to add
1803 // Structured Bindings Support to the iteration_proxy_value class
1804 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1805 // And see https://github.com/nlohmann/json/pull/1391
1806 namespace std
1807 {
1808 #if defined(__clang__)
1809     // Fix: https://github.com/nlohmann/json/issues/1401
1810     #pragma clang diagnostic push
1811     #pragma clang diagnostic ignored "-Wmismatched-tags"
1812 #endif
1813 template <typename IteratorType>
1814 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
1815             : public std::integral_constant<std::size_t, 2> {};
1816 
1817 template <std::size_t N, typename IteratorType>
1818 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
1819 {
1820   public:
1821     using type = decltype(
1822                      get<N>(std::declval <
1823                             ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
1824 };
1825 #if defined(__clang__)
1826     #pragma clang diagnostic pop
1827 #endif
1828 } // namespace std
1829 
1830 // #include <nlohmann/detail/meta/cpp_future.hpp>
1831 
1832 // #include <nlohmann/detail/meta/type_traits.hpp>
1833 
1834 // #include <nlohmann/detail/value_t.hpp>
1835 
1836 
1837 namespace nlohmann
1838 {
1839 namespace detail
1840 {
1841 //////////////////
1842 // constructors //
1843 //////////////////
1844 
1845 template<value_t> struct external_constructor;
1846 
1847 template<>
1848 struct external_constructor<value_t::boolean>
1849 {
1850     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1851     static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1852     {
1853         j.m_type = value_t::boolean;
1854         j.m_value = b;
1855         j.assert_invariant();
1856     }
1857 };
1858 
1859 template<>
1860 struct external_constructor<value_t::string>
1861 {
1862     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1863     static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1864     {
1865         j.m_type = value_t::string;
1866         j.m_value = s;
1867         j.assert_invariant();
1868     }
1869 
1870     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1871     static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1872     {
1873         j.m_type = value_t::string;
1874         j.m_value = std::move(s);
1875         j.assert_invariant();
1876     }
1877 
1878     template<typename BasicJsonType, typename CompatibleStringType,
1879              enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
1880                          int> = 0>
constructnlohmann::detail::external_constructor1881     static void construct(BasicJsonType& j, const CompatibleStringType& str)
1882     {
1883         j.m_type = value_t::string;
1884         j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1885         j.assert_invariant();
1886     }
1887 };
1888 
1889 template<>
1890 struct external_constructor<value_t::number_float>
1891 {
1892     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1893     static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1894     {
1895         j.m_type = value_t::number_float;
1896         j.m_value = val;
1897         j.assert_invariant();
1898     }
1899 };
1900 
1901 template<>
1902 struct external_constructor<value_t::number_unsigned>
1903 {
1904     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1905     static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1906     {
1907         j.m_type = value_t::number_unsigned;
1908         j.m_value = val;
1909         j.assert_invariant();
1910     }
1911 };
1912 
1913 template<>
1914 struct external_constructor<value_t::number_integer>
1915 {
1916     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1917     static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1918     {
1919         j.m_type = value_t::number_integer;
1920         j.m_value = val;
1921         j.assert_invariant();
1922     }
1923 };
1924 
1925 template<>
1926 struct external_constructor<value_t::array>
1927 {
1928     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1929     static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1930     {
1931         j.m_type = value_t::array;
1932         j.m_value = arr;
1933         j.assert_invariant();
1934     }
1935 
1936     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1937     static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1938     {
1939         j.m_type = value_t::array;
1940         j.m_value = std::move(arr);
1941         j.assert_invariant();
1942     }
1943 
1944     template<typename BasicJsonType, typename CompatibleArrayType,
1945              enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1946                          int> = 0>
constructnlohmann::detail::external_constructor1947     static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1948     {
1949         using std::begin;
1950         using std::end;
1951         j.m_type = value_t::array;
1952         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1953         j.assert_invariant();
1954     }
1955 
1956     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1957     static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1958     {
1959         j.m_type = value_t::array;
1960         j.m_value = value_t::array;
1961         j.m_value.array->reserve(arr.size());
1962         for (const bool x : arr)
1963         {
1964             j.m_value.array->push_back(x);
1965         }
1966         j.assert_invariant();
1967     }
1968 
1969     template<typename BasicJsonType, typename T,
1970              enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor1971     static void construct(BasicJsonType& j, const std::valarray<T>& arr)
1972     {
1973         j.m_type = value_t::array;
1974         j.m_value = value_t::array;
1975         j.m_value.array->resize(arr.size());
1976         std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1977         j.assert_invariant();
1978     }
1979 };
1980 
1981 template<>
1982 struct external_constructor<value_t::object>
1983 {
1984     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1985     static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1986     {
1987         j.m_type = value_t::object;
1988         j.m_value = obj;
1989         j.assert_invariant();
1990     }
1991 
1992     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1993     static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1994     {
1995         j.m_type = value_t::object;
1996         j.m_value = std::move(obj);
1997         j.assert_invariant();
1998     }
1999 
2000     template<typename BasicJsonType, typename CompatibleObjectType,
2001              enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
constructnlohmann::detail::external_constructor2002     static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
2003     {
2004         using std::begin;
2005         using std::end;
2006 
2007         j.m_type = value_t::object;
2008         j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
2009         j.assert_invariant();
2010     }
2011 };
2012 
2013 /////////////
2014 // to_json //
2015 /////////////
2016 
2017 template<typename BasicJsonType, typename T,
2018          enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)2019 void to_json(BasicJsonType& j, T b) noexcept
2020 {
2021     external_constructor<value_t::boolean>::construct(j, b);
2022 }
2023 
2024 template<typename BasicJsonType, typename CompatibleString,
2025          enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)2026 void to_json(BasicJsonType& j, const CompatibleString& s)
2027 {
2028     external_constructor<value_t::string>::construct(j, s);
2029 }
2030 
2031 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)2032 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
2033 {
2034     external_constructor<value_t::string>::construct(j, std::move(s));
2035 }
2036 
2037 template<typename BasicJsonType, typename FloatType,
2038          enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)2039 void to_json(BasicJsonType& j, FloatType val) noexcept
2040 {
2041     external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
2042 }
2043 
2044 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
2045          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)2046 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
2047 {
2048     external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
2049 }
2050 
2051 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
2052          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)2053 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
2054 {
2055     external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
2056 }
2057 
2058 template<typename BasicJsonType, typename EnumType,
2059          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)2060 void to_json(BasicJsonType& j, EnumType e) noexcept
2061 {
2062     using underlying_type = typename std::underlying_type<EnumType>::type;
2063     external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
2064 }
2065 
2066 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)2067 void to_json(BasicJsonType& j, const std::vector<bool>& e)
2068 {
2069     external_constructor<value_t::array>::construct(j, e);
2070 }
2071 
2072 template <typename BasicJsonType, typename CompatibleArrayType,
2073           enable_if_t<is_compatible_array_type<BasicJsonType,
2074                       CompatibleArrayType>::value and
2075                       not is_compatible_object_type<
2076                           BasicJsonType, CompatibleArrayType>::value and
2077                       not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
2078                       not is_basic_json<CompatibleArrayType>::value,
2079                       int> = 0>
to_json(BasicJsonType & j,const CompatibleArrayType & arr)2080 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
2081 {
2082     external_constructor<value_t::array>::construct(j, arr);
2083 }
2084 
2085 template<typename BasicJsonType, typename T,
2086          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)2087 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
2088 {
2089     external_constructor<value_t::array>::construct(j, std::move(arr));
2090 }
2091 
2092 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)2093 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
2094 {
2095     external_constructor<value_t::array>::construct(j, std::move(arr));
2096 }
2097 
2098 template<typename BasicJsonType, typename CompatibleObjectType,
2099          enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleObjectType & obj)2100 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
2101 {
2102     external_constructor<value_t::object>::construct(j, obj);
2103 }
2104 
2105 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)2106 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
2107 {
2108     external_constructor<value_t::object>::construct(j, std::move(obj));
2109 }
2110 
2111 template <
2112     typename BasicJsonType, typename T, std::size_t N,
2113     enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
2114                 const T(&)[N]>::value,
2115                 int> = 0 >
to_json(BasicJsonType & j,const T (& arr)[N])2116 void to_json(BasicJsonType& j, const T(&arr)[N])
2117 {
2118     external_constructor<value_t::array>::construct(j, arr);
2119 }
2120 
2121 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::pair<Args...> & p)2122 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
2123 {
2124     j = { p.first, p.second };
2125 }
2126 
2127 // for https://github.com/nlohmann/json/pull/1134
2128 template < typename BasicJsonType, typename T,
2129            enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
to_json(BasicJsonType & j,const T & b)2130 void to_json(BasicJsonType& j, const T& b)
2131 {
2132     j = { {b.key(), b.value()} };
2133 }
2134 
2135 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)2136 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
2137 {
2138     j = { std::get<Idx>(t)... };
2139 }
2140 
2141 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::tuple<Args...> & t)2142 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
2143 {
2144     to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
2145 }
2146 
2147 struct to_json_fn
2148 {
2149     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn2150     auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
2151     -> decltype(to_json(j, std::forward<T>(val)), void())
2152     {
2153         return to_json(j, std::forward<T>(val));
2154     }
2155 };
2156 }  // namespace detail
2157 
2158 /// namespace to hold default `to_json` function
2159 namespace
2160 {
2161 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
2162 } // namespace
2163 }  // namespace nlohmann
2164 
2165 
2166 namespace nlohmann
2167 {
2168 
2169 template<typename, typename>
2170 struct adl_serializer
2171 {
2172     /*!
2173     @brief convert a JSON value to any value type
2174 
2175     This function is usually called by the `get()` function of the
2176     @ref basic_json class (either explicit or via conversion operators).
2177 
2178     @param[in] j        JSON value to read from
2179     @param[in,out] val  value to write to
2180     */
2181     template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer2182     static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
2183         noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
2184     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
2185     {
2186         ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
2187     }
2188 
2189     /*!
2190     @brief convert any value type to a JSON value
2191 
2192     This function is usually called by the constructors of the @ref basic_json
2193     class.
2194 
2195     @param[in,out] j  JSON value to write to
2196     @param[in] val    value to read from
2197     */
2198     template <typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer2199     static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
2200         noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
2201     -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
2202     {
2203         ::nlohmann::to_json(j, std::forward<ValueType>(val));
2204     }
2205 };
2206 
2207 }  // namespace nlohmann
2208 
2209 // #include <nlohmann/detail/conversions/from_json.hpp>
2210 
2211 // #include <nlohmann/detail/conversions/to_json.hpp>
2212 
2213 // #include <nlohmann/detail/exceptions.hpp>
2214 
2215 // #include <nlohmann/detail/input/binary_reader.hpp>
2216 
2217 
2218 #include <algorithm> // generate_n
2219 #include <array> // array
2220 #include <cassert> // assert
2221 #include <cmath> // ldexp
2222 #include <cstddef> // size_t
2223 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
2224 #include <cstdio> // snprintf
2225 #include <cstring> // memcpy
2226 #include <iterator> // back_inserter
2227 #include <limits> // numeric_limits
2228 #include <string> // char_traits, string
2229 #include <utility> // make_pair, move
2230 
2231 // #include <nlohmann/detail/exceptions.hpp>
2232 
2233 // #include <nlohmann/detail/input/input_adapters.hpp>
2234 
2235 
2236 #include <array> // array
2237 #include <cassert> // assert
2238 #include <cstddef> // size_t
2239 #include <cstdio> //FILE *
2240 #include <cstring> // strlen
2241 #include <istream> // istream
2242 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
2243 #include <memory> // shared_ptr, make_shared, addressof
2244 #include <numeric> // accumulate
2245 #include <string> // string, char_traits
2246 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
2247 #include <utility> // pair, declval
2248 
2249 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2250 
2251 // #include <nlohmann/detail/macro_scope.hpp>
2252 
2253 
2254 namespace nlohmann
2255 {
2256 namespace detail
2257 {
2258 /// the supported input formats
2259 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
2260 
2261 ////////////////////
2262 // input adapters //
2263 ////////////////////
2264 
2265 /*!
2266 @brief abstract input adapter interface
2267 
2268 Produces a stream of std::char_traits<char>::int_type characters from a
2269 std::istream, a buffer, or some other input type. Accepts the return of
2270 exactly one non-EOF character for future input. The int_type characters
2271 returned consist of all valid char values as positive values (typically
2272 unsigned char), plus an EOF value outside that range, specified by the value
2273 of the function std::char_traits<char>::eof(). This value is typically -1, but
2274 could be any arbitrary value which is not a valid char value.
2275 */
2276 struct input_adapter_protocol
2277 {
2278     /// get a character [0,255] or std::char_traits<char>::eof().
2279     virtual std::char_traits<char>::int_type get_character() = 0;
2280     virtual ~input_adapter_protocol() = default;
2281 };
2282 
2283 /// a type to simplify interfaces
2284 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
2285 
2286 /*!
2287 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
2288  buffer. This adapter is a very low level adapter.
2289 */
2290 class file_input_adapter : public input_adapter_protocol
2291 {
2292   public:
file_input_adapter(std::FILE * f)2293     explicit file_input_adapter(std::FILE* f)  noexcept
2294         : m_file(f)
2295     {}
2296 
2297     // make class move-only
2298     file_input_adapter(const file_input_adapter&) = delete;
2299     file_input_adapter(file_input_adapter&&) = default;
2300     file_input_adapter& operator=(const file_input_adapter&) = delete;
2301     file_input_adapter& operator=(file_input_adapter&&) = default;
2302     ~file_input_adapter() override = default;
2303 
get_character()2304     std::char_traits<char>::int_type get_character() noexcept override
2305     {
2306         return std::fgetc(m_file);
2307     }
2308 
2309   private:
2310     /// the file pointer to read from
2311     std::FILE* m_file;
2312 };
2313 
2314 
2315 /*!
2316 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
2317 beginning of input. Does not support changing the underlying std::streambuf
2318 in mid-input. Maintains underlying std::istream and std::streambuf to support
2319 subsequent use of standard std::istream operations to process any input
2320 characters following those used in parsing the JSON input.  Clears the
2321 std::istream flags; any input errors (e.g., EOF) will be detected by the first
2322 subsequent call for input from the std::istream.
2323 */
2324 class input_stream_adapter : public input_adapter_protocol
2325 {
2326   public:
~input_stream_adapter()2327     ~input_stream_adapter() override
2328     {
2329         // clear stream flags; we use underlying streambuf I/O, do not
2330         // maintain ifstream flags, except eof
2331         is.clear(is.rdstate() & std::ios::eofbit);
2332     }
2333 
input_stream_adapter(std::istream & i)2334     explicit input_stream_adapter(std::istream& i)
2335         : is(i), sb(*i.rdbuf())
2336     {}
2337 
2338     // delete because of pointer members
2339     input_stream_adapter(const input_stream_adapter&) = delete;
2340     input_stream_adapter& operator=(input_stream_adapter&) = delete;
2341     input_stream_adapter(input_stream_adapter&&) = delete;
2342     input_stream_adapter& operator=(input_stream_adapter&&) = delete;
2343 
2344     // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
2345     // ensure that std::char_traits<char>::eof() and the character 0xFF do not
2346     // end up as the same value, eg. 0xFFFFFFFF.
get_character()2347     std::char_traits<char>::int_type get_character() override
2348     {
2349         auto res = sb.sbumpc();
2350         // set eof manually, as we don't use the istream interface.
2351         if (res == EOF)
2352         {
2353             is.clear(is.rdstate() | std::ios::eofbit);
2354         }
2355         return res;
2356     }
2357 
2358   private:
2359     /// the associated input stream
2360     std::istream& is;
2361     std::streambuf& sb;
2362 };
2363 
2364 /// input adapter for buffer input
2365 class input_buffer_adapter : public input_adapter_protocol
2366 {
2367   public:
input_buffer_adapter(const char * b,const std::size_t l)2368     input_buffer_adapter(const char* b, const std::size_t l) noexcept
2369         : cursor(b), limit(b + l)
2370     {}
2371 
2372     // delete because of pointer members
2373     input_buffer_adapter(const input_buffer_adapter&) = delete;
2374     input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
2375     input_buffer_adapter(input_buffer_adapter&&) = delete;
2376     input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
2377     ~input_buffer_adapter() override = default;
2378 
get_character()2379     std::char_traits<char>::int_type get_character() noexcept override
2380     {
2381         if (JSON_LIKELY(cursor < limit))
2382         {
2383             return std::char_traits<char>::to_int_type(*(cursor++));
2384         }
2385 
2386         return std::char_traits<char>::eof();
2387     }
2388 
2389   private:
2390     /// pointer to the current character
2391     const char* cursor;
2392     /// pointer past the last character
2393     const char* const limit;
2394 };
2395 
2396 template<typename WideStringType, size_t T>
2397 struct wide_string_input_helper
2398 {
2399     // UTF-32
fill_buffernlohmann::detail::wide_string_input_helper2400     static void fill_buffer(const WideStringType& str,
2401                             size_t& current_wchar,
2402                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2403                             size_t& utf8_bytes_index,
2404                             size_t& utf8_bytes_filled)
2405     {
2406         utf8_bytes_index = 0;
2407 
2408         if (current_wchar == str.size())
2409         {
2410             utf8_bytes[0] = std::char_traits<char>::eof();
2411             utf8_bytes_filled = 1;
2412         }
2413         else
2414         {
2415             // get the current character
2416             const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2417 
2418             // UTF-32 to UTF-8 encoding
2419             if (wc < 0x80)
2420             {
2421                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2422                 utf8_bytes_filled = 1;
2423             }
2424             else if (wc <= 0x7FF)
2425             {
2426                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
2427                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2428                 utf8_bytes_filled = 2;
2429             }
2430             else if (wc <= 0xFFFF)
2431             {
2432                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
2433                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2434                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2435                 utf8_bytes_filled = 3;
2436             }
2437             else if (wc <= 0x10FFFF)
2438             {
2439                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
2440                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
2441                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2442                 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2443                 utf8_bytes_filled = 4;
2444             }
2445             else
2446             {
2447                 // unknown character
2448                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2449                 utf8_bytes_filled = 1;
2450             }
2451         }
2452     }
2453 };
2454 
2455 template<typename WideStringType>
2456 struct wide_string_input_helper<WideStringType, 2>
2457 {
2458     // UTF-16
fill_buffernlohmann::detail::wide_string_input_helper2459     static void fill_buffer(const WideStringType& str,
2460                             size_t& current_wchar,
2461                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2462                             size_t& utf8_bytes_index,
2463                             size_t& utf8_bytes_filled)
2464     {
2465         utf8_bytes_index = 0;
2466 
2467         if (current_wchar == str.size())
2468         {
2469             utf8_bytes[0] = std::char_traits<char>::eof();
2470             utf8_bytes_filled = 1;
2471         }
2472         else
2473         {
2474             // get the current character
2475             const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2476 
2477             // UTF-16 to UTF-8 encoding
2478             if (wc < 0x80)
2479             {
2480                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2481                 utf8_bytes_filled = 1;
2482             }
2483             else if (wc <= 0x7FF)
2484             {
2485                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
2486                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2487                 utf8_bytes_filled = 2;
2488             }
2489             else if (0xD800 > wc or wc >= 0xE000)
2490             {
2491                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
2492                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2493                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2494                 utf8_bytes_filled = 3;
2495             }
2496             else
2497             {
2498                 if (current_wchar < str.size())
2499                 {
2500                     const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
2501                     const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
2502                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
2503                     utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
2504                     utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
2505                     utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
2506                     utf8_bytes_filled = 4;
2507                 }
2508                 else
2509                 {
2510                     // unknown character
2511                     ++current_wchar;
2512                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2513                     utf8_bytes_filled = 1;
2514                 }
2515             }
2516         }
2517     }
2518 };
2519 
2520 template<typename WideStringType>
2521 class wide_string_input_adapter : public input_adapter_protocol
2522 {
2523   public:
wide_string_input_adapter(const WideStringType & w)2524     explicit wide_string_input_adapter(const WideStringType& w) noexcept
2525         : str(w)
2526     {}
2527 
get_character()2528     std::char_traits<char>::int_type get_character() noexcept override
2529     {
2530         // check if buffer needs to be filled
2531         if (utf8_bytes_index == utf8_bytes_filled)
2532         {
2533             fill_buffer<sizeof(typename WideStringType::value_type)>();
2534 
2535             assert(utf8_bytes_filled > 0);
2536             assert(utf8_bytes_index == 0);
2537         }
2538 
2539         // use buffer
2540         assert(utf8_bytes_filled > 0);
2541         assert(utf8_bytes_index < utf8_bytes_filled);
2542         return utf8_bytes[utf8_bytes_index++];
2543     }
2544 
2545   private:
2546     template<size_t T>
fill_buffer()2547     void fill_buffer()
2548     {
2549         wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2550     }
2551 
2552     /// the wstring to process
2553     const WideStringType& str;
2554 
2555     /// index of the current wchar in str
2556     std::size_t current_wchar = 0;
2557 
2558     /// a buffer for UTF-8 bytes
2559     std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2560 
2561     /// index to the utf8_codes array for the next valid byte
2562     std::size_t utf8_bytes_index = 0;
2563     /// number of valid bytes in the utf8_codes array
2564     std::size_t utf8_bytes_filled = 0;
2565 };
2566 
2567 class input_adapter
2568 {
2569   public:
2570     // native support
input_adapter(std::FILE * file)2571     input_adapter(std::FILE* file)
2572         : ia(std::make_shared<file_input_adapter>(file)) {}
2573     /// input adapter for input stream
input_adapter(std::istream & i)2574     input_adapter(std::istream& i)
2575         : ia(std::make_shared<input_stream_adapter>(i)) {}
2576 
2577     /// input adapter for input stream
input_adapter(std::istream && i)2578     input_adapter(std::istream&& i)
2579         : ia(std::make_shared<input_stream_adapter>(i)) {}
2580 
input_adapter(const std::wstring & ws)2581     input_adapter(const std::wstring& ws)
2582         : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2583 
input_adapter(const std::u16string & ws)2584     input_adapter(const std::u16string& ws)
2585         : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2586 
input_adapter(const std::u32string & ws)2587     input_adapter(const std::u32string& ws)
2588         : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2589 
2590     /// input adapter for buffer
2591     template<typename CharT,
2592              typename std::enable_if<
2593                  std::is_pointer<CharT>::value and
2594                  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2595                  sizeof(typename std::remove_pointer<CharT>::type) == 1,
2596                  int>::type = 0>
input_adapter(CharT b,std::size_t l)2597     input_adapter(CharT b, std::size_t l)
2598         : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2599 
2600     // derived support
2601 
2602     /// input adapter for string literal
2603     template<typename CharT,
2604              typename std::enable_if<
2605                  std::is_pointer<CharT>::value and
2606                  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2607                  sizeof(typename std::remove_pointer<CharT>::type) == 1,
2608                  int>::type = 0>
input_adapter(CharT b)2609     input_adapter(CharT b)
2610         : input_adapter(reinterpret_cast<const char*>(b),
2611                         std::strlen(reinterpret_cast<const char*>(b))) {}
2612 
2613     /// input adapter for iterator range with contiguous storage
2614     template<class IteratorType,
2615              typename std::enable_if<
2616                  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2617                  int>::type = 0>
input_adapter(IteratorType first,IteratorType last)2618     input_adapter(IteratorType first, IteratorType last)
2619     {
2620 #ifndef NDEBUG
2621         // assertion to check that the iterator range is indeed contiguous,
2622         // see http://stackoverflow.com/a/35008842/266378 for more discussion
2623         const auto is_contiguous = std::accumulate(
2624                                        first, last, std::pair<bool, int>(true, 0),
2625                                        [&first](std::pair<bool, int> res, decltype(*first) val)
2626         {
2627             res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2628             return res;
2629         }).first;
2630         assert(is_contiguous);
2631 #endif
2632 
2633         // assertion to check that each element is 1 byte long
2634         static_assert(
2635             sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
2636             "each element in the iterator range must have the size of 1 byte");
2637 
2638         const auto len = static_cast<size_t>(std::distance(first, last));
2639         if (JSON_LIKELY(len > 0))
2640         {
2641             // there is at least one element: use the address of first
2642             ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2643         }
2644         else
2645         {
2646             // the address of first cannot be used: use nullptr
2647             ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2648         }
2649     }
2650 
2651     /// input adapter for array
2652     template<class T, std::size_t N>
input_adapter(T (& array)[N])2653     input_adapter(T (&array)[N])
2654         : input_adapter(std::begin(array), std::end(array)) {}
2655 
2656     /// input adapter for contiguous container
2657     template<class ContiguousContainer, typename
2658              std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2659                             std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2660                             int>::type = 0>
input_adapter(const ContiguousContainer & c)2661     input_adapter(const ContiguousContainer& c)
2662         : input_adapter(std::begin(c), std::end(c)) {}
2663 
operator input_adapter_t()2664     operator input_adapter_t()
2665     {
2666         return ia;
2667     }
2668 
2669   private:
2670     /// the actual adapter
2671     input_adapter_t ia = nullptr;
2672 };
2673 }  // namespace detail
2674 }  // namespace nlohmann
2675 
2676 // #include <nlohmann/detail/input/json_sax.hpp>
2677 
2678 
2679 #include <cassert> // assert
2680 #include <cstddef>
2681 #include <string> // string
2682 #include <utility> // move
2683 #include <vector> // vector
2684 
2685 // #include <nlohmann/detail/exceptions.hpp>
2686 
2687 // #include <nlohmann/detail/macro_scope.hpp>
2688 
2689 
2690 namespace nlohmann
2691 {
2692 
2693 /*!
2694 @brief SAX interface
2695 
2696 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
2697 Each function is called in different situations while the input is parsed. The
2698 boolean return value informs the parser whether to continue processing the
2699 input.
2700 */
2701 template<typename BasicJsonType>
2702 struct json_sax
2703 {
2704     /// type for (signed) integers
2705     using number_integer_t = typename BasicJsonType::number_integer_t;
2706     /// type for unsigned integers
2707     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2708     /// type for floating-point numbers
2709     using number_float_t = typename BasicJsonType::number_float_t;
2710     /// type for strings
2711     using string_t = typename BasicJsonType::string_t;
2712 
2713     /*!
2714     @brief a null value was read
2715     @return whether parsing should proceed
2716     */
2717     virtual bool null() = 0;
2718 
2719     /*!
2720     @brief a boolean value was read
2721     @param[in] val  boolean value
2722     @return whether parsing should proceed
2723     */
2724     virtual bool boolean(bool val) = 0;
2725 
2726     /*!
2727     @brief an integer number was read
2728     @param[in] val  integer value
2729     @return whether parsing should proceed
2730     */
2731     virtual bool number_integer(number_integer_t val) = 0;
2732 
2733     /*!
2734     @brief an unsigned integer number was read
2735     @param[in] val  unsigned integer value
2736     @return whether parsing should proceed
2737     */
2738     virtual bool number_unsigned(number_unsigned_t val) = 0;
2739 
2740     /*!
2741     @brief an floating-point number was read
2742     @param[in] val  floating-point value
2743     @param[in] s    raw token value
2744     @return whether parsing should proceed
2745     */
2746     virtual bool number_float(number_float_t val, const string_t& s) = 0;
2747 
2748     /*!
2749     @brief a string was read
2750     @param[in] val  string value
2751     @return whether parsing should proceed
2752     @note It is safe to move the passed string.
2753     */
2754     virtual bool string(string_t& val) = 0;
2755 
2756     /*!
2757     @brief the beginning of an object was read
2758     @param[in] elements  number of object elements or -1 if unknown
2759     @return whether parsing should proceed
2760     @note binary formats may report the number of elements
2761     */
2762     virtual bool start_object(std::size_t elements) = 0;
2763 
2764     /*!
2765     @brief an object key was read
2766     @param[in] val  object key
2767     @return whether parsing should proceed
2768     @note It is safe to move the passed string.
2769     */
2770     virtual bool key(string_t& val) = 0;
2771 
2772     /*!
2773     @brief the end of an object was read
2774     @return whether parsing should proceed
2775     */
2776     virtual bool end_object() = 0;
2777 
2778     /*!
2779     @brief the beginning of an array was read
2780     @param[in] elements  number of array elements or -1 if unknown
2781     @return whether parsing should proceed
2782     @note binary formats may report the number of elements
2783     */
2784     virtual bool start_array(std::size_t elements) = 0;
2785 
2786     /*!
2787     @brief the end of an array was read
2788     @return whether parsing should proceed
2789     */
2790     virtual bool end_array() = 0;
2791 
2792     /*!
2793     @brief a parse error occurred
2794     @param[in] position    the position in the input where the error occurs
2795     @param[in] last_token  the last read token
2796     @param[in] ex          an exception object describing the error
2797     @return whether parsing should proceed (must return false)
2798     */
2799     virtual bool parse_error(std::size_t position,
2800                              const std::string& last_token,
2801                              const detail::exception& ex) = 0;
2802 
2803     virtual ~json_sax() = default;
2804 };
2805 
2806 
2807 namespace detail
2808 {
2809 /*!
2810 @brief SAX implementation to create a JSON value from SAX events
2811 
2812 This class implements the @ref json_sax interface and processes the SAX events
2813 to create a JSON value which makes it basically a DOM parser. The structure or
2814 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
2815 a pointer to the respective array or object for each recursion depth.
2816 
2817 After successful parsing, the value that is passed by reference to the
2818 constructor contains the parsed value.
2819 
2820 @tparam BasicJsonType  the JSON type
2821 */
2822 template<typename BasicJsonType>
2823 class json_sax_dom_parser
2824 {
2825   public:
2826     using number_integer_t = typename BasicJsonType::number_integer_t;
2827     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2828     using number_float_t = typename BasicJsonType::number_float_t;
2829     using string_t = typename BasicJsonType::string_t;
2830 
2831     /*!
2832     @param[in, out] r  reference to a JSON value that is manipulated while
2833                        parsing
2834     @param[in] allow_exceptions_  whether parse errors yield exceptions
2835     */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)2836     explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
2837         : root(r), allow_exceptions(allow_exceptions_)
2838     {}
2839 
2840     // make class move-only
2841     json_sax_dom_parser(const json_sax_dom_parser&) = delete;
2842     json_sax_dom_parser(json_sax_dom_parser&&) = default;
2843     json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
2844     json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
2845     ~json_sax_dom_parser() = default;
2846 
null()2847     bool null()
2848     {
2849         handle_value(nullptr);
2850         return true;
2851     }
2852 
boolean(bool val)2853     bool boolean(bool val)
2854     {
2855         handle_value(val);
2856         return true;
2857     }
2858 
number_integer(number_integer_t val)2859     bool number_integer(number_integer_t val)
2860     {
2861         handle_value(val);
2862         return true;
2863     }
2864 
number_unsigned(number_unsigned_t val)2865     bool number_unsigned(number_unsigned_t val)
2866     {
2867         handle_value(val);
2868         return true;
2869     }
2870 
number_float(number_float_t val,const string_t &)2871     bool number_float(number_float_t val, const string_t& /*unused*/)
2872     {
2873         handle_value(val);
2874         return true;
2875     }
2876 
string(string_t & val)2877     bool string(string_t& val)
2878     {
2879         handle_value(val);
2880         return true;
2881     }
2882 
start_object(std::size_t len)2883     bool start_object(std::size_t len)
2884     {
2885         ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
2886 
2887         if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2888         {
2889             JSON_THROW(out_of_range::create(408,
2890                                             "excessive object size: " + std::to_string(len)));
2891         }
2892 
2893         return true;
2894     }
2895 
key(string_t & val)2896     bool key(string_t& val)
2897     {
2898         // add null at given key and store the reference for later
2899         object_element = &(ref_stack.back()->m_value.object->operator[](val));
2900         return true;
2901     }
2902 
end_object()2903     bool end_object()
2904     {
2905         ref_stack.pop_back();
2906         return true;
2907     }
2908 
start_array(std::size_t len)2909     bool start_array(std::size_t len)
2910     {
2911         ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
2912 
2913         if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2914         {
2915             JSON_THROW(out_of_range::create(408,
2916                                             "excessive array size: " + std::to_string(len)));
2917         }
2918 
2919         return true;
2920     }
2921 
end_array()2922     bool end_array()
2923     {
2924         ref_stack.pop_back();
2925         return true;
2926     }
2927 
parse_error(std::size_t,const std::string &,const detail::exception & ex)2928     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
2929                      const detail::exception& ex)
2930     {
2931         errored = true;
2932         if (allow_exceptions)
2933         {
2934             // determine the proper exception type from the id
2935             switch ((ex.id / 100) % 100)
2936             {
2937                 case 1:
2938                     JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
2939                 case 4:
2940                     JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
2941                 // LCOV_EXCL_START
2942                 case 2:
2943                     JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
2944                 case 3:
2945                     JSON_THROW(*static_cast<const detail::type_error*>(&ex));
2946                 case 5:
2947                     JSON_THROW(*static_cast<const detail::other_error*>(&ex));
2948                 default:
2949                     assert(false);
2950                     // LCOV_EXCL_STOP
2951             }
2952         }
2953         return false;
2954     }
2955 
is_errored() const2956     constexpr bool is_errored() const
2957     {
2958         return errored;
2959     }
2960 
2961   private:
2962     /*!
2963     @invariant If the ref stack is empty, then the passed value will be the new
2964                root.
2965     @invariant If the ref stack contains a value, then it is an array or an
2966                object to which we can add elements
2967     */
2968     template<typename Value>
handle_value(Value && v)2969     BasicJsonType* handle_value(Value&& v)
2970     {
2971         if (ref_stack.empty())
2972         {
2973             root = BasicJsonType(std::forward<Value>(v));
2974             return &root;
2975         }
2976 
2977         assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
2978 
2979         if (ref_stack.back()->is_array())
2980         {
2981             ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
2982             return &(ref_stack.back()->m_value.array->back());
2983         }
2984 
2985         assert(ref_stack.back()->is_object());
2986         assert(object_element);
2987         *object_element = BasicJsonType(std::forward<Value>(v));
2988         return object_element;
2989     }
2990 
2991     /// the parsed JSON value
2992     BasicJsonType& root;
2993     /// stack to model hierarchy of values
2994     std::vector<BasicJsonType*> ref_stack {};
2995     /// helper to hold the reference for the next object element
2996     BasicJsonType* object_element = nullptr;
2997     /// whether a syntax error occurred
2998     bool errored = false;
2999     /// whether to throw exceptions in case of errors
3000     const bool allow_exceptions = true;
3001 };
3002 
3003 template<typename BasicJsonType>
3004 class json_sax_dom_callback_parser
3005 {
3006   public:
3007     using number_integer_t = typename BasicJsonType::number_integer_t;
3008     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3009     using number_float_t = typename BasicJsonType::number_float_t;
3010     using string_t = typename BasicJsonType::string_t;
3011     using parser_callback_t = typename BasicJsonType::parser_callback_t;
3012     using parse_event_t = typename BasicJsonType::parse_event_t;
3013 
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)3014     json_sax_dom_callback_parser(BasicJsonType& r,
3015                                  const parser_callback_t cb,
3016                                  const bool allow_exceptions_ = true)
3017         : root(r), callback(cb), allow_exceptions(allow_exceptions_)
3018     {
3019         keep_stack.push_back(true);
3020     }
3021 
3022     // make class move-only
3023     json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
3024     json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
3025     json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
3026     json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
3027     ~json_sax_dom_callback_parser() = default;
3028 
null()3029     bool null()
3030     {
3031         handle_value(nullptr);
3032         return true;
3033     }
3034 
boolean(bool val)3035     bool boolean(bool val)
3036     {
3037         handle_value(val);
3038         return true;
3039     }
3040 
number_integer(number_integer_t val)3041     bool number_integer(number_integer_t val)
3042     {
3043         handle_value(val);
3044         return true;
3045     }
3046 
number_unsigned(number_unsigned_t val)3047     bool number_unsigned(number_unsigned_t val)
3048     {
3049         handle_value(val);
3050         return true;
3051     }
3052 
number_float(number_float_t val,const string_t &)3053     bool number_float(number_float_t val, const string_t& /*unused*/)
3054     {
3055         handle_value(val);
3056         return true;
3057     }
3058 
string(string_t & val)3059     bool string(string_t& val)
3060     {
3061         handle_value(val);
3062         return true;
3063     }
3064 
start_object(std::size_t len)3065     bool start_object(std::size_t len)
3066     {
3067         // check callback for object start
3068         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
3069         keep_stack.push_back(keep);
3070 
3071         auto val = handle_value(BasicJsonType::value_t::object, true);
3072         ref_stack.push_back(val.second);
3073 
3074         // check object limit
3075         if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3076         {
3077             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
3078         }
3079 
3080         return true;
3081     }
3082 
key(string_t & val)3083     bool key(string_t& val)
3084     {
3085         BasicJsonType k = BasicJsonType(val);
3086 
3087         // check callback for key
3088         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
3089         key_keep_stack.push_back(keep);
3090 
3091         // add discarded value at given key and store the reference for later
3092         if (keep and ref_stack.back())
3093         {
3094             object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
3095         }
3096 
3097         return true;
3098     }
3099 
end_object()3100     bool end_object()
3101     {
3102         if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
3103         {
3104             // discard object
3105             *ref_stack.back() = discarded;
3106         }
3107 
3108         assert(not ref_stack.empty());
3109         assert(not keep_stack.empty());
3110         ref_stack.pop_back();
3111         keep_stack.pop_back();
3112 
3113         if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
3114         {
3115             // remove discarded value
3116             for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
3117             {
3118                 if (it->is_discarded())
3119                 {
3120                     ref_stack.back()->erase(it);
3121                     break;
3122                 }
3123             }
3124         }
3125 
3126         return true;
3127     }
3128 
start_array(std::size_t len)3129     bool start_array(std::size_t len)
3130     {
3131         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
3132         keep_stack.push_back(keep);
3133 
3134         auto val = handle_value(BasicJsonType::value_t::array, true);
3135         ref_stack.push_back(val.second);
3136 
3137         // check array limit
3138         if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3139         {
3140             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
3141         }
3142 
3143         return true;
3144     }
3145 
end_array()3146     bool end_array()
3147     {
3148         bool keep = true;
3149 
3150         if (ref_stack.back())
3151         {
3152             keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
3153             if (not keep)
3154             {
3155                 // discard array
3156                 *ref_stack.back() = discarded;
3157             }
3158         }
3159 
3160         assert(not ref_stack.empty());
3161         assert(not keep_stack.empty());
3162         ref_stack.pop_back();
3163         keep_stack.pop_back();
3164 
3165         // remove discarded value
3166         if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
3167         {
3168             ref_stack.back()->m_value.array->pop_back();
3169         }
3170 
3171         return true;
3172     }
3173 
parse_error(std::size_t,const std::string &,const detail::exception & ex)3174     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
3175                      const detail::exception& ex)
3176     {
3177         errored = true;
3178         if (allow_exceptions)
3179         {
3180             // determine the proper exception type from the id
3181             switch ((ex.id / 100) % 100)
3182             {
3183                 case 1:
3184                     JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
3185                 case 4:
3186                     JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
3187                 // LCOV_EXCL_START
3188                 case 2:
3189                     JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
3190                 case 3:
3191                     JSON_THROW(*static_cast<const detail::type_error*>(&ex));
3192                 case 5:
3193                     JSON_THROW(*static_cast<const detail::other_error*>(&ex));
3194                 default:
3195                     assert(false);
3196                     // LCOV_EXCL_STOP
3197             }
3198         }
3199         return false;
3200     }
3201 
is_errored() const3202     constexpr bool is_errored() const
3203     {
3204         return errored;
3205     }
3206 
3207   private:
3208     /*!
3209     @param[in] v  value to add to the JSON value we build during parsing
3210     @param[in] skip_callback  whether we should skip calling the callback
3211                function; this is required after start_array() and
3212                start_object() SAX events, because otherwise we would call the
3213                callback function with an empty array or object, respectively.
3214 
3215     @invariant If the ref stack is empty, then the passed value will be the new
3216                root.
3217     @invariant If the ref stack contains a value, then it is an array or an
3218                object to which we can add elements
3219 
3220     @return pair of boolean (whether value should be kept) and pointer (to the
3221             passed value in the ref_stack hierarchy; nullptr if not kept)
3222     */
3223     template<typename Value>
handle_value(Value && v,const bool skip_callback=false)3224     std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
3225     {
3226         assert(not keep_stack.empty());
3227 
3228         // do not handle this value if we know it would be added to a discarded
3229         // container
3230         if (not keep_stack.back())
3231         {
3232             return {false, nullptr};
3233         }
3234 
3235         // create value
3236         auto value = BasicJsonType(std::forward<Value>(v));
3237 
3238         // check callback
3239         const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
3240 
3241         // do not handle this value if we just learnt it shall be discarded
3242         if (not keep)
3243         {
3244             return {false, nullptr};
3245         }
3246 
3247         if (ref_stack.empty())
3248         {
3249             root = std::move(value);
3250             return {true, &root};
3251         }
3252 
3253         // skip this value if we already decided to skip the parent
3254         // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
3255         if (not ref_stack.back())
3256         {
3257             return {false, nullptr};
3258         }
3259 
3260         // we now only expect arrays and objects
3261         assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
3262 
3263         // array
3264         if (ref_stack.back()->is_array())
3265         {
3266             ref_stack.back()->m_value.array->push_back(std::move(value));
3267             return {true, &(ref_stack.back()->m_value.array->back())};
3268         }
3269 
3270         // object
3271         assert(ref_stack.back()->is_object());
3272         // check if we should store an element for the current key
3273         assert(not key_keep_stack.empty());
3274         const bool store_element = key_keep_stack.back();
3275         key_keep_stack.pop_back();
3276 
3277         if (not store_element)
3278         {
3279             return {false, nullptr};
3280         }
3281 
3282         assert(object_element);
3283         *object_element = std::move(value);
3284         return {true, object_element};
3285     }
3286 
3287     /// the parsed JSON value
3288     BasicJsonType& root;
3289     /// stack to model hierarchy of values
3290     std::vector<BasicJsonType*> ref_stack {};
3291     /// stack to manage which values to keep
3292     std::vector<bool> keep_stack {};
3293     /// stack to manage which object keys to keep
3294     std::vector<bool> key_keep_stack {};
3295     /// helper to hold the reference for the next object element
3296     BasicJsonType* object_element = nullptr;
3297     /// whether a syntax error occurred
3298     bool errored = false;
3299     /// callback function
3300     const parser_callback_t callback = nullptr;
3301     /// whether to throw exceptions in case of errors
3302     const bool allow_exceptions = true;
3303     /// a discarded value for the callback
3304     BasicJsonType discarded = BasicJsonType::value_t::discarded;
3305 };
3306 
3307 template<typename BasicJsonType>
3308 class json_sax_acceptor
3309 {
3310   public:
3311     using number_integer_t = typename BasicJsonType::number_integer_t;
3312     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3313     using number_float_t = typename BasicJsonType::number_float_t;
3314     using string_t = typename BasicJsonType::string_t;
3315 
null()3316     bool null()
3317     {
3318         return true;
3319     }
3320 
boolean(bool)3321     bool boolean(bool /*unused*/)
3322     {
3323         return true;
3324     }
3325 
number_integer(number_integer_t)3326     bool number_integer(number_integer_t /*unused*/)
3327     {
3328         return true;
3329     }
3330 
number_unsigned(number_unsigned_t)3331     bool number_unsigned(number_unsigned_t /*unused*/)
3332     {
3333         return true;
3334     }
3335 
number_float(number_float_t,const string_t &)3336     bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
3337     {
3338         return true;
3339     }
3340 
string(string_t &)3341     bool string(string_t& /*unused*/)
3342     {
3343         return true;
3344     }
3345 
start_object(std::size_t=std::size_t (-1))3346     bool start_object(std::size_t  /*unused*/ = std::size_t(-1))
3347     {
3348         return true;
3349     }
3350 
key(string_t &)3351     bool key(string_t& /*unused*/)
3352     {
3353         return true;
3354     }
3355 
end_object()3356     bool end_object()
3357     {
3358         return true;
3359     }
3360 
start_array(std::size_t=std::size_t (-1))3361     bool start_array(std::size_t  /*unused*/ = std::size_t(-1))
3362     {
3363         return true;
3364     }
3365 
end_array()3366     bool end_array()
3367     {
3368         return true;
3369     }
3370 
parse_error(std::size_t,const std::string &,const detail::exception &)3371     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
3372     {
3373         return false;
3374     }
3375 };
3376 }  // namespace detail
3377 
3378 }  // namespace nlohmann
3379 
3380 // #include <nlohmann/detail/macro_scope.hpp>
3381 
3382 // #include <nlohmann/detail/meta/is_sax.hpp>
3383 
3384 
3385 #include <cstdint> // size_t
3386 #include <utility> // declval
3387 #include <string> // string
3388 
3389 // #include <nlohmann/detail/meta/detected.hpp>
3390 
3391 // #include <nlohmann/detail/meta/type_traits.hpp>
3392 
3393 
3394 namespace nlohmann
3395 {
3396 namespace detail
3397 {
3398 template <typename T>
3399 using null_function_t = decltype(std::declval<T&>().null());
3400 
3401 template <typename T>
3402 using boolean_function_t =
3403     decltype(std::declval<T&>().boolean(std::declval<bool>()));
3404 
3405 template <typename T, typename Integer>
3406 using number_integer_function_t =
3407     decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3408 
3409 template <typename T, typename Unsigned>
3410 using number_unsigned_function_t =
3411     decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3412 
3413 template <typename T, typename Float, typename String>
3414 using number_float_function_t = decltype(std::declval<T&>().number_float(
3415                                     std::declval<Float>(), std::declval<const String&>()));
3416 
3417 template <typename T, typename String>
3418 using string_function_t =
3419     decltype(std::declval<T&>().string(std::declval<String&>()));
3420 
3421 template <typename T>
3422 using start_object_function_t =
3423     decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
3424 
3425 template <typename T, typename String>
3426 using key_function_t =
3427     decltype(std::declval<T&>().key(std::declval<String&>()));
3428 
3429 template <typename T>
3430 using end_object_function_t = decltype(std::declval<T&>().end_object());
3431 
3432 template <typename T>
3433 using start_array_function_t =
3434     decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
3435 
3436 template <typename T>
3437 using end_array_function_t = decltype(std::declval<T&>().end_array());
3438 
3439 template <typename T, typename Exception>
3440 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
3441         std::declval<std::size_t>(), std::declval<const std::string&>(),
3442         std::declval<const Exception&>()));
3443 
3444 template <typename SAX, typename BasicJsonType>
3445 struct is_sax
3446 {
3447   private:
3448     static_assert(is_basic_json<BasicJsonType>::value,
3449                   "BasicJsonType must be of type basic_json<...>");
3450 
3451     using number_integer_t = typename BasicJsonType::number_integer_t;
3452     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3453     using number_float_t = typename BasicJsonType::number_float_t;
3454     using string_t = typename BasicJsonType::string_t;
3455     using exception_t = typename BasicJsonType::exception;
3456 
3457   public:
3458     static constexpr bool value =
3459         is_detected_exact<bool, null_function_t, SAX>::value &&
3460         is_detected_exact<bool, boolean_function_t, SAX>::value &&
3461         is_detected_exact<bool, number_integer_function_t, SAX,
3462         number_integer_t>::value &&
3463         is_detected_exact<bool, number_unsigned_function_t, SAX,
3464         number_unsigned_t>::value &&
3465         is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
3466         string_t>::value &&
3467         is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
3468         is_detected_exact<bool, start_object_function_t, SAX>::value &&
3469         is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
3470         is_detected_exact<bool, end_object_function_t, SAX>::value &&
3471         is_detected_exact<bool, start_array_function_t, SAX>::value &&
3472         is_detected_exact<bool, end_array_function_t, SAX>::value &&
3473         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
3474 };
3475 
3476 template <typename SAX, typename BasicJsonType>
3477 struct is_sax_static_asserts
3478 {
3479   private:
3480     static_assert(is_basic_json<BasicJsonType>::value,
3481                   "BasicJsonType must be of type basic_json<...>");
3482 
3483     using number_integer_t = typename BasicJsonType::number_integer_t;
3484     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3485     using number_float_t = typename BasicJsonType::number_float_t;
3486     using string_t = typename BasicJsonType::string_t;
3487     using exception_t = typename BasicJsonType::exception;
3488 
3489   public:
3490     static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
3491                   "Missing/invalid function: bool null()");
3492     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3493                   "Missing/invalid function: bool boolean(bool)");
3494     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3495                   "Missing/invalid function: bool boolean(bool)");
3496     static_assert(
3497         is_detected_exact<bool, number_integer_function_t, SAX,
3498         number_integer_t>::value,
3499         "Missing/invalid function: bool number_integer(number_integer_t)");
3500     static_assert(
3501         is_detected_exact<bool, number_unsigned_function_t, SAX,
3502         number_unsigned_t>::value,
3503         "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
3504     static_assert(is_detected_exact<bool, number_float_function_t, SAX,
3505                   number_float_t, string_t>::value,
3506                   "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
3507     static_assert(
3508         is_detected_exact<bool, string_function_t, SAX, string_t>::value,
3509         "Missing/invalid function: bool string(string_t&)");
3510     static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
3511                   "Missing/invalid function: bool start_object(std::size_t)");
3512     static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
3513                   "Missing/invalid function: bool key(string_t&)");
3514     static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
3515                   "Missing/invalid function: bool end_object()");
3516     static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
3517                   "Missing/invalid function: bool start_array(std::size_t)");
3518     static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
3519                   "Missing/invalid function: bool end_array()");
3520     static_assert(
3521         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
3522         "Missing/invalid function: bool parse_error(std::size_t, const "
3523         "std::string&, const exception&)");
3524 };
3525 }  // namespace detail
3526 }  // namespace nlohmann
3527 
3528 // #include <nlohmann/detail/value_t.hpp>
3529 
3530 
3531 namespace nlohmann
3532 {
3533 namespace detail
3534 {
3535 ///////////////////
3536 // binary reader //
3537 ///////////////////
3538 
3539 /*!
3540 @brief deserialization of CBOR, MessagePack, and UBJSON values
3541 */
3542 template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
3543 class binary_reader
3544 {
3545     using number_integer_t = typename BasicJsonType::number_integer_t;
3546     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3547     using number_float_t = typename BasicJsonType::number_float_t;
3548     using string_t = typename BasicJsonType::string_t;
3549     using json_sax_t = SAX;
3550 
3551   public:
3552     /*!
3553     @brief create a binary reader
3554 
3555     @param[in] adapter  input adapter to read from
3556     */
binary_reader(input_adapter_t adapter)3557     explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
3558     {
3559         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
3560         assert(ia);
3561     }
3562 
3563     // make class move-only
3564     binary_reader(const binary_reader&) = delete;
3565     binary_reader(binary_reader&&) = default;
3566     binary_reader& operator=(const binary_reader&) = delete;
3567     binary_reader& operator=(binary_reader&&) = default;
3568     ~binary_reader() = default;
3569 
3570     /*!
3571     @param[in] format  the binary format to parse
3572     @param[in] sax_    a SAX event processor
3573     @param[in] strict  whether to expect the input to be consumed completed
3574 
3575     @return
3576     */
sax_parse(const input_format_t format,json_sax_t * sax_,const bool strict=true)3577     bool sax_parse(const input_format_t format,
3578                    json_sax_t* sax_,
3579                    const bool strict = true)
3580     {
3581         sax = sax_;
3582         bool result = false;
3583 
3584         switch (format)
3585         {
3586             case input_format_t::bson:
3587                 result = parse_bson_internal();
3588                 break;
3589 
3590             case input_format_t::cbor:
3591                 result = parse_cbor_internal();
3592                 break;
3593 
3594             case input_format_t::msgpack:
3595                 result = parse_msgpack_internal();
3596                 break;
3597 
3598             case input_format_t::ubjson:
3599                 result = parse_ubjson_internal();
3600                 break;
3601 
3602             default:            // LCOV_EXCL_LINE
3603                 assert(false);  // LCOV_EXCL_LINE
3604         }
3605 
3606         // strict mode: next byte must be EOF
3607         if (result and strict)
3608         {
3609             if (format == input_format_t::ubjson)
3610             {
3611                 get_ignore_noop();
3612             }
3613             else
3614             {
3615                 get();
3616             }
3617 
3618             if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
3619             {
3620                 return sax->parse_error(chars_read, get_token_string(),
3621                                         parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
3622             }
3623         }
3624 
3625         return result;
3626     }
3627 
3628     /*!
3629     @brief determine system byte order
3630 
3631     @return true if and only if system's byte order is little endian
3632 
3633     @note from http://stackoverflow.com/a/1001328/266378
3634     */
little_endianess(int num=1)3635     static constexpr bool little_endianess(int num = 1) noexcept
3636     {
3637         return *reinterpret_cast<char*>(&num) == 1;
3638     }
3639 
3640   private:
3641     //////////
3642     // BSON //
3643     //////////
3644 
3645     /*!
3646     @brief Reads in a BSON-object and passes it to the SAX-parser.
3647     @return whether a valid BSON-value was passed to the SAX parser
3648     */
parse_bson_internal()3649     bool parse_bson_internal()
3650     {
3651         std::int32_t document_size;
3652         get_number<std::int32_t, true>(input_format_t::bson, document_size);
3653 
3654         if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
3655         {
3656             return false;
3657         }
3658 
3659         if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
3660         {
3661             return false;
3662         }
3663 
3664         return sax->end_object();
3665     }
3666 
3667     /*!
3668     @brief Parses a C-style string from the BSON input.
3669     @param[in, out] result  A reference to the string variable where the read
3670                             string is to be stored.
3671     @return `true` if the \x00-byte indicating the end of the string was
3672              encountered before the EOF; false` indicates an unexpected EOF.
3673     */
get_bson_cstr(string_t & result)3674     bool get_bson_cstr(string_t& result)
3675     {
3676         auto out = std::back_inserter(result);
3677         while (true)
3678         {
3679             get();
3680             if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
3681             {
3682                 return false;
3683             }
3684             if (current == 0x00)
3685             {
3686                 return true;
3687             }
3688             *out++ = static_cast<char>(current);
3689         }
3690 
3691         return true;
3692     }
3693 
3694     /*!
3695     @brief Parses a zero-terminated string of length @a len from the BSON
3696            input.
3697     @param[in] len  The length (including the zero-byte at the end) of the
3698                     string to be read.
3699     @param[in, out] result  A reference to the string variable where the read
3700                             string is to be stored.
3701     @tparam NumberType The type of the length @a len
3702     @pre len >= 1
3703     @return `true` if the string was successfully parsed
3704     */
3705     template<typename NumberType>
get_bson_string(const NumberType len,string_t & result)3706     bool get_bson_string(const NumberType len, string_t& result)
3707     {
3708         if (JSON_UNLIKELY(len < 1))
3709         {
3710             auto last_token = get_token_string();
3711             return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
3712         }
3713 
3714         return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
3715     }
3716 
3717     /*!
3718     @brief Read a BSON document element of the given @a element_type.
3719     @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
3720     @param[in] element_type_parse_position The position in the input stream,
3721                where the `element_type` was read.
3722     @warning Not all BSON element types are supported yet. An unsupported
3723              @a element_type will give rise to a parse_error.114:
3724              Unsupported BSON record type 0x...
3725     @return whether a valid BSON-object/array was passed to the SAX parser
3726     */
parse_bson_element_internal(const int element_type,const std::size_t element_type_parse_position)3727     bool parse_bson_element_internal(const int element_type,
3728                                      const std::size_t element_type_parse_position)
3729     {
3730         switch (element_type)
3731         {
3732             case 0x01: // double
3733             {
3734                 double number;
3735                 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
3736             }
3737 
3738             case 0x02: // string
3739             {
3740                 std::int32_t len;
3741                 string_t value;
3742                 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
3743             }
3744 
3745             case 0x03: // object
3746             {
3747                 return parse_bson_internal();
3748             }
3749 
3750             case 0x04: // array
3751             {
3752                 return parse_bson_array();
3753             }
3754 
3755             case 0x08: // boolean
3756             {
3757                 return sax->boolean(get() != 0);
3758             }
3759 
3760             case 0x0A: // null
3761             {
3762                 return sax->null();
3763             }
3764 
3765             case 0x10: // int32
3766             {
3767                 std::int32_t value;
3768                 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
3769             }
3770 
3771             case 0x12: // int64
3772             {
3773                 std::int64_t value;
3774                 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
3775             }
3776 
3777             default: // anything else not supported (yet)
3778             {
3779                 std::array<char, 3> cr{{}};
3780                 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
3781                 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
3782             }
3783         }
3784     }
3785 
3786     /*!
3787     @brief Read a BSON element list (as specified in the BSON-spec)
3788 
3789     The same binary layout is used for objects and arrays, hence it must be
3790     indicated with the argument @a is_array which one is expected
3791     (true --> array, false --> object).
3792 
3793     @param[in] is_array Determines if the element list being read is to be
3794                         treated as an object (@a is_array == false), or as an
3795                         array (@a is_array == true).
3796     @return whether a valid BSON-object/array was passed to the SAX parser
3797     */
parse_bson_element_list(const bool is_array)3798     bool parse_bson_element_list(const bool is_array)
3799     {
3800         string_t key;
3801         while (int element_type = get())
3802         {
3803             if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
3804             {
3805                 return false;
3806             }
3807 
3808             const std::size_t element_type_parse_position = chars_read;
3809             if (JSON_UNLIKELY(not get_bson_cstr(key)))
3810             {
3811                 return false;
3812             }
3813 
3814             if (not is_array and not sax->key(key))
3815             {
3816                 return false;
3817             }
3818 
3819             if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
3820             {
3821                 return false;
3822             }
3823 
3824             // get_bson_cstr only appends
3825             key.clear();
3826         }
3827 
3828         return true;
3829     }
3830 
3831     /*!
3832     @brief Reads an array from the BSON input and passes it to the SAX-parser.
3833     @return whether a valid BSON-array was passed to the SAX parser
3834     */
parse_bson_array()3835     bool parse_bson_array()
3836     {
3837         std::int32_t document_size;
3838         get_number<std::int32_t, true>(input_format_t::bson, document_size);
3839 
3840         if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
3841         {
3842             return false;
3843         }
3844 
3845         if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
3846         {
3847             return false;
3848         }
3849 
3850         return sax->end_array();
3851     }
3852 
3853     //////////
3854     // CBOR //
3855     //////////
3856 
3857     /*!
3858     @param[in] get_char  whether a new character should be retrieved from the
3859                          input (true, default) or whether the last read
3860                          character should be considered instead
3861 
3862     @return whether a valid CBOR value was passed to the SAX parser
3863     */
parse_cbor_internal(const bool get_char=true)3864     bool parse_cbor_internal(const bool get_char = true)
3865     {
3866         switch (get_char ? get() : current)
3867         {
3868             // EOF
3869             case std::char_traits<char>::eof():
3870                 return unexpect_eof(input_format_t::cbor, "value");
3871 
3872             // Integer 0x00..0x17 (0..23)
3873             case 0x00:
3874             case 0x01:
3875             case 0x02:
3876             case 0x03:
3877             case 0x04:
3878             case 0x05:
3879             case 0x06:
3880             case 0x07:
3881             case 0x08:
3882             case 0x09:
3883             case 0x0A:
3884             case 0x0B:
3885             case 0x0C:
3886             case 0x0D:
3887             case 0x0E:
3888             case 0x0F:
3889             case 0x10:
3890             case 0x11:
3891             case 0x12:
3892             case 0x13:
3893             case 0x14:
3894             case 0x15:
3895             case 0x16:
3896             case 0x17:
3897                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
3898 
3899             case 0x18: // Unsigned integer (one-byte uint8_t follows)
3900             {
3901                 std::uint8_t number;
3902                 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3903             }
3904 
3905             case 0x19: // Unsigned integer (two-byte uint16_t follows)
3906             {
3907                 std::uint16_t number;
3908                 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3909             }
3910 
3911             case 0x1A: // Unsigned integer (four-byte uint32_t follows)
3912             {
3913                 std::uint32_t number;
3914                 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3915             }
3916 
3917             case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
3918             {
3919                 std::uint64_t number;
3920                 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3921             }
3922 
3923             // Negative integer -1-0x00..-1-0x17 (-1..-24)
3924             case 0x20:
3925             case 0x21:
3926             case 0x22:
3927             case 0x23:
3928             case 0x24:
3929             case 0x25:
3930             case 0x26:
3931             case 0x27:
3932             case 0x28:
3933             case 0x29:
3934             case 0x2A:
3935             case 0x2B:
3936             case 0x2C:
3937             case 0x2D:
3938             case 0x2E:
3939             case 0x2F:
3940             case 0x30:
3941             case 0x31:
3942             case 0x32:
3943             case 0x33:
3944             case 0x34:
3945             case 0x35:
3946             case 0x36:
3947             case 0x37:
3948                 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
3949 
3950             case 0x38: // Negative integer (one-byte uint8_t follows)
3951             {
3952                 std::uint8_t number;
3953                 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
3954             }
3955 
3956             case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
3957             {
3958                 std::uint16_t number;
3959                 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
3960             }
3961 
3962             case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
3963             {
3964                 std::uint32_t number;
3965                 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
3966             }
3967 
3968             case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
3969             {
3970                 std::uint64_t number;
3971                 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
3972                         - static_cast<number_integer_t>(number));
3973             }
3974 
3975             // UTF-8 string (0x00..0x17 bytes follow)
3976             case 0x60:
3977             case 0x61:
3978             case 0x62:
3979             case 0x63:
3980             case 0x64:
3981             case 0x65:
3982             case 0x66:
3983             case 0x67:
3984             case 0x68:
3985             case 0x69:
3986             case 0x6A:
3987             case 0x6B:
3988             case 0x6C:
3989             case 0x6D:
3990             case 0x6E:
3991             case 0x6F:
3992             case 0x70:
3993             case 0x71:
3994             case 0x72:
3995             case 0x73:
3996             case 0x74:
3997             case 0x75:
3998             case 0x76:
3999             case 0x77:
4000             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4001             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4002             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
4003             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
4004             case 0x7F: // UTF-8 string (indefinite length)
4005             {
4006                 string_t s;
4007                 return get_cbor_string(s) and sax->string(s);
4008             }
4009 
4010             // array (0x00..0x17 data items follow)
4011             case 0x80:
4012             case 0x81:
4013             case 0x82:
4014             case 0x83:
4015             case 0x84:
4016             case 0x85:
4017             case 0x86:
4018             case 0x87:
4019             case 0x88:
4020             case 0x89:
4021             case 0x8A:
4022             case 0x8B:
4023             case 0x8C:
4024             case 0x8D:
4025             case 0x8E:
4026             case 0x8F:
4027             case 0x90:
4028             case 0x91:
4029             case 0x92:
4030             case 0x93:
4031             case 0x94:
4032             case 0x95:
4033             case 0x96:
4034             case 0x97:
4035                 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
4036 
4037             case 0x98: // array (one-byte uint8_t for n follows)
4038             {
4039                 std::uint8_t len;
4040                 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4041             }
4042 
4043             case 0x99: // array (two-byte uint16_t for n follow)
4044             {
4045                 std::uint16_t len;
4046                 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4047             }
4048 
4049             case 0x9A: // array (four-byte uint32_t for n follow)
4050             {
4051                 std::uint32_t len;
4052                 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4053             }
4054 
4055             case 0x9B: // array (eight-byte uint64_t for n follow)
4056             {
4057                 std::uint64_t len;
4058                 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4059             }
4060 
4061             case 0x9F: // array (indefinite length)
4062                 return get_cbor_array(std::size_t(-1));
4063 
4064             // map (0x00..0x17 pairs of data items follow)
4065             case 0xA0:
4066             case 0xA1:
4067             case 0xA2:
4068             case 0xA3:
4069             case 0xA4:
4070             case 0xA5:
4071             case 0xA6:
4072             case 0xA7:
4073             case 0xA8:
4074             case 0xA9:
4075             case 0xAA:
4076             case 0xAB:
4077             case 0xAC:
4078             case 0xAD:
4079             case 0xAE:
4080             case 0xAF:
4081             case 0xB0:
4082             case 0xB1:
4083             case 0xB2:
4084             case 0xB3:
4085             case 0xB4:
4086             case 0xB5:
4087             case 0xB6:
4088             case 0xB7:
4089                 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
4090 
4091             case 0xB8: // map (one-byte uint8_t for n follows)
4092             {
4093                 std::uint8_t len;
4094                 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4095             }
4096 
4097             case 0xB9: // map (two-byte uint16_t for n follow)
4098             {
4099                 std::uint16_t len;
4100                 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4101             }
4102 
4103             case 0xBA: // map (four-byte uint32_t for n follow)
4104             {
4105                 std::uint32_t len;
4106                 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4107             }
4108 
4109             case 0xBB: // map (eight-byte uint64_t for n follow)
4110             {
4111                 std::uint64_t len;
4112                 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4113             }
4114 
4115             case 0xBF: // map (indefinite length)
4116                 return get_cbor_object(std::size_t(-1));
4117 
4118             case 0xF4: // false
4119                 return sax->boolean(false);
4120 
4121             case 0xF5: // true
4122                 return sax->boolean(true);
4123 
4124             case 0xF6: // null
4125                 return sax->null();
4126 
4127             case 0xF9: // Half-Precision Float (two-byte IEEE 754)
4128             {
4129                 const int byte1_raw = get();
4130                 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
4131                 {
4132                     return false;
4133                 }
4134                 const int byte2_raw = get();
4135                 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
4136                 {
4137                     return false;
4138                 }
4139 
4140                 const auto byte1 = static_cast<unsigned char>(byte1_raw);
4141                 const auto byte2 = static_cast<unsigned char>(byte2_raw);
4142 
4143                 // code from RFC 7049, Appendix D, Figure 3:
4144                 // As half-precision floating-point numbers were only added
4145                 // to IEEE 754 in 2008, today's programming platforms often
4146                 // still only have limited support for them. It is very
4147                 // easy to include at least decoding support for them even
4148                 // without such support. An example of a small decoder for
4149                 // half-precision floating-point numbers in the C language
4150                 // is shown in Fig. 3.
4151                 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
4152                 const double val = [&half]
4153                 {
4154                     const int exp = (half >> 10u) & 0x1Fu;
4155                     const unsigned int mant = half & 0x3FFu;
4156                     assert(0 <= exp and exp <= 32);
4157                     assert(0 <= mant and mant <= 1024);
4158                     switch (exp)
4159                     {
4160                         case 0:
4161                             return std::ldexp(mant, -24);
4162                         case 31:
4163                             return (mant == 0)
4164                             ? std::numeric_limits<double>::infinity()
4165                             : std::numeric_limits<double>::quiet_NaN();
4166                         default:
4167                             return std::ldexp(mant + 1024, exp - 25);
4168                     }
4169                 }();
4170                 return sax->number_float((half & 0x8000u) != 0
4171                                          ? static_cast<number_float_t>(-val)
4172                                          : static_cast<number_float_t>(val), "");
4173             }
4174 
4175             case 0xFA: // Single-Precision Float (four-byte IEEE 754)
4176             {
4177                 float number;
4178                 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
4179             }
4180 
4181             case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
4182             {
4183                 double number;
4184                 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
4185             }
4186 
4187             default: // anything else (0xFF is handled inside the other types)
4188             {
4189                 auto last_token = get_token_string();
4190                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
4191             }
4192         }
4193     }
4194 
4195     /*!
4196     @brief reads a CBOR string
4197 
4198     This function first reads starting bytes to determine the expected
4199     string length and then copies this number of bytes into a string.
4200     Additionally, CBOR's strings with indefinite lengths are supported.
4201 
4202     @param[out] result  created string
4203 
4204     @return whether string creation completed
4205     */
get_cbor_string(string_t & result)4206     bool get_cbor_string(string_t& result)
4207     {
4208         if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
4209         {
4210             return false;
4211         }
4212 
4213         switch (current)
4214         {
4215             // UTF-8 string (0x00..0x17 bytes follow)
4216             case 0x60:
4217             case 0x61:
4218             case 0x62:
4219             case 0x63:
4220             case 0x64:
4221             case 0x65:
4222             case 0x66:
4223             case 0x67:
4224             case 0x68:
4225             case 0x69:
4226             case 0x6A:
4227             case 0x6B:
4228             case 0x6C:
4229             case 0x6D:
4230             case 0x6E:
4231             case 0x6F:
4232             case 0x70:
4233             case 0x71:
4234             case 0x72:
4235             case 0x73:
4236             case 0x74:
4237             case 0x75:
4238             case 0x76:
4239             case 0x77:
4240             {
4241                 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
4242             }
4243 
4244             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4245             {
4246                 std::uint8_t len;
4247                 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4248             }
4249 
4250             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4251             {
4252                 std::uint16_t len;
4253                 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4254             }
4255 
4256             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
4257             {
4258                 std::uint32_t len;
4259                 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4260             }
4261 
4262             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
4263             {
4264                 std::uint64_t len;
4265                 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4266             }
4267 
4268             case 0x7F: // UTF-8 string (indefinite length)
4269             {
4270                 while (get() != 0xFF)
4271                 {
4272                     string_t chunk;
4273                     if (not get_cbor_string(chunk))
4274                     {
4275                         return false;
4276                     }
4277                     result.append(chunk);
4278                 }
4279                 return true;
4280             }
4281 
4282             default:
4283             {
4284                 auto last_token = get_token_string();
4285                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
4286             }
4287         }
4288     }
4289 
4290     /*!
4291     @param[in] len  the length of the array or std::size_t(-1) for an
4292                     array of indefinite size
4293     @return whether array creation completed
4294     */
get_cbor_array(const std::size_t len)4295     bool get_cbor_array(const std::size_t len)
4296     {
4297         if (JSON_UNLIKELY(not sax->start_array(len)))
4298         {
4299             return false;
4300         }
4301 
4302         if (len != std::size_t(-1))
4303         {
4304             for (std::size_t i = 0; i < len; ++i)
4305             {
4306                 if (JSON_UNLIKELY(not parse_cbor_internal()))
4307                 {
4308                     return false;
4309                 }
4310             }
4311         }
4312         else
4313         {
4314             while (get() != 0xFF)
4315             {
4316                 if (JSON_UNLIKELY(not parse_cbor_internal(false)))
4317                 {
4318                     return false;
4319                 }
4320             }
4321         }
4322 
4323         return sax->end_array();
4324     }
4325 
4326     /*!
4327     @param[in] len  the length of the object or std::size_t(-1) for an
4328                     object of indefinite size
4329     @return whether object creation completed
4330     */
get_cbor_object(const std::size_t len)4331     bool get_cbor_object(const std::size_t len)
4332     {
4333         if (JSON_UNLIKELY(not sax->start_object(len)))
4334         {
4335             return false;
4336         }
4337 
4338         string_t key;
4339         if (len != std::size_t(-1))
4340         {
4341             for (std::size_t i = 0; i < len; ++i)
4342             {
4343                 get();
4344                 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
4345                 {
4346                     return false;
4347                 }
4348 
4349                 if (JSON_UNLIKELY(not parse_cbor_internal()))
4350                 {
4351                     return false;
4352                 }
4353                 key.clear();
4354             }
4355         }
4356         else
4357         {
4358             while (get() != 0xFF)
4359             {
4360                 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
4361                 {
4362                     return false;
4363                 }
4364 
4365                 if (JSON_UNLIKELY(not parse_cbor_internal()))
4366                 {
4367                     return false;
4368                 }
4369                 key.clear();
4370             }
4371         }
4372 
4373         return sax->end_object();
4374     }
4375 
4376     /////////////
4377     // MsgPack //
4378     /////////////
4379 
4380     /*!
4381     @return whether a valid MessagePack value was passed to the SAX parser
4382     */
parse_msgpack_internal()4383     bool parse_msgpack_internal()
4384     {
4385         switch (get())
4386         {
4387             // EOF
4388             case std::char_traits<char>::eof():
4389                 return unexpect_eof(input_format_t::msgpack, "value");
4390 
4391             // positive fixint
4392             case 0x00:
4393             case 0x01:
4394             case 0x02:
4395             case 0x03:
4396             case 0x04:
4397             case 0x05:
4398             case 0x06:
4399             case 0x07:
4400             case 0x08:
4401             case 0x09:
4402             case 0x0A:
4403             case 0x0B:
4404             case 0x0C:
4405             case 0x0D:
4406             case 0x0E:
4407             case 0x0F:
4408             case 0x10:
4409             case 0x11:
4410             case 0x12:
4411             case 0x13:
4412             case 0x14:
4413             case 0x15:
4414             case 0x16:
4415             case 0x17:
4416             case 0x18:
4417             case 0x19:
4418             case 0x1A:
4419             case 0x1B:
4420             case 0x1C:
4421             case 0x1D:
4422             case 0x1E:
4423             case 0x1F:
4424             case 0x20:
4425             case 0x21:
4426             case 0x22:
4427             case 0x23:
4428             case 0x24:
4429             case 0x25:
4430             case 0x26:
4431             case 0x27:
4432             case 0x28:
4433             case 0x29:
4434             case 0x2A:
4435             case 0x2B:
4436             case 0x2C:
4437             case 0x2D:
4438             case 0x2E:
4439             case 0x2F:
4440             case 0x30:
4441             case 0x31:
4442             case 0x32:
4443             case 0x33:
4444             case 0x34:
4445             case 0x35:
4446             case 0x36:
4447             case 0x37:
4448             case 0x38:
4449             case 0x39:
4450             case 0x3A:
4451             case 0x3B:
4452             case 0x3C:
4453             case 0x3D:
4454             case 0x3E:
4455             case 0x3F:
4456             case 0x40:
4457             case 0x41:
4458             case 0x42:
4459             case 0x43:
4460             case 0x44:
4461             case 0x45:
4462             case 0x46:
4463             case 0x47:
4464             case 0x48:
4465             case 0x49:
4466             case 0x4A:
4467             case 0x4B:
4468             case 0x4C:
4469             case 0x4D:
4470             case 0x4E:
4471             case 0x4F:
4472             case 0x50:
4473             case 0x51:
4474             case 0x52:
4475             case 0x53:
4476             case 0x54:
4477             case 0x55:
4478             case 0x56:
4479             case 0x57:
4480             case 0x58:
4481             case 0x59:
4482             case 0x5A:
4483             case 0x5B:
4484             case 0x5C:
4485             case 0x5D:
4486             case 0x5E:
4487             case 0x5F:
4488             case 0x60:
4489             case 0x61:
4490             case 0x62:
4491             case 0x63:
4492             case 0x64:
4493             case 0x65:
4494             case 0x66:
4495             case 0x67:
4496             case 0x68:
4497             case 0x69:
4498             case 0x6A:
4499             case 0x6B:
4500             case 0x6C:
4501             case 0x6D:
4502             case 0x6E:
4503             case 0x6F:
4504             case 0x70:
4505             case 0x71:
4506             case 0x72:
4507             case 0x73:
4508             case 0x74:
4509             case 0x75:
4510             case 0x76:
4511             case 0x77:
4512             case 0x78:
4513             case 0x79:
4514             case 0x7A:
4515             case 0x7B:
4516             case 0x7C:
4517             case 0x7D:
4518             case 0x7E:
4519             case 0x7F:
4520                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
4521 
4522             // fixmap
4523             case 0x80:
4524             case 0x81:
4525             case 0x82:
4526             case 0x83:
4527             case 0x84:
4528             case 0x85:
4529             case 0x86:
4530             case 0x87:
4531             case 0x88:
4532             case 0x89:
4533             case 0x8A:
4534             case 0x8B:
4535             case 0x8C:
4536             case 0x8D:
4537             case 0x8E:
4538             case 0x8F:
4539                 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
4540 
4541             // fixarray
4542             case 0x90:
4543             case 0x91:
4544             case 0x92:
4545             case 0x93:
4546             case 0x94:
4547             case 0x95:
4548             case 0x96:
4549             case 0x97:
4550             case 0x98:
4551             case 0x99:
4552             case 0x9A:
4553             case 0x9B:
4554             case 0x9C:
4555             case 0x9D:
4556             case 0x9E:
4557             case 0x9F:
4558                 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
4559 
4560             // fixstr
4561             case 0xA0:
4562             case 0xA1:
4563             case 0xA2:
4564             case 0xA3:
4565             case 0xA4:
4566             case 0xA5:
4567             case 0xA6:
4568             case 0xA7:
4569             case 0xA8:
4570             case 0xA9:
4571             case 0xAA:
4572             case 0xAB:
4573             case 0xAC:
4574             case 0xAD:
4575             case 0xAE:
4576             case 0xAF:
4577             case 0xB0:
4578             case 0xB1:
4579             case 0xB2:
4580             case 0xB3:
4581             case 0xB4:
4582             case 0xB5:
4583             case 0xB6:
4584             case 0xB7:
4585             case 0xB8:
4586             case 0xB9:
4587             case 0xBA:
4588             case 0xBB:
4589             case 0xBC:
4590             case 0xBD:
4591             case 0xBE:
4592             case 0xBF:
4593             {
4594                 string_t s;
4595                 return get_msgpack_string(s) and sax->string(s);
4596             }
4597 
4598             case 0xC0: // nil
4599                 return sax->null();
4600 
4601             case 0xC2: // false
4602                 return sax->boolean(false);
4603 
4604             case 0xC3: // true
4605                 return sax->boolean(true);
4606 
4607             case 0xCA: // float 32
4608             {
4609                 float number;
4610                 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
4611             }
4612 
4613             case 0xCB: // float 64
4614             {
4615                 double number;
4616                 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
4617             }
4618 
4619             case 0xCC: // uint 8
4620             {
4621                 std::uint8_t number;
4622                 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4623             }
4624 
4625             case 0xCD: // uint 16
4626             {
4627                 std::uint16_t number;
4628                 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4629             }
4630 
4631             case 0xCE: // uint 32
4632             {
4633                 std::uint32_t number;
4634                 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4635             }
4636 
4637             case 0xCF: // uint 64
4638             {
4639                 std::uint64_t number;
4640                 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4641             }
4642 
4643             case 0xD0: // int 8
4644             {
4645                 std::int8_t number;
4646                 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4647             }
4648 
4649             case 0xD1: // int 16
4650             {
4651                 std::int16_t number;
4652                 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4653             }
4654 
4655             case 0xD2: // int 32
4656             {
4657                 std::int32_t number;
4658                 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4659             }
4660 
4661             case 0xD3: // int 64
4662             {
4663                 std::int64_t number;
4664                 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4665             }
4666 
4667             case 0xD9: // str 8
4668             case 0xDA: // str 16
4669             case 0xDB: // str 32
4670             {
4671                 string_t s;
4672                 return get_msgpack_string(s) and sax->string(s);
4673             }
4674 
4675             case 0xDC: // array 16
4676             {
4677                 std::uint16_t len;
4678                 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
4679             }
4680 
4681             case 0xDD: // array 32
4682             {
4683                 std::uint32_t len;
4684                 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
4685             }
4686 
4687             case 0xDE: // map 16
4688             {
4689                 std::uint16_t len;
4690                 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
4691             }
4692 
4693             case 0xDF: // map 32
4694             {
4695                 std::uint32_t len;
4696                 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
4697             }
4698 
4699             // negative fixint
4700             case 0xE0:
4701             case 0xE1:
4702             case 0xE2:
4703             case 0xE3:
4704             case 0xE4:
4705             case 0xE5:
4706             case 0xE6:
4707             case 0xE7:
4708             case 0xE8:
4709             case 0xE9:
4710             case 0xEA:
4711             case 0xEB:
4712             case 0xEC:
4713             case 0xED:
4714             case 0xEE:
4715             case 0xEF:
4716             case 0xF0:
4717             case 0xF1:
4718             case 0xF2:
4719             case 0xF3:
4720             case 0xF4:
4721             case 0xF5:
4722             case 0xF6:
4723             case 0xF7:
4724             case 0xF8:
4725             case 0xF9:
4726             case 0xFA:
4727             case 0xFB:
4728             case 0xFC:
4729             case 0xFD:
4730             case 0xFE:
4731             case 0xFF:
4732                 return sax->number_integer(static_cast<std::int8_t>(current));
4733 
4734             default: // anything else
4735             {
4736                 auto last_token = get_token_string();
4737                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
4738             }
4739         }
4740     }
4741 
4742     /*!
4743     @brief reads a MessagePack string
4744 
4745     This function first reads starting bytes to determine the expected
4746     string length and then copies this number of bytes into a string.
4747 
4748     @param[out] result  created string
4749 
4750     @return whether string creation completed
4751     */
get_msgpack_string(string_t & result)4752     bool get_msgpack_string(string_t& result)
4753     {
4754         if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
4755         {
4756             return false;
4757         }
4758 
4759         switch (current)
4760         {
4761             // fixstr
4762             case 0xA0:
4763             case 0xA1:
4764             case 0xA2:
4765             case 0xA3:
4766             case 0xA4:
4767             case 0xA5:
4768             case 0xA6:
4769             case 0xA7:
4770             case 0xA8:
4771             case 0xA9:
4772             case 0xAA:
4773             case 0xAB:
4774             case 0xAC:
4775             case 0xAD:
4776             case 0xAE:
4777             case 0xAF:
4778             case 0xB0:
4779             case 0xB1:
4780             case 0xB2:
4781             case 0xB3:
4782             case 0xB4:
4783             case 0xB5:
4784             case 0xB6:
4785             case 0xB7:
4786             case 0xB8:
4787             case 0xB9:
4788             case 0xBA:
4789             case 0xBB:
4790             case 0xBC:
4791             case 0xBD:
4792             case 0xBE:
4793             case 0xBF:
4794             {
4795                 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
4796             }
4797 
4798             case 0xD9: // str 8
4799             {
4800                 std::uint8_t len;
4801                 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4802             }
4803 
4804             case 0xDA: // str 16
4805             {
4806                 std::uint16_t len;
4807                 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4808             }
4809 
4810             case 0xDB: // str 32
4811             {
4812                 std::uint32_t len;
4813                 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4814             }
4815 
4816             default:
4817             {
4818                 auto last_token = get_token_string();
4819                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
4820             }
4821         }
4822     }
4823 
4824     /*!
4825     @param[in] len  the length of the array
4826     @return whether array creation completed
4827     */
get_msgpack_array(const std::size_t len)4828     bool get_msgpack_array(const std::size_t len)
4829     {
4830         if (JSON_UNLIKELY(not sax->start_array(len)))
4831         {
4832             return false;
4833         }
4834 
4835         for (std::size_t i = 0; i < len; ++i)
4836         {
4837             if (JSON_UNLIKELY(not parse_msgpack_internal()))
4838             {
4839                 return false;
4840             }
4841         }
4842 
4843         return sax->end_array();
4844     }
4845 
4846     /*!
4847     @param[in] len  the length of the object
4848     @return whether object creation completed
4849     */
get_msgpack_object(const std::size_t len)4850     bool get_msgpack_object(const std::size_t len)
4851     {
4852         if (JSON_UNLIKELY(not sax->start_object(len)))
4853         {
4854             return false;
4855         }
4856 
4857         string_t key;
4858         for (std::size_t i = 0; i < len; ++i)
4859         {
4860             get();
4861             if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
4862             {
4863                 return false;
4864             }
4865 
4866             if (JSON_UNLIKELY(not parse_msgpack_internal()))
4867             {
4868                 return false;
4869             }
4870             key.clear();
4871         }
4872 
4873         return sax->end_object();
4874     }
4875 
4876     ////////////
4877     // UBJSON //
4878     ////////////
4879 
4880     /*!
4881     @param[in] get_char  whether a new character should be retrieved from the
4882                          input (true, default) or whether the last read
4883                          character should be considered instead
4884 
4885     @return whether a valid UBJSON value was passed to the SAX parser
4886     */
parse_ubjson_internal(const bool get_char=true)4887     bool parse_ubjson_internal(const bool get_char = true)
4888     {
4889         return get_ubjson_value(get_char ? get_ignore_noop() : current);
4890     }
4891 
4892     /*!
4893     @brief reads a UBJSON string
4894 
4895     This function is either called after reading the 'S' byte explicitly
4896     indicating a string, or in case of an object key where the 'S' byte can be
4897     left out.
4898 
4899     @param[out] result   created string
4900     @param[in] get_char  whether a new character should be retrieved from the
4901                          input (true, default) or whether the last read
4902                          character should be considered instead
4903 
4904     @return whether string creation completed
4905     */
get_ubjson_string(string_t & result,const bool get_char=true)4906     bool get_ubjson_string(string_t& result, const bool get_char = true)
4907     {
4908         if (get_char)
4909         {
4910             get();  // TODO(niels): may we ignore N here?
4911         }
4912 
4913         if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
4914         {
4915             return false;
4916         }
4917 
4918         switch (current)
4919         {
4920             case 'U':
4921             {
4922                 std::uint8_t len;
4923                 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4924             }
4925 
4926             case 'i':
4927             {
4928                 std::int8_t len;
4929                 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4930             }
4931 
4932             case 'I':
4933             {
4934                 std::int16_t len;
4935                 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4936             }
4937 
4938             case 'l':
4939             {
4940                 std::int32_t len;
4941                 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4942             }
4943 
4944             case 'L':
4945             {
4946                 std::int64_t len;
4947                 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4948             }
4949 
4950             default:
4951                 auto last_token = get_token_string();
4952                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
4953         }
4954     }
4955 
4956     /*!
4957     @param[out] result  determined size
4958     @return whether size determination completed
4959     */
get_ubjson_size_value(std::size_t & result)4960     bool get_ubjson_size_value(std::size_t& result)
4961     {
4962         switch (get_ignore_noop())
4963         {
4964             case 'U':
4965             {
4966                 std::uint8_t number;
4967                 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
4968                 {
4969                     return false;
4970                 }
4971                 result = static_cast<std::size_t>(number);
4972                 return true;
4973             }
4974 
4975             case 'i':
4976             {
4977                 std::int8_t number;
4978                 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
4979                 {
4980                     return false;
4981                 }
4982                 result = static_cast<std::size_t>(number);
4983                 return true;
4984             }
4985 
4986             case 'I':
4987             {
4988                 std::int16_t number;
4989                 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
4990                 {
4991                     return false;
4992                 }
4993                 result = static_cast<std::size_t>(number);
4994                 return true;
4995             }
4996 
4997             case 'l':
4998             {
4999                 std::int32_t number;
5000                 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5001                 {
5002                     return false;
5003                 }
5004                 result = static_cast<std::size_t>(number);
5005                 return true;
5006             }
5007 
5008             case 'L':
5009             {
5010                 std::int64_t number;
5011                 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5012                 {
5013                     return false;
5014                 }
5015                 result = static_cast<std::size_t>(number);
5016                 return true;
5017             }
5018 
5019             default:
5020             {
5021                 auto last_token = get_token_string();
5022                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
5023             }
5024         }
5025     }
5026 
5027     /*!
5028     @brief determine the type and size for a container
5029 
5030     In the optimized UBJSON format, a type and a size can be provided to allow
5031     for a more compact representation.
5032 
5033     @param[out] result  pair of the size and the type
5034 
5035     @return whether pair creation completed
5036     */
get_ubjson_size_type(std::pair<std::size_t,int> & result)5037     bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
5038     {
5039         result.first = string_t::npos; // size
5040         result.second = 0; // type
5041 
5042         get_ignore_noop();
5043 
5044         if (current == '$')
5045         {
5046             result.second = get();  // must not ignore 'N', because 'N' maybe the type
5047             if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
5048             {
5049                 return false;
5050             }
5051 
5052             get_ignore_noop();
5053             if (JSON_UNLIKELY(current != '#'))
5054             {
5055                 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
5056                 {
5057                     return false;
5058                 }
5059                 auto last_token = get_token_string();
5060                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
5061             }
5062 
5063             return get_ubjson_size_value(result.first);
5064         }
5065 
5066         if (current == '#')
5067         {
5068             return get_ubjson_size_value(result.first);
5069         }
5070 
5071         return true;
5072     }
5073 
5074     /*!
5075     @param prefix  the previously read or set type prefix
5076     @return whether value creation completed
5077     */
get_ubjson_value(const int prefix)5078     bool get_ubjson_value(const int prefix)
5079     {
5080         switch (prefix)
5081         {
5082             case std::char_traits<char>::eof():  // EOF
5083                 return unexpect_eof(input_format_t::ubjson, "value");
5084 
5085             case 'T':  // true
5086                 return sax->boolean(true);
5087             case 'F':  // false
5088                 return sax->boolean(false);
5089 
5090             case 'Z':  // null
5091                 return sax->null();
5092 
5093             case 'U':
5094             {
5095                 std::uint8_t number;
5096                 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
5097             }
5098 
5099             case 'i':
5100             {
5101                 std::int8_t number;
5102                 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5103             }
5104 
5105             case 'I':
5106             {
5107                 std::int16_t number;
5108                 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5109             }
5110 
5111             case 'l':
5112             {
5113                 std::int32_t number;
5114                 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5115             }
5116 
5117             case 'L':
5118             {
5119                 std::int64_t number;
5120                 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5121             }
5122 
5123             case 'd':
5124             {
5125                 float number;
5126                 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5127             }
5128 
5129             case 'D':
5130             {
5131                 double number;
5132                 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5133             }
5134 
5135             case 'C':  // char
5136             {
5137                 get();
5138                 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
5139                 {
5140                     return false;
5141                 }
5142                 if (JSON_UNLIKELY(current > 127))
5143                 {
5144                     auto last_token = get_token_string();
5145                     return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
5146                 }
5147                 string_t s(1, static_cast<char>(current));
5148                 return sax->string(s);
5149             }
5150 
5151             case 'S':  // string
5152             {
5153                 string_t s;
5154                 return get_ubjson_string(s) and sax->string(s);
5155             }
5156 
5157             case '[':  // array
5158                 return get_ubjson_array();
5159 
5160             case '{':  // object
5161                 return get_ubjson_object();
5162 
5163             default: // anything else
5164             {
5165                 auto last_token = get_token_string();
5166                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
5167             }
5168         }
5169     }
5170 
5171     /*!
5172     @return whether array creation completed
5173     */
get_ubjson_array()5174     bool get_ubjson_array()
5175     {
5176         std::pair<std::size_t, int> size_and_type;
5177         if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
5178         {
5179             return false;
5180         }
5181 
5182         if (size_and_type.first != string_t::npos)
5183         {
5184             if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
5185             {
5186                 return false;
5187             }
5188 
5189             if (size_and_type.second != 0)
5190             {
5191                 if (size_and_type.second != 'N')
5192                 {
5193                     for (std::size_t i = 0; i < size_and_type.first; ++i)
5194                     {
5195                         if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
5196                         {
5197                             return false;
5198                         }
5199                     }
5200                 }
5201             }
5202             else
5203             {
5204                 for (std::size_t i = 0; i < size_and_type.first; ++i)
5205                 {
5206                     if (JSON_UNLIKELY(not parse_ubjson_internal()))
5207                     {
5208                         return false;
5209                     }
5210                 }
5211             }
5212         }
5213         else
5214         {
5215             if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
5216             {
5217                 return false;
5218             }
5219 
5220             while (current != ']')
5221             {
5222                 if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
5223                 {
5224                     return false;
5225                 }
5226                 get_ignore_noop();
5227             }
5228         }
5229 
5230         return sax->end_array();
5231     }
5232 
5233     /*!
5234     @return whether object creation completed
5235     */
get_ubjson_object()5236     bool get_ubjson_object()
5237     {
5238         std::pair<std::size_t, int> size_and_type;
5239         if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
5240         {
5241             return false;
5242         }
5243 
5244         string_t key;
5245         if (size_and_type.first != string_t::npos)
5246         {
5247             if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
5248             {
5249                 return false;
5250             }
5251 
5252             if (size_and_type.second != 0)
5253             {
5254                 for (std::size_t i = 0; i < size_and_type.first; ++i)
5255                 {
5256                     if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
5257                     {
5258                         return false;
5259                     }
5260                     if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
5261                     {
5262                         return false;
5263                     }
5264                     key.clear();
5265                 }
5266             }
5267             else
5268             {
5269                 for (std::size_t i = 0; i < size_and_type.first; ++i)
5270                 {
5271                     if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
5272                     {
5273                         return false;
5274                     }
5275                     if (JSON_UNLIKELY(not parse_ubjson_internal()))
5276                     {
5277                         return false;
5278                     }
5279                     key.clear();
5280                 }
5281             }
5282         }
5283         else
5284         {
5285             if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
5286             {
5287                 return false;
5288             }
5289 
5290             while (current != '}')
5291             {
5292                 if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
5293                 {
5294                     return false;
5295                 }
5296                 if (JSON_UNLIKELY(not parse_ubjson_internal()))
5297                 {
5298                     return false;
5299                 }
5300                 get_ignore_noop();
5301                 key.clear();
5302             }
5303         }
5304 
5305         return sax->end_object();
5306     }
5307 
5308     ///////////////////////
5309     // Utility functions //
5310     ///////////////////////
5311 
5312     /*!
5313     @brief get next character from the input
5314 
5315     This function provides the interface to the used input adapter. It does
5316     not throw in case the input reached EOF, but returns a -'ve valued
5317     `std::char_traits<char>::eof()` in that case.
5318 
5319     @return character read from the input
5320     */
get()5321     int get()
5322     {
5323         ++chars_read;
5324         return current = ia->get_character();
5325     }
5326 
5327     /*!
5328     @return character read from the input after ignoring all 'N' entries
5329     */
get_ignore_noop()5330     int get_ignore_noop()
5331     {
5332         do
5333         {
5334             get();
5335         }
5336         while (current == 'N');
5337 
5338         return current;
5339     }
5340 
5341     /*
5342     @brief read a number from the input
5343 
5344     @tparam NumberType the type of the number
5345     @param[in] format   the current format (for diagnostics)
5346     @param[out] result  number of type @a NumberType
5347 
5348     @return whether conversion completed
5349 
5350     @note This function needs to respect the system's endianess, because
5351           bytes in CBOR, MessagePack, and UBJSON are stored in network order
5352           (big endian) and therefore need reordering on little endian systems.
5353     */
5354     template<typename NumberType, bool InputIsLittleEndian = false>
get_number(const input_format_t format,NumberType & result)5355     bool get_number(const input_format_t format, NumberType& result)
5356     {
5357         // step 1: read input into array with system's byte order
5358         std::array<std::uint8_t, sizeof(NumberType)> vec;
5359         for (std::size_t i = 0; i < sizeof(NumberType); ++i)
5360         {
5361             get();
5362             if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
5363             {
5364                 return false;
5365             }
5366 
5367             // reverse byte order prior to conversion if necessary
5368             if (is_little_endian != InputIsLittleEndian)
5369             {
5370                 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
5371             }
5372             else
5373             {
5374                 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
5375             }
5376         }
5377 
5378         // step 2: convert array into number of type T and return
5379         std::memcpy(&result, vec.data(), sizeof(NumberType));
5380         return true;
5381     }
5382 
5383     /*!
5384     @brief create a string by reading characters from the input
5385 
5386     @tparam NumberType the type of the number
5387     @param[in] format the current format (for diagnostics)
5388     @param[in] len number of characters to read
5389     @param[out] result string created by reading @a len bytes
5390 
5391     @return whether string creation completed
5392 
5393     @note We can not reserve @a len bytes for the result, because @a len
5394           may be too large. Usually, @ref unexpect_eof() detects the end of
5395           the input before we run out of string memory.
5396     */
5397     template<typename NumberType>
get_string(const input_format_t format,const NumberType len,string_t & result)5398     bool get_string(const input_format_t format,
5399                     const NumberType len,
5400                     string_t& result)
5401     {
5402         bool success = true;
5403         std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
5404         {
5405             get();
5406             if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
5407             {
5408                 success = false;
5409             }
5410             return static_cast<char>(current);
5411         });
5412         return success;
5413     }
5414 
5415     /*!
5416     @param[in] format   the current format (for diagnostics)
5417     @param[in] context  further context information (for diagnostics)
5418     @return whether the last read character is not EOF
5419     */
unexpect_eof(const input_format_t format,const char * context) const5420     bool unexpect_eof(const input_format_t format, const char* context) const
5421     {
5422         if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
5423         {
5424             return sax->parse_error(chars_read, "<end of file>",
5425                                     parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
5426         }
5427         return true;
5428     }
5429 
5430     /*!
5431     @return a string representation of the last read byte
5432     */
get_token_string() const5433     std::string get_token_string() const
5434     {
5435         std::array<char, 3> cr{{}};
5436         (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
5437         return std::string{cr.data()};
5438     }
5439 
5440     /*!
5441     @param[in] format   the current format
5442     @param[in] detail   a detailed error message
5443     @param[in] context  further contect information
5444     @return a message string to use in the parse_error exceptions
5445     */
exception_message(const input_format_t format,const std::string & detail,const std::string & context) const5446     std::string exception_message(const input_format_t format,
5447                                   const std::string& detail,
5448                                   const std::string& context) const
5449     {
5450         std::string error_msg = "syntax error while parsing ";
5451 
5452         switch (format)
5453         {
5454             case input_format_t::cbor:
5455                 error_msg += "CBOR";
5456                 break;
5457 
5458             case input_format_t::msgpack:
5459                 error_msg += "MessagePack";
5460                 break;
5461 
5462             case input_format_t::ubjson:
5463                 error_msg += "UBJSON";
5464                 break;
5465 
5466             case input_format_t::bson:
5467                 error_msg += "BSON";
5468                 break;
5469 
5470             default:            // LCOV_EXCL_LINE
5471                 assert(false);  // LCOV_EXCL_LINE
5472         }
5473 
5474         return error_msg + " " + context + ": " + detail;
5475     }
5476 
5477   private:
5478     /// input adapter
5479     input_adapter_t ia = nullptr;
5480 
5481     /// the current character
5482     int current = std::char_traits<char>::eof();
5483 
5484     /// the number of characters read
5485     std::size_t chars_read = 0;
5486 
5487     /// whether we can assume little endianess
5488     const bool is_little_endian = little_endianess();
5489 
5490     /// the SAX parser
5491     json_sax_t* sax = nullptr;
5492 };
5493 }  // namespace detail
5494 }  // namespace nlohmann
5495 
5496 // #include <nlohmann/detail/input/input_adapters.hpp>
5497 
5498 // #include <nlohmann/detail/input/lexer.hpp>
5499 
5500 
5501 #include <array> // array
5502 #include <clocale> // localeconv
5503 #include <cstddef> // size_t
5504 #include <cstdio> // snprintf
5505 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5506 #include <initializer_list> // initializer_list
5507 #include <string> // char_traits, string
5508 #include <utility> // move
5509 #include <vector> // vector
5510 
5511 // #include <nlohmann/detail/input/input_adapters.hpp>
5512 
5513 // #include <nlohmann/detail/input/position_t.hpp>
5514 
5515 // #include <nlohmann/detail/macro_scope.hpp>
5516 
5517 
5518 namespace nlohmann
5519 {
5520 namespace detail
5521 {
5522 ///////////
5523 // lexer //
5524 ///////////
5525 
5526 /*!
5527 @brief lexical analysis
5528 
5529 This class organizes the lexical analysis during JSON deserialization.
5530 */
5531 template<typename BasicJsonType>
5532 class lexer
5533 {
5534     using number_integer_t = typename BasicJsonType::number_integer_t;
5535     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5536     using number_float_t = typename BasicJsonType::number_float_t;
5537     using string_t = typename BasicJsonType::string_t;
5538 
5539   public:
5540     /// token types for the parser
5541     enum class token_type
5542     {
5543         uninitialized,    ///< indicating the scanner is uninitialized
5544         literal_true,     ///< the `true` literal
5545         literal_false,    ///< the `false` literal
5546         literal_null,     ///< the `null` literal
5547         value_string,     ///< a string -- use get_string() for actual value
5548         value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
5549         value_integer,    ///< a signed integer -- use get_number_integer() for actual value
5550         value_float,      ///< an floating point number -- use get_number_float() for actual value
5551         begin_array,      ///< the character for array begin `[`
5552         begin_object,     ///< the character for object begin `{`
5553         end_array,        ///< the character for array end `]`
5554         end_object,       ///< the character for object end `}`
5555         name_separator,   ///< the name separator `:`
5556         value_separator,  ///< the value separator `,`
5557         parse_error,      ///< indicating a parse error
5558         end_of_input,     ///< indicating the end of the input buffer
5559         literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
5560     };
5561 
5562     /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)5563     static const char* token_type_name(const token_type t) noexcept
5564     {
5565         switch (t)
5566         {
5567             case token_type::uninitialized:
5568                 return "<uninitialized>";
5569             case token_type::literal_true:
5570                 return "true literal";
5571             case token_type::literal_false:
5572                 return "false literal";
5573             case token_type::literal_null:
5574                 return "null literal";
5575             case token_type::value_string:
5576                 return "string literal";
5577             case lexer::token_type::value_unsigned:
5578             case lexer::token_type::value_integer:
5579             case lexer::token_type::value_float:
5580                 return "number literal";
5581             case token_type::begin_array:
5582                 return "'['";
5583             case token_type::begin_object:
5584                 return "'{'";
5585             case token_type::end_array:
5586                 return "']'";
5587             case token_type::end_object:
5588                 return "'}'";
5589             case token_type::name_separator:
5590                 return "':'";
5591             case token_type::value_separator:
5592                 return "','";
5593             case token_type::parse_error:
5594                 return "<parse error>";
5595             case token_type::end_of_input:
5596                 return "end of input";
5597             case token_type::literal_or_value:
5598                 return "'[', '{', or a literal";
5599             // LCOV_EXCL_START
5600             default: // catch non-enum values
5601                 return "unknown token";
5602                 // LCOV_EXCL_STOP
5603         }
5604     }
5605 
lexer(detail::input_adapter_t && adapter)5606     explicit lexer(detail::input_adapter_t&& adapter)
5607         : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
5608 
5609     // delete because of pointer members
5610     lexer(const lexer&) = delete;
5611     lexer(lexer&&) = delete;
5612     lexer& operator=(lexer&) = delete;
5613     lexer& operator=(lexer&&) = delete;
5614     ~lexer() = default;
5615 
5616   private:
5617     /////////////////////
5618     // locales
5619     /////////////////////
5620 
5621     /// return the locale-dependent decimal point
get_decimal_point()5622     static char get_decimal_point() noexcept
5623     {
5624         const auto loc = localeconv();
5625         assert(loc != nullptr);
5626         return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
5627     }
5628 
5629     /////////////////////
5630     // scan functions
5631     /////////////////////
5632 
5633     /*!
5634     @brief get codepoint from 4 hex characters following `\u`
5635 
5636     For input "\u c1 c2 c3 c4" the codepoint is:
5637       (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
5638     = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
5639 
5640     Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
5641     must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
5642     conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
5643     between the ASCII value of the character and the desired integer value.
5644 
5645     @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
5646             non-hex character)
5647     */
get_codepoint()5648     int get_codepoint()
5649     {
5650         // this function only makes sense after reading `\u`
5651         assert(current == 'u');
5652         int codepoint = 0;
5653 
5654         const auto factors = { 12u, 8u, 4u, 0u };
5655         for (const auto factor : factors)
5656         {
5657             get();
5658 
5659             if (current >= '0' and current <= '9')
5660             {
5661                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
5662             }
5663             else if (current >= 'A' and current <= 'F')
5664             {
5665                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
5666             }
5667             else if (current >= 'a' and current <= 'f')
5668             {
5669                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
5670             }
5671             else
5672             {
5673                 return -1;
5674             }
5675         }
5676 
5677         assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
5678         return codepoint;
5679     }
5680 
5681     /*!
5682     @brief check if the next byte(s) are inside a given range
5683 
5684     Adds the current byte and, for each passed range, reads a new byte and
5685     checks if it is inside the range. If a violation was detected, set up an
5686     error message and return false. Otherwise, return true.
5687 
5688     @param[in] ranges  list of integers; interpreted as list of pairs of
5689                        inclusive lower and upper bound, respectively
5690 
5691     @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
5692          1, 2, or 3 pairs. This precondition is enforced by an assertion.
5693 
5694     @return true if and only if no range violation was detected
5695     */
next_byte_in_range(std::initializer_list<int> ranges)5696     bool next_byte_in_range(std::initializer_list<int> ranges)
5697     {
5698         assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
5699         add(current);
5700 
5701         for (auto range = ranges.begin(); range != ranges.end(); ++range)
5702         {
5703             get();
5704             if (JSON_LIKELY(*range <= current and current <= *(++range)))
5705             {
5706                 add(current);
5707             }
5708             else
5709             {
5710                 error_message = "invalid string: ill-formed UTF-8 byte";
5711                 return false;
5712             }
5713         }
5714 
5715         return true;
5716     }
5717 
5718     /*!
5719     @brief scan a string literal
5720 
5721     This function scans a string according to Sect. 7 of RFC 7159. While
5722     scanning, bytes are escaped and copied into buffer token_buffer. Then the
5723     function returns successfully, token_buffer is *not* null-terminated (as it
5724     may contain \0 bytes), and token_buffer.size() is the number of bytes in the
5725     string.
5726 
5727     @return token_type::value_string if string could be successfully scanned,
5728             token_type::parse_error otherwise
5729 
5730     @note In case of errors, variable error_message contains a textual
5731           description.
5732     */
scan_string()5733     token_type scan_string()
5734     {
5735         // reset token_buffer (ignore opening quote)
5736         reset();
5737 
5738         // we entered the function by reading an open quote
5739         assert(current == '\"');
5740 
5741         while (true)
5742         {
5743             // get next character
5744             switch (get())
5745             {
5746                 // end of file while parsing string
5747                 case std::char_traits<char>::eof():
5748                 {
5749                     error_message = "invalid string: missing closing quote";
5750                     return token_type::parse_error;
5751                 }
5752 
5753                 // closing quote
5754                 case '\"':
5755                 {
5756                     return token_type::value_string;
5757                 }
5758 
5759                 // escapes
5760                 case '\\':
5761                 {
5762                     switch (get())
5763                     {
5764                         // quotation mark
5765                         case '\"':
5766                             add('\"');
5767                             break;
5768                         // reverse solidus
5769                         case '\\':
5770                             add('\\');
5771                             break;
5772                         // solidus
5773                         case '/':
5774                             add('/');
5775                             break;
5776                         // backspace
5777                         case 'b':
5778                             add('\b');
5779                             break;
5780                         // form feed
5781                         case 'f':
5782                             add('\f');
5783                             break;
5784                         // line feed
5785                         case 'n':
5786                             add('\n');
5787                             break;
5788                         // carriage return
5789                         case 'r':
5790                             add('\r');
5791                             break;
5792                         // tab
5793                         case 't':
5794                             add('\t');
5795                             break;
5796 
5797                         // unicode escapes
5798                         case 'u':
5799                         {
5800                             const int codepoint1 = get_codepoint();
5801                             int codepoint = codepoint1; // start with codepoint1
5802 
5803                             if (JSON_UNLIKELY(codepoint1 == -1))
5804                             {
5805                                 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
5806                                 return token_type::parse_error;
5807                             }
5808 
5809                             // check if code point is a high surrogate
5810                             if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
5811                             {
5812                                 // expect next \uxxxx entry
5813                                 if (JSON_LIKELY(get() == '\\' and get() == 'u'))
5814                                 {
5815                                     const int codepoint2 = get_codepoint();
5816 
5817                                     if (JSON_UNLIKELY(codepoint2 == -1))
5818                                     {
5819                                         error_message = "invalid string: '\\u' must be followed by 4 hex digits";
5820                                         return token_type::parse_error;
5821                                     }
5822 
5823                                     // check if codepoint2 is a low surrogate
5824                                     if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
5825                                     {
5826                                         // overwrite codepoint
5827                                         codepoint = static_cast<int>(
5828                                                         // high surrogate occupies the most significant 22 bits
5829                                                         (static_cast<unsigned int>(codepoint1) << 10u)
5830                                                         // low surrogate occupies the least significant 15 bits
5831                                                         + static_cast<unsigned int>(codepoint2)
5832                                                         // there is still the 0xD800, 0xDC00 and 0x10000 noise
5833                                                         // in the result so we have to subtract with:
5834                                                         // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
5835                                                         - 0x35FDC00u);
5836                                     }
5837                                     else
5838                                     {
5839                                         error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5840                                         return token_type::parse_error;
5841                                     }
5842                                 }
5843                                 else
5844                                 {
5845                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5846                                     return token_type::parse_error;
5847                                 }
5848                             }
5849                             else
5850                             {
5851                                 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
5852                                 {
5853                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
5854                                     return token_type::parse_error;
5855                                 }
5856                             }
5857 
5858                             // result of the above calculation yields a proper codepoint
5859                             assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
5860 
5861                             // translate codepoint into bytes
5862                             if (codepoint < 0x80)
5863                             {
5864                                 // 1-byte characters: 0xxxxxxx (ASCII)
5865                                 add(codepoint);
5866                             }
5867                             else if (codepoint <= 0x7FF)
5868                             {
5869                                 // 2-byte characters: 110xxxxx 10xxxxxx
5870                                 add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
5871                                 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5872                             }
5873                             else if (codepoint <= 0xFFFF)
5874                             {
5875                                 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
5876                                 add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
5877                                 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5878                                 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5879                             }
5880                             else
5881                             {
5882                                 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5883                                 add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
5884                                 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
5885                                 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5886                                 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5887                             }
5888 
5889                             break;
5890                         }
5891 
5892                         // other characters after escape
5893                         default:
5894                             error_message = "invalid string: forbidden character after backslash";
5895                             return token_type::parse_error;
5896                     }
5897 
5898                     break;
5899                 }
5900 
5901                 // invalid control characters
5902                 case 0x00:
5903                 {
5904                     error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
5905                     return token_type::parse_error;
5906                 }
5907 
5908                 case 0x01:
5909                 {
5910                     error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
5911                     return token_type::parse_error;
5912                 }
5913 
5914                 case 0x02:
5915                 {
5916                     error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
5917                     return token_type::parse_error;
5918                 }
5919 
5920                 case 0x03:
5921                 {
5922                     error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
5923                     return token_type::parse_error;
5924                 }
5925 
5926                 case 0x04:
5927                 {
5928                     error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
5929                     return token_type::parse_error;
5930                 }
5931 
5932                 case 0x05:
5933                 {
5934                     error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
5935                     return token_type::parse_error;
5936                 }
5937 
5938                 case 0x06:
5939                 {
5940                     error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
5941                     return token_type::parse_error;
5942                 }
5943 
5944                 case 0x07:
5945                 {
5946                     error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
5947                     return token_type::parse_error;
5948                 }
5949 
5950                 case 0x08:
5951                 {
5952                     error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
5953                     return token_type::parse_error;
5954                 }
5955 
5956                 case 0x09:
5957                 {
5958                     error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
5959                     return token_type::parse_error;
5960                 }
5961 
5962                 case 0x0A:
5963                 {
5964                     error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
5965                     return token_type::parse_error;
5966                 }
5967 
5968                 case 0x0B:
5969                 {
5970                     error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
5971                     return token_type::parse_error;
5972                 }
5973 
5974                 case 0x0C:
5975                 {
5976                     error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
5977                     return token_type::parse_error;
5978                 }
5979 
5980                 case 0x0D:
5981                 {
5982                     error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
5983                     return token_type::parse_error;
5984                 }
5985 
5986                 case 0x0E:
5987                 {
5988                     error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
5989                     return token_type::parse_error;
5990                 }
5991 
5992                 case 0x0F:
5993                 {
5994                     error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
5995                     return token_type::parse_error;
5996                 }
5997 
5998                 case 0x10:
5999                 {
6000                     error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6001                     return token_type::parse_error;
6002                 }
6003 
6004                 case 0x11:
6005                 {
6006                     error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6007                     return token_type::parse_error;
6008                 }
6009 
6010                 case 0x12:
6011                 {
6012                     error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6013                     return token_type::parse_error;
6014                 }
6015 
6016                 case 0x13:
6017                 {
6018                     error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6019                     return token_type::parse_error;
6020                 }
6021 
6022                 case 0x14:
6023                 {
6024                     error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6025                     return token_type::parse_error;
6026                 }
6027 
6028                 case 0x15:
6029                 {
6030                     error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6031                     return token_type::parse_error;
6032                 }
6033 
6034                 case 0x16:
6035                 {
6036                     error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6037                     return token_type::parse_error;
6038                 }
6039 
6040                 case 0x17:
6041                 {
6042                     error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6043                     return token_type::parse_error;
6044                 }
6045 
6046                 case 0x18:
6047                 {
6048                     error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6049                     return token_type::parse_error;
6050                 }
6051 
6052                 case 0x19:
6053                 {
6054                     error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6055                     return token_type::parse_error;
6056                 }
6057 
6058                 case 0x1A:
6059                 {
6060                     error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6061                     return token_type::parse_error;
6062                 }
6063 
6064                 case 0x1B:
6065                 {
6066                     error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6067                     return token_type::parse_error;
6068                 }
6069 
6070                 case 0x1C:
6071                 {
6072                     error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6073                     return token_type::parse_error;
6074                 }
6075 
6076                 case 0x1D:
6077                 {
6078                     error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6079                     return token_type::parse_error;
6080                 }
6081 
6082                 case 0x1E:
6083                 {
6084                     error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6085                     return token_type::parse_error;
6086                 }
6087 
6088                 case 0x1F:
6089                 {
6090                     error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6091                     return token_type::parse_error;
6092                 }
6093 
6094                 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6095                 case 0x20:
6096                 case 0x21:
6097                 case 0x23:
6098                 case 0x24:
6099                 case 0x25:
6100                 case 0x26:
6101                 case 0x27:
6102                 case 0x28:
6103                 case 0x29:
6104                 case 0x2A:
6105                 case 0x2B:
6106                 case 0x2C:
6107                 case 0x2D:
6108                 case 0x2E:
6109                 case 0x2F:
6110                 case 0x30:
6111                 case 0x31:
6112                 case 0x32:
6113                 case 0x33:
6114                 case 0x34:
6115                 case 0x35:
6116                 case 0x36:
6117                 case 0x37:
6118                 case 0x38:
6119                 case 0x39:
6120                 case 0x3A:
6121                 case 0x3B:
6122                 case 0x3C:
6123                 case 0x3D:
6124                 case 0x3E:
6125                 case 0x3F:
6126                 case 0x40:
6127                 case 0x41:
6128                 case 0x42:
6129                 case 0x43:
6130                 case 0x44:
6131                 case 0x45:
6132                 case 0x46:
6133                 case 0x47:
6134                 case 0x48:
6135                 case 0x49:
6136                 case 0x4A:
6137                 case 0x4B:
6138                 case 0x4C:
6139                 case 0x4D:
6140                 case 0x4E:
6141                 case 0x4F:
6142                 case 0x50:
6143                 case 0x51:
6144                 case 0x52:
6145                 case 0x53:
6146                 case 0x54:
6147                 case 0x55:
6148                 case 0x56:
6149                 case 0x57:
6150                 case 0x58:
6151                 case 0x59:
6152                 case 0x5A:
6153                 case 0x5B:
6154                 case 0x5D:
6155                 case 0x5E:
6156                 case 0x5F:
6157                 case 0x60:
6158                 case 0x61:
6159                 case 0x62:
6160                 case 0x63:
6161                 case 0x64:
6162                 case 0x65:
6163                 case 0x66:
6164                 case 0x67:
6165                 case 0x68:
6166                 case 0x69:
6167                 case 0x6A:
6168                 case 0x6B:
6169                 case 0x6C:
6170                 case 0x6D:
6171                 case 0x6E:
6172                 case 0x6F:
6173                 case 0x70:
6174                 case 0x71:
6175                 case 0x72:
6176                 case 0x73:
6177                 case 0x74:
6178                 case 0x75:
6179                 case 0x76:
6180                 case 0x77:
6181                 case 0x78:
6182                 case 0x79:
6183                 case 0x7A:
6184                 case 0x7B:
6185                 case 0x7C:
6186                 case 0x7D:
6187                 case 0x7E:
6188                 case 0x7F:
6189                 {
6190                     add(current);
6191                     break;
6192                 }
6193 
6194                 // U+0080..U+07FF: bytes C2..DF 80..BF
6195                 case 0xC2:
6196                 case 0xC3:
6197                 case 0xC4:
6198                 case 0xC5:
6199                 case 0xC6:
6200                 case 0xC7:
6201                 case 0xC8:
6202                 case 0xC9:
6203                 case 0xCA:
6204                 case 0xCB:
6205                 case 0xCC:
6206                 case 0xCD:
6207                 case 0xCE:
6208                 case 0xCF:
6209                 case 0xD0:
6210                 case 0xD1:
6211                 case 0xD2:
6212                 case 0xD3:
6213                 case 0xD4:
6214                 case 0xD5:
6215                 case 0xD6:
6216                 case 0xD7:
6217                 case 0xD8:
6218                 case 0xD9:
6219                 case 0xDA:
6220                 case 0xDB:
6221                 case 0xDC:
6222                 case 0xDD:
6223                 case 0xDE:
6224                 case 0xDF:
6225                 {
6226                     if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
6227                     {
6228                         return token_type::parse_error;
6229                     }
6230                     break;
6231                 }
6232 
6233                 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6234                 case 0xE0:
6235                 {
6236                     if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6237                     {
6238                         return token_type::parse_error;
6239                     }
6240                     break;
6241                 }
6242 
6243                 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6244                 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6245                 case 0xE1:
6246                 case 0xE2:
6247                 case 0xE3:
6248                 case 0xE4:
6249                 case 0xE5:
6250                 case 0xE6:
6251                 case 0xE7:
6252                 case 0xE8:
6253                 case 0xE9:
6254                 case 0xEA:
6255                 case 0xEB:
6256                 case 0xEC:
6257                 case 0xEE:
6258                 case 0xEF:
6259                 {
6260                     if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6261                     {
6262                         return token_type::parse_error;
6263                     }
6264                     break;
6265                 }
6266 
6267                 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6268                 case 0xED:
6269                 {
6270                     if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6271                     {
6272                         return token_type::parse_error;
6273                     }
6274                     break;
6275                 }
6276 
6277                 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6278                 case 0xF0:
6279                 {
6280                     if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6281                     {
6282                         return token_type::parse_error;
6283                     }
6284                     break;
6285                 }
6286 
6287                 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6288                 case 0xF1:
6289                 case 0xF2:
6290                 case 0xF3:
6291                 {
6292                     if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6293                     {
6294                         return token_type::parse_error;
6295                     }
6296                     break;
6297                 }
6298 
6299                 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6300                 case 0xF4:
6301                 {
6302                     if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6303                     {
6304                         return token_type::parse_error;
6305                     }
6306                     break;
6307                 }
6308 
6309                 // remaining bytes (80..C1 and F5..FF) are ill-formed
6310                 default:
6311                 {
6312                     error_message = "invalid string: ill-formed UTF-8 byte";
6313                     return token_type::parse_error;
6314                 }
6315             }
6316         }
6317     }
6318 
strtof(float & f,const char * str,char ** endptr)6319     static void strtof(float& f, const char* str, char** endptr) noexcept
6320     {
6321         f = std::strtof(str, endptr);
6322     }
6323 
strtof(double & f,const char * str,char ** endptr)6324     static void strtof(double& f, const char* str, char** endptr) noexcept
6325     {
6326         f = std::strtod(str, endptr);
6327     }
6328 
strtof(long double & f,const char * str,char ** endptr)6329     static void strtof(long double& f, const char* str, char** endptr) noexcept
6330     {
6331         f = std::strtold(str, endptr);
6332     }
6333 
6334     /*!
6335     @brief scan a number literal
6336 
6337     This function scans a string according to Sect. 6 of RFC 7159.
6338 
6339     The function is realized with a deterministic finite state machine derived
6340     from the grammar described in RFC 7159. Starting in state "init", the
6341     input is read and used to determined the next state. Only state "done"
6342     accepts the number. State "error" is a trap state to model errors. In the
6343     table below, "anything" means any character but the ones listed before.
6344 
6345     state    | 0        | 1-9      | e E      | +       | -       | .        | anything
6346     ---------|----------|----------|----------|---------|---------|----------|-----------
6347     init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
6348     minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
6349     zero     | done     | done     | exponent | done    | done    | decimal1 | done
6350     any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
6351     decimal1 | decimal2 | [error]  | [error]  | [error] | [error] | [error]  | [error]
6352     decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
6353     exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
6354     sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
6355     any2     | any2     | any2     | done     | done    | done    | done     | done
6356 
6357     The state machine is realized with one label per state (prefixed with
6358     "scan_number_") and `goto` statements between them. The state machine
6359     contains cycles, but any cycle can be left when EOF is read. Therefore,
6360     the function is guaranteed to terminate.
6361 
6362     During scanning, the read bytes are stored in token_buffer. This string is
6363     then converted to a signed integer, an unsigned integer, or a
6364     floating-point number.
6365 
6366     @return token_type::value_unsigned, token_type::value_integer, or
6367             token_type::value_float if number could be successfully scanned,
6368             token_type::parse_error otherwise
6369 
6370     @note The scanner is independent of the current locale. Internally, the
6371           locale's decimal point is used instead of `.` to work with the
6372           locale-dependent converters.
6373     */
scan_number()6374     token_type scan_number()  // lgtm [cpp/use-of-goto]
6375     {
6376         // reset token_buffer to store the number's bytes
6377         reset();
6378 
6379         // the type of the parsed number; initially set to unsigned; will be
6380         // changed if minus sign, decimal point or exponent is read
6381         token_type number_type = token_type::value_unsigned;
6382 
6383         // state (init): we just found out we need to scan a number
6384         switch (current)
6385         {
6386             case '-':
6387             {
6388                 add(current);
6389                 goto scan_number_minus;
6390             }
6391 
6392             case '0':
6393             {
6394                 add(current);
6395                 goto scan_number_zero;
6396             }
6397 
6398             case '1':
6399             case '2':
6400             case '3':
6401             case '4':
6402             case '5':
6403             case '6':
6404             case '7':
6405             case '8':
6406             case '9':
6407             {
6408                 add(current);
6409                 goto scan_number_any1;
6410             }
6411 
6412             // all other characters are rejected outside scan_number()
6413             default:            // LCOV_EXCL_LINE
6414                 assert(false);  // LCOV_EXCL_LINE
6415         }
6416 
6417 scan_number_minus:
6418         // state: we just parsed a leading minus sign
6419         number_type = token_type::value_integer;
6420         switch (get())
6421         {
6422             case '0':
6423             {
6424                 add(current);
6425                 goto scan_number_zero;
6426             }
6427 
6428             case '1':
6429             case '2':
6430             case '3':
6431             case '4':
6432             case '5':
6433             case '6':
6434             case '7':
6435             case '8':
6436             case '9':
6437             {
6438                 add(current);
6439                 goto scan_number_any1;
6440             }
6441 
6442             default:
6443             {
6444                 error_message = "invalid number; expected digit after '-'";
6445                 return token_type::parse_error;
6446             }
6447         }
6448 
6449 scan_number_zero:
6450         // state: we just parse a zero (maybe with a leading minus sign)
6451         switch (get())
6452         {
6453             case '.':
6454             {
6455                 add(decimal_point_char);
6456                 goto scan_number_decimal1;
6457             }
6458 
6459             case 'e':
6460             case 'E':
6461             {
6462                 add(current);
6463                 goto scan_number_exponent;
6464             }
6465 
6466             default:
6467                 goto scan_number_done;
6468         }
6469 
6470 scan_number_any1:
6471         // state: we just parsed a number 0-9 (maybe with a leading minus sign)
6472         switch (get())
6473         {
6474             case '0':
6475             case '1':
6476             case '2':
6477             case '3':
6478             case '4':
6479             case '5':
6480             case '6':
6481             case '7':
6482             case '8':
6483             case '9':
6484             {
6485                 add(current);
6486                 goto scan_number_any1;
6487             }
6488 
6489             case '.':
6490             {
6491                 add(decimal_point_char);
6492                 goto scan_number_decimal1;
6493             }
6494 
6495             case 'e':
6496             case 'E':
6497             {
6498                 add(current);
6499                 goto scan_number_exponent;
6500             }
6501 
6502             default:
6503                 goto scan_number_done;
6504         }
6505 
6506 scan_number_decimal1:
6507         // state: we just parsed a decimal point
6508         number_type = token_type::value_float;
6509         switch (get())
6510         {
6511             case '0':
6512             case '1':
6513             case '2':
6514             case '3':
6515             case '4':
6516             case '5':
6517             case '6':
6518             case '7':
6519             case '8':
6520             case '9':
6521             {
6522                 add(current);
6523                 goto scan_number_decimal2;
6524             }
6525 
6526             default:
6527             {
6528                 error_message = "invalid number; expected digit after '.'";
6529                 return token_type::parse_error;
6530             }
6531         }
6532 
6533 scan_number_decimal2:
6534         // we just parsed at least one number after a decimal point
6535         switch (get())
6536         {
6537             case '0':
6538             case '1':
6539             case '2':
6540             case '3':
6541             case '4':
6542             case '5':
6543             case '6':
6544             case '7':
6545             case '8':
6546             case '9':
6547             {
6548                 add(current);
6549                 goto scan_number_decimal2;
6550             }
6551 
6552             case 'e':
6553             case 'E':
6554             {
6555                 add(current);
6556                 goto scan_number_exponent;
6557             }
6558 
6559             default:
6560                 goto scan_number_done;
6561         }
6562 
6563 scan_number_exponent:
6564         // we just parsed an exponent
6565         number_type = token_type::value_float;
6566         switch (get())
6567         {
6568             case '+':
6569             case '-':
6570             {
6571                 add(current);
6572                 goto scan_number_sign;
6573             }
6574 
6575             case '0':
6576             case '1':
6577             case '2':
6578             case '3':
6579             case '4':
6580             case '5':
6581             case '6':
6582             case '7':
6583             case '8':
6584             case '9':
6585             {
6586                 add(current);
6587                 goto scan_number_any2;
6588             }
6589 
6590             default:
6591             {
6592                 error_message =
6593                     "invalid number; expected '+', '-', or digit after exponent";
6594                 return token_type::parse_error;
6595             }
6596         }
6597 
6598 scan_number_sign:
6599         // we just parsed an exponent sign
6600         switch (get())
6601         {
6602             case '0':
6603             case '1':
6604             case '2':
6605             case '3':
6606             case '4':
6607             case '5':
6608             case '6':
6609             case '7':
6610             case '8':
6611             case '9':
6612             {
6613                 add(current);
6614                 goto scan_number_any2;
6615             }
6616 
6617             default:
6618             {
6619                 error_message = "invalid number; expected digit after exponent sign";
6620                 return token_type::parse_error;
6621             }
6622         }
6623 
6624 scan_number_any2:
6625         // we just parsed a number after the exponent or exponent sign
6626         switch (get())
6627         {
6628             case '0':
6629             case '1':
6630             case '2':
6631             case '3':
6632             case '4':
6633             case '5':
6634             case '6':
6635             case '7':
6636             case '8':
6637             case '9':
6638             {
6639                 add(current);
6640                 goto scan_number_any2;
6641             }
6642 
6643             default:
6644                 goto scan_number_done;
6645         }
6646 
6647 scan_number_done:
6648         // unget the character after the number (we only read it to know that
6649         // we are done scanning a number)
6650         unget();
6651 
6652         char* endptr = nullptr;
6653         errno = 0;
6654 
6655         // try to parse integers first and fall back to floats
6656         if (number_type == token_type::value_unsigned)
6657         {
6658             const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
6659 
6660             // we checked the number format before
6661             assert(endptr == token_buffer.data() + token_buffer.size());
6662 
6663             if (errno == 0)
6664             {
6665                 value_unsigned = static_cast<number_unsigned_t>(x);
6666                 if (value_unsigned == x)
6667                 {
6668                     return token_type::value_unsigned;
6669                 }
6670             }
6671         }
6672         else if (number_type == token_type::value_integer)
6673         {
6674             const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
6675 
6676             // we checked the number format before
6677             assert(endptr == token_buffer.data() + token_buffer.size());
6678 
6679             if (errno == 0)
6680             {
6681                 value_integer = static_cast<number_integer_t>(x);
6682                 if (value_integer == x)
6683                 {
6684                     return token_type::value_integer;
6685                 }
6686             }
6687         }
6688 
6689         // this code is reached if we parse a floating-point number or if an
6690         // integer conversion above failed
6691         strtof(value_float, token_buffer.data(), &endptr);
6692 
6693         // we checked the number format before
6694         assert(endptr == token_buffer.data() + token_buffer.size());
6695 
6696         return token_type::value_float;
6697     }
6698 
6699     /*!
6700     @param[in] literal_text  the literal text to expect
6701     @param[in] length        the length of the passed literal text
6702     @param[in] return_type   the token type to return on success
6703     */
scan_literal(const char * literal_text,const std::size_t length,token_type return_type)6704     token_type scan_literal(const char* literal_text, const std::size_t length,
6705                             token_type return_type)
6706     {
6707         assert(current == literal_text[0]);
6708         for (std::size_t i = 1; i < length; ++i)
6709         {
6710             if (JSON_UNLIKELY(get() != literal_text[i]))
6711             {
6712                 error_message = "invalid literal";
6713                 return token_type::parse_error;
6714             }
6715         }
6716         return return_type;
6717     }
6718 
6719     /////////////////////
6720     // input management
6721     /////////////////////
6722 
6723     /// reset token_buffer; current character is beginning of token
reset()6724     void reset() noexcept
6725     {
6726         token_buffer.clear();
6727         token_string.clear();
6728         token_string.push_back(std::char_traits<char>::to_char_type(current));
6729     }
6730 
6731     /*
6732     @brief get next character from the input
6733 
6734     This function provides the interface to the used input adapter. It does
6735     not throw in case the input reached EOF, but returns a
6736     `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
6737     for use in error messages.
6738 
6739     @return character read from the input
6740     */
get()6741     std::char_traits<char>::int_type get()
6742     {
6743         ++position.chars_read_total;
6744         ++position.chars_read_current_line;
6745 
6746         if (next_unget)
6747         {
6748             // just reset the next_unget variable and work with current
6749             next_unget = false;
6750         }
6751         else
6752         {
6753             current = ia->get_character();
6754         }
6755 
6756         if (JSON_LIKELY(current != std::char_traits<char>::eof()))
6757         {
6758             token_string.push_back(std::char_traits<char>::to_char_type(current));
6759         }
6760 
6761         if (current == '\n')
6762         {
6763             ++position.lines_read;
6764             position.chars_read_current_line = 0;
6765         }
6766 
6767         return current;
6768     }
6769 
6770     /*!
6771     @brief unget current character (read it again on next get)
6772 
6773     We implement unget by setting variable next_unget to true. The input is not
6774     changed - we just simulate ungetting by modifying chars_read_total,
6775     chars_read_current_line, and token_string. The next call to get() will
6776     behave as if the unget character is read again.
6777     */
unget()6778     void unget()
6779     {
6780         next_unget = true;
6781 
6782         --position.chars_read_total;
6783 
6784         // in case we "unget" a newline, we have to also decrement the lines_read
6785         if (position.chars_read_current_line == 0)
6786         {
6787             if (position.lines_read > 0)
6788             {
6789                 --position.lines_read;
6790             }
6791         }
6792         else
6793         {
6794             --position.chars_read_current_line;
6795         }
6796 
6797         if (JSON_LIKELY(current != std::char_traits<char>::eof()))
6798         {
6799             assert(not token_string.empty());
6800             token_string.pop_back();
6801         }
6802     }
6803 
6804     /// add a character to token_buffer
add(int c)6805     void add(int c)
6806     {
6807         token_buffer.push_back(std::char_traits<char>::to_char_type(c));
6808     }
6809 
6810   public:
6811     /////////////////////
6812     // value getters
6813     /////////////////////
6814 
6815     /// return integer value
get_number_integer() const6816     constexpr number_integer_t get_number_integer() const noexcept
6817     {
6818         return value_integer;
6819     }
6820 
6821     /// return unsigned integer value
get_number_unsigned() const6822     constexpr number_unsigned_t get_number_unsigned() const noexcept
6823     {
6824         return value_unsigned;
6825     }
6826 
6827     /// return floating-point value
get_number_float() const6828     constexpr number_float_t get_number_float() const noexcept
6829     {
6830         return value_float;
6831     }
6832 
6833     /// return current string value (implicitly resets the token; useful only once)
get_string()6834     string_t& get_string()
6835     {
6836         return token_buffer;
6837     }
6838 
6839     /////////////////////
6840     // diagnostics
6841     /////////////////////
6842 
6843     /// return position of last read token
get_position() const6844     constexpr position_t get_position() const noexcept
6845     {
6846         return position;
6847     }
6848 
6849     /// return the last read token (for errors only).  Will never contain EOF
6850     /// (an arbitrary value that is not a valid char value, often -1), because
6851     /// 255 may legitimately occur.  May contain NUL, which should be escaped.
get_token_string() const6852     std::string get_token_string() const
6853     {
6854         // escape control characters
6855         std::string result;
6856         for (const auto c : token_string)
6857         {
6858             if ('\x00' <= c and c <= '\x1F')
6859             {
6860                 // escape control characters
6861                 std::array<char, 9> cs{{}};
6862                 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
6863                 result += cs.data();
6864             }
6865             else
6866             {
6867                 // add character as is
6868                 result.push_back(c);
6869             }
6870         }
6871 
6872         return result;
6873     }
6874 
6875     /// return syntax error message
get_error_message() const6876     constexpr const char* get_error_message() const noexcept
6877     {
6878         return error_message;
6879     }
6880 
6881     /////////////////////
6882     // actual scanner
6883     /////////////////////
6884 
6885     /*!
6886     @brief skip the UTF-8 byte order mark
6887     @return true iff there is no BOM or the correct BOM has been skipped
6888     */
skip_bom()6889     bool skip_bom()
6890     {
6891         if (get() == 0xEF)
6892         {
6893             // check if we completely parse the BOM
6894             return get() == 0xBB and get() == 0xBF;
6895         }
6896 
6897         // the first character is not the beginning of the BOM; unget it to
6898         // process is later
6899         unget();
6900         return true;
6901     }
6902 
scan()6903     token_type scan()
6904     {
6905         // initially, skip the BOM
6906         if (position.chars_read_total == 0 and not skip_bom())
6907         {
6908             error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
6909             return token_type::parse_error;
6910         }
6911 
6912         // read next character and ignore whitespace
6913         do
6914         {
6915             get();
6916         }
6917         while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
6918 
6919         switch (current)
6920         {
6921             // structural characters
6922             case '[':
6923                 return token_type::begin_array;
6924             case ']':
6925                 return token_type::end_array;
6926             case '{':
6927                 return token_type::begin_object;
6928             case '}':
6929                 return token_type::end_object;
6930             case ':':
6931                 return token_type::name_separator;
6932             case ',':
6933                 return token_type::value_separator;
6934 
6935             // literals
6936             case 't':
6937                 return scan_literal("true", 4, token_type::literal_true);
6938             case 'f':
6939                 return scan_literal("false", 5, token_type::literal_false);
6940             case 'n':
6941                 return scan_literal("null", 4, token_type::literal_null);
6942 
6943             // string
6944             case '\"':
6945                 return scan_string();
6946 
6947             // number
6948             case '-':
6949             case '0':
6950             case '1':
6951             case '2':
6952             case '3':
6953             case '4':
6954             case '5':
6955             case '6':
6956             case '7':
6957             case '8':
6958             case '9':
6959                 return scan_number();
6960 
6961             // end of input (the null byte is needed when parsing from
6962             // string literals)
6963             case '\0':
6964             case std::char_traits<char>::eof():
6965                 return token_type::end_of_input;
6966 
6967             // error
6968             default:
6969                 error_message = "invalid literal";
6970                 return token_type::parse_error;
6971         }
6972     }
6973 
6974   private:
6975     /// input adapter
6976     detail::input_adapter_t ia = nullptr;
6977 
6978     /// the current character
6979     std::char_traits<char>::int_type current = std::char_traits<char>::eof();
6980 
6981     /// whether the next get() call should just return current
6982     bool next_unget = false;
6983 
6984     /// the start position of the current token
6985     position_t position {};
6986 
6987     /// raw input token string (for error messages)
6988     std::vector<char> token_string {};
6989 
6990     /// buffer for variable-length tokens (numbers, strings)
6991     string_t token_buffer {};
6992 
6993     /// a description of occurred lexer errors
6994     const char* error_message = "";
6995 
6996     // number values
6997     number_integer_t value_integer = 0;
6998     number_unsigned_t value_unsigned = 0;
6999     number_float_t value_float = 0;
7000 
7001     /// the decimal point
7002     const char decimal_point_char = '.';
7003 };
7004 }  // namespace detail
7005 }  // namespace nlohmann
7006 
7007 // #include <nlohmann/detail/input/parser.hpp>
7008 
7009 
7010 #include <cassert> // assert
7011 #include <cmath> // isfinite
7012 #include <cstdint> // uint8_t
7013 #include <functional> // function
7014 #include <string> // string
7015 #include <utility> // move
7016 #include <vector> // vector
7017 
7018 // #include <nlohmann/detail/exceptions.hpp>
7019 
7020 // #include <nlohmann/detail/input/input_adapters.hpp>
7021 
7022 // #include <nlohmann/detail/input/json_sax.hpp>
7023 
7024 // #include <nlohmann/detail/input/lexer.hpp>
7025 
7026 // #include <nlohmann/detail/macro_scope.hpp>
7027 
7028 // #include <nlohmann/detail/meta/is_sax.hpp>
7029 
7030 // #include <nlohmann/detail/value_t.hpp>
7031 
7032 
7033 namespace nlohmann
7034 {
7035 namespace detail
7036 {
7037 ////////////
7038 // parser //
7039 ////////////
7040 
7041 /*!
7042 @brief syntax analysis
7043 
7044 This class implements a recursive decent parser.
7045 */
7046 template<typename BasicJsonType>
7047 class parser
7048 {
7049     using number_integer_t = typename BasicJsonType::number_integer_t;
7050     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7051     using number_float_t = typename BasicJsonType::number_float_t;
7052     using string_t = typename BasicJsonType::string_t;
7053     using lexer_t = lexer<BasicJsonType>;
7054     using token_type = typename lexer_t::token_type;
7055 
7056   public:
7057     enum class parse_event_t : uint8_t
7058     {
7059         /// the parser read `{` and started to process a JSON object
7060         object_start,
7061         /// the parser read `}` and finished processing a JSON object
7062         object_end,
7063         /// the parser read `[` and started to process a JSON array
7064         array_start,
7065         /// the parser read `]` and finished processing a JSON array
7066         array_end,
7067         /// the parser read a key of a value in an object
7068         key,
7069         /// the parser finished reading a JSON value
7070         value
7071     };
7072 
7073     using parser_callback_t =
7074         std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
7075 
7076     /// a parser reading from an input adapter
parser(detail::input_adapter_t && adapter,const parser_callback_t cb=nullptr,const bool allow_exceptions_=true)7077     explicit parser(detail::input_adapter_t&& adapter,
7078                     const parser_callback_t cb = nullptr,
7079                     const bool allow_exceptions_ = true)
7080         : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
7081     {
7082         // read first token
7083         get_token();
7084     }
7085 
7086     /*!
7087     @brief public parser interface
7088 
7089     @param[in] strict      whether to expect the last token to be EOF
7090     @param[in,out] result  parsed JSON value
7091 
7092     @throw parse_error.101 in case of an unexpected token
7093     @throw parse_error.102 if to_unicode fails or surrogate error
7094     @throw parse_error.103 if to_unicode fails
7095     */
parse(const bool strict,BasicJsonType & result)7096     void parse(const bool strict, BasicJsonType& result)
7097     {
7098         if (callback)
7099         {
7100             json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
7101             sax_parse_internal(&sdp);
7102             result.assert_invariant();
7103 
7104             // in strict mode, input must be completely read
7105             if (strict and (get_token() != token_type::end_of_input))
7106             {
7107                 sdp.parse_error(m_lexer.get_position(),
7108                                 m_lexer.get_token_string(),
7109                                 parse_error::create(101, m_lexer.get_position(),
7110                                                     exception_message(token_type::end_of_input, "value")));
7111             }
7112 
7113             // in case of an error, return discarded value
7114             if (sdp.is_errored())
7115             {
7116                 result = value_t::discarded;
7117                 return;
7118             }
7119 
7120             // set top-level value to null if it was discarded by the callback
7121             // function
7122             if (result.is_discarded())
7123             {
7124                 result = nullptr;
7125             }
7126         }
7127         else
7128         {
7129             json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
7130             sax_parse_internal(&sdp);
7131             result.assert_invariant();
7132 
7133             // in strict mode, input must be completely read
7134             if (strict and (get_token() != token_type::end_of_input))
7135             {
7136                 sdp.parse_error(m_lexer.get_position(),
7137                                 m_lexer.get_token_string(),
7138                                 parse_error::create(101, m_lexer.get_position(),
7139                                                     exception_message(token_type::end_of_input, "value")));
7140             }
7141 
7142             // in case of an error, return discarded value
7143             if (sdp.is_errored())
7144             {
7145                 result = value_t::discarded;
7146                 return;
7147             }
7148         }
7149     }
7150 
7151     /*!
7152     @brief public accept interface
7153 
7154     @param[in] strict  whether to expect the last token to be EOF
7155     @return whether the input is a proper JSON text
7156     */
accept(const bool strict=true)7157     bool accept(const bool strict = true)
7158     {
7159         json_sax_acceptor<BasicJsonType> sax_acceptor;
7160         return sax_parse(&sax_acceptor, strict);
7161     }
7162 
7163     template <typename SAX>
sax_parse(SAX * sax,const bool strict=true)7164     bool sax_parse(SAX* sax, const bool strict = true)
7165     {
7166         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7167         const bool result = sax_parse_internal(sax);
7168 
7169         // strict mode: next byte must be EOF
7170         if (result and strict and (get_token() != token_type::end_of_input))
7171         {
7172             return sax->parse_error(m_lexer.get_position(),
7173                                     m_lexer.get_token_string(),
7174                                     parse_error::create(101, m_lexer.get_position(),
7175                                             exception_message(token_type::end_of_input, "value")));
7176         }
7177 
7178         return result;
7179     }
7180 
7181   private:
7182     template <typename SAX>
sax_parse_internal(SAX * sax)7183     bool sax_parse_internal(SAX* sax)
7184     {
7185         // stack to remember the hierarchy of structured values we are parsing
7186         // true = array; false = object
7187         std::vector<bool> states;
7188         // value to avoid a goto (see comment where set to true)
7189         bool skip_to_state_evaluation = false;
7190 
7191         while (true)
7192         {
7193             if (not skip_to_state_evaluation)
7194             {
7195                 // invariant: get_token() was called before each iteration
7196                 switch (last_token)
7197                 {
7198                     case token_type::begin_object:
7199                     {
7200                         if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
7201                         {
7202                             return false;
7203                         }
7204 
7205                         // closing } -> we are done
7206                         if (get_token() == token_type::end_object)
7207                         {
7208                             if (JSON_UNLIKELY(not sax->end_object()))
7209                             {
7210                                 return false;
7211                             }
7212                             break;
7213                         }
7214 
7215                         // parse key
7216                         if (JSON_UNLIKELY(last_token != token_type::value_string))
7217                         {
7218                             return sax->parse_error(m_lexer.get_position(),
7219                                                     m_lexer.get_token_string(),
7220                                                     parse_error::create(101, m_lexer.get_position(),
7221                                                             exception_message(token_type::value_string, "object key")));
7222                         }
7223                         if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
7224                         {
7225                             return false;
7226                         }
7227 
7228                         // parse separator (:)
7229                         if (JSON_UNLIKELY(get_token() != token_type::name_separator))
7230                         {
7231                             return sax->parse_error(m_lexer.get_position(),
7232                                                     m_lexer.get_token_string(),
7233                                                     parse_error::create(101, m_lexer.get_position(),
7234                                                             exception_message(token_type::name_separator, "object separator")));
7235                         }
7236 
7237                         // remember we are now inside an object
7238                         states.push_back(false);
7239 
7240                         // parse values
7241                         get_token();
7242                         continue;
7243                     }
7244 
7245                     case token_type::begin_array:
7246                     {
7247                         if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
7248                         {
7249                             return false;
7250                         }
7251 
7252                         // closing ] -> we are done
7253                         if (get_token() == token_type::end_array)
7254                         {
7255                             if (JSON_UNLIKELY(not sax->end_array()))
7256                             {
7257                                 return false;
7258                             }
7259                             break;
7260                         }
7261 
7262                         // remember we are now inside an array
7263                         states.push_back(true);
7264 
7265                         // parse values (no need to call get_token)
7266                         continue;
7267                     }
7268 
7269                     case token_type::value_float:
7270                     {
7271                         const auto res = m_lexer.get_number_float();
7272 
7273                         if (JSON_UNLIKELY(not std::isfinite(res)))
7274                         {
7275                             return sax->parse_error(m_lexer.get_position(),
7276                                                     m_lexer.get_token_string(),
7277                                                     out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
7278                         }
7279 
7280                         if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
7281                         {
7282                             return false;
7283                         }
7284 
7285                         break;
7286                     }
7287 
7288                     case token_type::literal_false:
7289                     {
7290                         if (JSON_UNLIKELY(not sax->boolean(false)))
7291                         {
7292                             return false;
7293                         }
7294                         break;
7295                     }
7296 
7297                     case token_type::literal_null:
7298                     {
7299                         if (JSON_UNLIKELY(not sax->null()))
7300                         {
7301                             return false;
7302                         }
7303                         break;
7304                     }
7305 
7306                     case token_type::literal_true:
7307                     {
7308                         if (JSON_UNLIKELY(not sax->boolean(true)))
7309                         {
7310                             return false;
7311                         }
7312                         break;
7313                     }
7314 
7315                     case token_type::value_integer:
7316                     {
7317                         if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
7318                         {
7319                             return false;
7320                         }
7321                         break;
7322                     }
7323 
7324                     case token_type::value_string:
7325                     {
7326                         if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
7327                         {
7328                             return false;
7329                         }
7330                         break;
7331                     }
7332 
7333                     case token_type::value_unsigned:
7334                     {
7335                         if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
7336                         {
7337                             return false;
7338                         }
7339                         break;
7340                     }
7341 
7342                     case token_type::parse_error:
7343                     {
7344                         // using "uninitialized" to avoid "expected" message
7345                         return sax->parse_error(m_lexer.get_position(),
7346                                                 m_lexer.get_token_string(),
7347                                                 parse_error::create(101, m_lexer.get_position(),
7348                                                         exception_message(token_type::uninitialized, "value")));
7349                     }
7350 
7351                     default: // the last token was unexpected
7352                     {
7353                         return sax->parse_error(m_lexer.get_position(),
7354                                                 m_lexer.get_token_string(),
7355                                                 parse_error::create(101, m_lexer.get_position(),
7356                                                         exception_message(token_type::literal_or_value, "value")));
7357                     }
7358                 }
7359             }
7360             else
7361             {
7362                 skip_to_state_evaluation = false;
7363             }
7364 
7365             // we reached this line after we successfully parsed a value
7366             if (states.empty())
7367             {
7368                 // empty stack: we reached the end of the hierarchy: done
7369                 return true;
7370             }
7371 
7372             if (states.back())  // array
7373             {
7374                 // comma -> next value
7375                 if (get_token() == token_type::value_separator)
7376                 {
7377                     // parse a new value
7378                     get_token();
7379                     continue;
7380                 }
7381 
7382                 // closing ]
7383                 if (JSON_LIKELY(last_token == token_type::end_array))
7384                 {
7385                     if (JSON_UNLIKELY(not sax->end_array()))
7386                     {
7387                         return false;
7388                     }
7389 
7390                     // We are done with this array. Before we can parse a
7391                     // new value, we need to evaluate the new state first.
7392                     // By setting skip_to_state_evaluation to false, we
7393                     // are effectively jumping to the beginning of this if.
7394                     assert(not states.empty());
7395                     states.pop_back();
7396                     skip_to_state_evaluation = true;
7397                     continue;
7398                 }
7399 
7400                 return sax->parse_error(m_lexer.get_position(),
7401                                         m_lexer.get_token_string(),
7402                                         parse_error::create(101, m_lexer.get_position(),
7403                                                 exception_message(token_type::end_array, "array")));
7404             }
7405             else  // object
7406             {
7407                 // comma -> next value
7408                 if (get_token() == token_type::value_separator)
7409                 {
7410                     // parse key
7411                     if (JSON_UNLIKELY(get_token() != token_type::value_string))
7412                     {
7413                         return sax->parse_error(m_lexer.get_position(),
7414                                                 m_lexer.get_token_string(),
7415                                                 parse_error::create(101, m_lexer.get_position(),
7416                                                         exception_message(token_type::value_string, "object key")));
7417                     }
7418 
7419                     if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
7420                     {
7421                         return false;
7422                     }
7423 
7424                     // parse separator (:)
7425                     if (JSON_UNLIKELY(get_token() != token_type::name_separator))
7426                     {
7427                         return sax->parse_error(m_lexer.get_position(),
7428                                                 m_lexer.get_token_string(),
7429                                                 parse_error::create(101, m_lexer.get_position(),
7430                                                         exception_message(token_type::name_separator, "object separator")));
7431                     }
7432 
7433                     // parse values
7434                     get_token();
7435                     continue;
7436                 }
7437 
7438                 // closing }
7439                 if (JSON_LIKELY(last_token == token_type::end_object))
7440                 {
7441                     if (JSON_UNLIKELY(not sax->end_object()))
7442                     {
7443                         return false;
7444                     }
7445 
7446                     // We are done with this object. Before we can parse a
7447                     // new value, we need to evaluate the new state first.
7448                     // By setting skip_to_state_evaluation to false, we
7449                     // are effectively jumping to the beginning of this if.
7450                     assert(not states.empty());
7451                     states.pop_back();
7452                     skip_to_state_evaluation = true;
7453                     continue;
7454                 }
7455 
7456                 return sax->parse_error(m_lexer.get_position(),
7457                                         m_lexer.get_token_string(),
7458                                         parse_error::create(101, m_lexer.get_position(),
7459                                                 exception_message(token_type::end_object, "object")));
7460             }
7461         }
7462     }
7463 
7464     /// get next token from lexer
get_token()7465     token_type get_token()
7466     {
7467         return last_token = m_lexer.scan();
7468     }
7469 
exception_message(const token_type expected,const std::string & context)7470     std::string exception_message(const token_type expected, const std::string& context)
7471     {
7472         std::string error_msg = "syntax error ";
7473 
7474         if (not context.empty())
7475         {
7476             error_msg += "while parsing " + context + " ";
7477         }
7478 
7479         error_msg += "- ";
7480 
7481         if (last_token == token_type::parse_error)
7482         {
7483             error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
7484                          m_lexer.get_token_string() + "'";
7485         }
7486         else
7487         {
7488             error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
7489         }
7490 
7491         if (expected != token_type::uninitialized)
7492         {
7493             error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
7494         }
7495 
7496         return error_msg;
7497     }
7498 
7499   private:
7500     /// callback function
7501     const parser_callback_t callback = nullptr;
7502     /// the type of the last read token
7503     token_type last_token = token_type::uninitialized;
7504     /// the lexer
7505     lexer_t m_lexer;
7506     /// whether to throw exceptions in case of errors
7507     const bool allow_exceptions = true;
7508 };
7509 }  // namespace detail
7510 }  // namespace nlohmann
7511 
7512 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
7513 
7514 
7515 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
7516 
7517 
7518 #include <cstddef> // ptrdiff_t
7519 #include <limits>  // numeric_limits
7520 
7521 namespace nlohmann
7522 {
7523 namespace detail
7524 {
7525 /*
7526 @brief an iterator for primitive JSON types
7527 
7528 This class models an iterator for primitive JSON types (boolean, number,
7529 string). It's only purpose is to allow the iterator/const_iterator classes
7530 to "iterate" over primitive values. Internally, the iterator is modeled by
7531 a `difference_type` variable. Value begin_value (`0`) models the begin,
7532 end_value (`1`) models past the end.
7533 */
7534 class primitive_iterator_t
7535 {
7536   private:
7537     using difference_type = std::ptrdiff_t;
7538     static constexpr difference_type begin_value = 0;
7539     static constexpr difference_type end_value = begin_value + 1;
7540 
7541     /// iterator as signed integer type
7542     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
7543 
7544   public:
get_value() const7545     constexpr difference_type get_value() const noexcept
7546     {
7547         return m_it;
7548     }
7549 
7550     /// set iterator to a defined beginning
set_begin()7551     void set_begin() noexcept
7552     {
7553         m_it = begin_value;
7554     }
7555 
7556     /// set iterator to a defined past the end
set_end()7557     void set_end() noexcept
7558     {
7559         m_it = end_value;
7560     }
7561 
7562     /// return whether the iterator can be dereferenced
is_begin() const7563     constexpr bool is_begin() const noexcept
7564     {
7565         return m_it == begin_value;
7566     }
7567 
7568     /// return whether the iterator is at end
is_end() const7569     constexpr bool is_end() const noexcept
7570     {
7571         return m_it == end_value;
7572     }
7573 
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)7574     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7575     {
7576         return lhs.m_it == rhs.m_it;
7577     }
7578 
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)7579     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7580     {
7581         return lhs.m_it < rhs.m_it;
7582     }
7583 
operator +(difference_type n)7584     primitive_iterator_t operator+(difference_type n) noexcept
7585     {
7586         auto result = *this;
7587         result += n;
7588         return result;
7589     }
7590 
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)7591     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7592     {
7593         return lhs.m_it - rhs.m_it;
7594     }
7595 
operator ++()7596     primitive_iterator_t& operator++() noexcept
7597     {
7598         ++m_it;
7599         return *this;
7600     }
7601 
operator ++(int)7602     primitive_iterator_t const operator++(int) noexcept
7603     {
7604         auto result = *this;
7605         ++m_it;
7606         return result;
7607     }
7608 
operator --()7609     primitive_iterator_t& operator--() noexcept
7610     {
7611         --m_it;
7612         return *this;
7613     }
7614 
operator --(int)7615     primitive_iterator_t const operator--(int) noexcept
7616     {
7617         auto result = *this;
7618         --m_it;
7619         return result;
7620     }
7621 
operator +=(difference_type n)7622     primitive_iterator_t& operator+=(difference_type n) noexcept
7623     {
7624         m_it += n;
7625         return *this;
7626     }
7627 
operator -=(difference_type n)7628     primitive_iterator_t& operator-=(difference_type n) noexcept
7629     {
7630         m_it -= n;
7631         return *this;
7632     }
7633 };
7634 }  // namespace detail
7635 }  // namespace nlohmann
7636 
7637 
7638 namespace nlohmann
7639 {
7640 namespace detail
7641 {
7642 /*!
7643 @brief an iterator value
7644 
7645 @note This structure could easily be a union, but MSVC currently does not allow
7646 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
7647 */
7648 template<typename BasicJsonType> struct internal_iterator
7649 {
7650     /// iterator for JSON objects
7651     typename BasicJsonType::object_t::iterator object_iterator {};
7652     /// iterator for JSON arrays
7653     typename BasicJsonType::array_t::iterator array_iterator {};
7654     /// generic iterator for all other types
7655     primitive_iterator_t primitive_iterator {};
7656 };
7657 }  // namespace detail
7658 }  // namespace nlohmann
7659 
7660 // #include <nlohmann/detail/iterators/iter_impl.hpp>
7661 
7662 
7663 #include <ciso646> // not
7664 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
7665 #include <type_traits> // conditional, is_const, remove_const
7666 
7667 // #include <nlohmann/detail/exceptions.hpp>
7668 
7669 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
7670 
7671 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
7672 
7673 // #include <nlohmann/detail/macro_scope.hpp>
7674 
7675 // #include <nlohmann/detail/meta/cpp_future.hpp>
7676 
7677 // #include <nlohmann/detail/meta/type_traits.hpp>
7678 
7679 // #include <nlohmann/detail/value_t.hpp>
7680 
7681 
7682 namespace nlohmann
7683 {
7684 namespace detail
7685 {
7686 // forward declare, to be able to friend it later on
7687 template<typename IteratorType> class iteration_proxy;
7688 template<typename IteratorType> class iteration_proxy_value;
7689 
7690 /*!
7691 @brief a template for a bidirectional iterator for the @ref basic_json class
7692 This class implements a both iterators (iterator and const_iterator) for the
7693 @ref basic_json class.
7694 @note An iterator is called *initialized* when a pointer to a JSON value has
7695       been set (e.g., by a constructor or a copy assignment). If the iterator is
7696       default-constructed, it is *uninitialized* and most methods are undefined.
7697       **The library uses assertions to detect calls on uninitialized iterators.**
7698 @requirement The class satisfies the following concept requirements:
7699 -
7700 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
7701   The iterator that can be moved can be moved in both directions (i.e.
7702   incremented and decremented).
7703 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
7704        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
7705 */
7706 template<typename BasicJsonType>
7707 class iter_impl
7708 {
7709     /// allow basic_json to access private members
7710     friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
7711     friend BasicJsonType;
7712     friend iteration_proxy<iter_impl>;
7713     friend iteration_proxy_value<iter_impl>;
7714 
7715     using object_t = typename BasicJsonType::object_t;
7716     using array_t = typename BasicJsonType::array_t;
7717     // make sure BasicJsonType is basic_json or const basic_json
7718     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
7719                   "iter_impl only accepts (const) basic_json");
7720 
7721   public:
7722 
7723     /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
7724     /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
7725     /// A user-defined iterator should provide publicly accessible typedefs named
7726     /// iterator_category, value_type, difference_type, pointer, and reference.
7727     /// Note that value_type is required to be non-const, even for constant iterators.
7728     using iterator_category = std::bidirectional_iterator_tag;
7729 
7730     /// the type of the values when the iterator is dereferenced
7731     using value_type = typename BasicJsonType::value_type;
7732     /// a type to represent differences between iterators
7733     using difference_type = typename BasicJsonType::difference_type;
7734     /// defines a pointer to the type iterated over (value_type)
7735     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
7736           typename BasicJsonType::const_pointer,
7737           typename BasicJsonType::pointer>::type;
7738     /// defines a reference to the type iterated over (value_type)
7739     using reference =
7740         typename std::conditional<std::is_const<BasicJsonType>::value,
7741         typename BasicJsonType::const_reference,
7742         typename BasicJsonType::reference>::type;
7743 
7744     /// default constructor
7745     iter_impl() = default;
7746 
7747     /*!
7748     @brief constructor for a given JSON instance
7749     @param[in] object  pointer to a JSON object for this iterator
7750     @pre object != nullptr
7751     @post The iterator is initialized; i.e. `m_object != nullptr`.
7752     */
iter_impl(pointer object)7753     explicit iter_impl(pointer object) noexcept : m_object(object)
7754     {
7755         assert(m_object != nullptr);
7756 
7757         switch (m_object->m_type)
7758         {
7759             case value_t::object:
7760             {
7761                 m_it.object_iterator = typename object_t::iterator();
7762                 break;
7763             }
7764 
7765             case value_t::array:
7766             {
7767                 m_it.array_iterator = typename array_t::iterator();
7768                 break;
7769             }
7770 
7771             default:
7772             {
7773                 m_it.primitive_iterator = primitive_iterator_t();
7774                 break;
7775             }
7776         }
7777     }
7778 
7779     /*!
7780     @note The conventional copy constructor and copy assignment are implicitly
7781           defined. Combined with the following converting constructor and
7782           assignment, they support: (1) copy from iterator to iterator, (2)
7783           copy from const iterator to const iterator, and (3) conversion from
7784           iterator to const iterator. However conversion from const iterator
7785           to iterator is not defined.
7786     */
7787 
7788     /*!
7789     @brief converting constructor
7790     @param[in] other  non-const iterator to copy from
7791     @note It is not checked whether @a other is initialized.
7792     */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)7793     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
7794         : m_object(other.m_object), m_it(other.m_it) {}
7795 
7796     /*!
7797     @brief converting assignment
7798     @param[in,out] other  non-const iterator to copy from
7799     @return const/non-const iterator
7800     @note It is not checked whether @a other is initialized.
7801     */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)7802     iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
7803     {
7804         m_object = other.m_object;
7805         m_it = other.m_it;
7806         return *this;
7807     }
7808 
7809   private:
7810     /*!
7811     @brief set the iterator to the first value
7812     @pre The iterator is initialized; i.e. `m_object != nullptr`.
7813     */
set_begin()7814     void set_begin() noexcept
7815     {
7816         assert(m_object != nullptr);
7817 
7818         switch (m_object->m_type)
7819         {
7820             case value_t::object:
7821             {
7822                 m_it.object_iterator = m_object->m_value.object->begin();
7823                 break;
7824             }
7825 
7826             case value_t::array:
7827             {
7828                 m_it.array_iterator = m_object->m_value.array->begin();
7829                 break;
7830             }
7831 
7832             case value_t::null:
7833             {
7834                 // set to end so begin()==end() is true: null is empty
7835                 m_it.primitive_iterator.set_end();
7836                 break;
7837             }
7838 
7839             default:
7840             {
7841                 m_it.primitive_iterator.set_begin();
7842                 break;
7843             }
7844         }
7845     }
7846 
7847     /*!
7848     @brief set the iterator past the last value
7849     @pre The iterator is initialized; i.e. `m_object != nullptr`.
7850     */
set_end()7851     void set_end() noexcept
7852     {
7853         assert(m_object != nullptr);
7854 
7855         switch (m_object->m_type)
7856         {
7857             case value_t::object:
7858             {
7859                 m_it.object_iterator = m_object->m_value.object->end();
7860                 break;
7861             }
7862 
7863             case value_t::array:
7864             {
7865                 m_it.array_iterator = m_object->m_value.array->end();
7866                 break;
7867             }
7868 
7869             default:
7870             {
7871                 m_it.primitive_iterator.set_end();
7872                 break;
7873             }
7874         }
7875     }
7876 
7877   public:
7878     /*!
7879     @brief return a reference to the value pointed to by the iterator
7880     @pre The iterator is initialized; i.e. `m_object != nullptr`.
7881     */
operator *() const7882     reference operator*() const
7883     {
7884         assert(m_object != nullptr);
7885 
7886         switch (m_object->m_type)
7887         {
7888             case value_t::object:
7889             {
7890                 assert(m_it.object_iterator != m_object->m_value.object->end());
7891                 return m_it.object_iterator->second;
7892             }
7893 
7894             case value_t::array:
7895             {
7896                 assert(m_it.array_iterator != m_object->m_value.array->end());
7897                 return *m_it.array_iterator;
7898             }
7899 
7900             case value_t::null:
7901                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7902 
7903             default:
7904             {
7905                 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7906                 {
7907                     return *m_object;
7908                 }
7909 
7910                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7911             }
7912         }
7913     }
7914 
7915     /*!
7916     @brief dereference the iterator
7917     @pre The iterator is initialized; i.e. `m_object != nullptr`.
7918     */
operator ->() const7919     pointer operator->() const
7920     {
7921         assert(m_object != nullptr);
7922 
7923         switch (m_object->m_type)
7924         {
7925             case value_t::object:
7926             {
7927                 assert(m_it.object_iterator != m_object->m_value.object->end());
7928                 return &(m_it.object_iterator->second);
7929             }
7930 
7931             case value_t::array:
7932             {
7933                 assert(m_it.array_iterator != m_object->m_value.array->end());
7934                 return &*m_it.array_iterator;
7935             }
7936 
7937             default:
7938             {
7939                 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7940                 {
7941                     return m_object;
7942                 }
7943 
7944                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7945             }
7946         }
7947     }
7948 
7949     /*!
7950     @brief post-increment (it++)
7951     @pre The iterator is initialized; i.e. `m_object != nullptr`.
7952     */
operator ++(int)7953     iter_impl const operator++(int)
7954     {
7955         auto result = *this;
7956         ++(*this);
7957         return result;
7958     }
7959 
7960     /*!
7961     @brief pre-increment (++it)
7962     @pre The iterator is initialized; i.e. `m_object != nullptr`.
7963     */
operator ++()7964     iter_impl& operator++()
7965     {
7966         assert(m_object != nullptr);
7967 
7968         switch (m_object->m_type)
7969         {
7970             case value_t::object:
7971             {
7972                 std::advance(m_it.object_iterator, 1);
7973                 break;
7974             }
7975 
7976             case value_t::array:
7977             {
7978                 std::advance(m_it.array_iterator, 1);
7979                 break;
7980             }
7981 
7982             default:
7983             {
7984                 ++m_it.primitive_iterator;
7985                 break;
7986             }
7987         }
7988 
7989         return *this;
7990     }
7991 
7992     /*!
7993     @brief post-decrement (it--)
7994     @pre The iterator is initialized; i.e. `m_object != nullptr`.
7995     */
operator --(int)7996     iter_impl const operator--(int)
7997     {
7998         auto result = *this;
7999         --(*this);
8000         return result;
8001     }
8002 
8003     /*!
8004     @brief pre-decrement (--it)
8005     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8006     */
operator --()8007     iter_impl& operator--()
8008     {
8009         assert(m_object != nullptr);
8010 
8011         switch (m_object->m_type)
8012         {
8013             case value_t::object:
8014             {
8015                 std::advance(m_it.object_iterator, -1);
8016                 break;
8017             }
8018 
8019             case value_t::array:
8020             {
8021                 std::advance(m_it.array_iterator, -1);
8022                 break;
8023             }
8024 
8025             default:
8026             {
8027                 --m_it.primitive_iterator;
8028                 break;
8029             }
8030         }
8031 
8032         return *this;
8033     }
8034 
8035     /*!
8036     @brief  comparison: equal
8037     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8038     */
operator ==(const iter_impl & other) const8039     bool operator==(const iter_impl& other) const
8040     {
8041         // if objects are not the same, the comparison is undefined
8042         if (JSON_UNLIKELY(m_object != other.m_object))
8043         {
8044             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8045         }
8046 
8047         assert(m_object != nullptr);
8048 
8049         switch (m_object->m_type)
8050         {
8051             case value_t::object:
8052                 return (m_it.object_iterator == other.m_it.object_iterator);
8053 
8054             case value_t::array:
8055                 return (m_it.array_iterator == other.m_it.array_iterator);
8056 
8057             default:
8058                 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
8059         }
8060     }
8061 
8062     /*!
8063     @brief  comparison: not equal
8064     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8065     */
operator !=(const iter_impl & other) const8066     bool operator!=(const iter_impl& other) const
8067     {
8068         return not operator==(other);
8069     }
8070 
8071     /*!
8072     @brief  comparison: smaller
8073     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8074     */
operator <(const iter_impl & other) const8075     bool operator<(const iter_impl& other) const
8076     {
8077         // if objects are not the same, the comparison is undefined
8078         if (JSON_UNLIKELY(m_object != other.m_object))
8079         {
8080             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8081         }
8082 
8083         assert(m_object != nullptr);
8084 
8085         switch (m_object->m_type)
8086         {
8087             case value_t::object:
8088                 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
8089 
8090             case value_t::array:
8091                 return (m_it.array_iterator < other.m_it.array_iterator);
8092 
8093             default:
8094                 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
8095         }
8096     }
8097 
8098     /*!
8099     @brief  comparison: less than or equal
8100     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8101     */
operator <=(const iter_impl & other) const8102     bool operator<=(const iter_impl& other) const
8103     {
8104         return not other.operator < (*this);
8105     }
8106 
8107     /*!
8108     @brief  comparison: greater than
8109     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8110     */
operator >(const iter_impl & other) const8111     bool operator>(const iter_impl& other) const
8112     {
8113         return not operator<=(other);
8114     }
8115 
8116     /*!
8117     @brief  comparison: greater than or equal
8118     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8119     */
operator >=(const iter_impl & other) const8120     bool operator>=(const iter_impl& other) const
8121     {
8122         return not operator<(other);
8123     }
8124 
8125     /*!
8126     @brief  add to iterator
8127     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8128     */
operator +=(difference_type i)8129     iter_impl& operator+=(difference_type i)
8130     {
8131         assert(m_object != nullptr);
8132 
8133         switch (m_object->m_type)
8134         {
8135             case value_t::object:
8136                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
8137 
8138             case value_t::array:
8139             {
8140                 std::advance(m_it.array_iterator, i);
8141                 break;
8142             }
8143 
8144             default:
8145             {
8146                 m_it.primitive_iterator += i;
8147                 break;
8148             }
8149         }
8150 
8151         return *this;
8152     }
8153 
8154     /*!
8155     @brief  subtract from iterator
8156     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8157     */
operator -=(difference_type i)8158     iter_impl& operator-=(difference_type i)
8159     {
8160         return operator+=(-i);
8161     }
8162 
8163     /*!
8164     @brief  add to iterator
8165     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8166     */
operator +(difference_type i) const8167     iter_impl operator+(difference_type i) const
8168     {
8169         auto result = *this;
8170         result += i;
8171         return result;
8172     }
8173 
8174     /*!
8175     @brief  addition of distance and iterator
8176     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8177     */
operator +(difference_type i,const iter_impl & it)8178     friend iter_impl operator+(difference_type i, const iter_impl& it)
8179     {
8180         auto result = it;
8181         result += i;
8182         return result;
8183     }
8184 
8185     /*!
8186     @brief  subtract from iterator
8187     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8188     */
operator -(difference_type i) const8189     iter_impl operator-(difference_type i) const
8190     {
8191         auto result = *this;
8192         result -= i;
8193         return result;
8194     }
8195 
8196     /*!
8197     @brief  return difference
8198     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8199     */
operator -(const iter_impl & other) const8200     difference_type operator-(const iter_impl& other) const
8201     {
8202         assert(m_object != nullptr);
8203 
8204         switch (m_object->m_type)
8205         {
8206             case value_t::object:
8207                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
8208 
8209             case value_t::array:
8210                 return m_it.array_iterator - other.m_it.array_iterator;
8211 
8212             default:
8213                 return m_it.primitive_iterator - other.m_it.primitive_iterator;
8214         }
8215     }
8216 
8217     /*!
8218     @brief  access to successor
8219     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8220     */
operator [](difference_type n) const8221     reference operator[](difference_type n) const
8222     {
8223         assert(m_object != nullptr);
8224 
8225         switch (m_object->m_type)
8226         {
8227             case value_t::object:
8228                 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
8229 
8230             case value_t::array:
8231                 return *std::next(m_it.array_iterator, n);
8232 
8233             case value_t::null:
8234                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8235 
8236             default:
8237             {
8238                 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
8239                 {
8240                     return *m_object;
8241                 }
8242 
8243                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8244             }
8245         }
8246     }
8247 
8248     /*!
8249     @brief  return the key of an object iterator
8250     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8251     */
key() const8252     const typename object_t::key_type& key() const
8253     {
8254         assert(m_object != nullptr);
8255 
8256         if (JSON_LIKELY(m_object->is_object()))
8257         {
8258             return m_it.object_iterator->first;
8259         }
8260 
8261         JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
8262     }
8263 
8264     /*!
8265     @brief  return the value of an iterator
8266     @pre The iterator is initialized; i.e. `m_object != nullptr`.
8267     */
value() const8268     reference value() const
8269     {
8270         return operator*();
8271     }
8272 
8273   private:
8274     /// associated JSON instance
8275     pointer m_object = nullptr;
8276     /// the actual iterator of the associated instance
8277     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
8278 };
8279 }  // namespace detail
8280 } // namespace nlohmann
8281 
8282 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
8283 
8284 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
8285 
8286 
8287 #include <cstddef> // ptrdiff_t
8288 #include <iterator> // reverse_iterator
8289 #include <utility> // declval
8290 
8291 namespace nlohmann
8292 {
8293 namespace detail
8294 {
8295 //////////////////////
8296 // reverse_iterator //
8297 //////////////////////
8298 
8299 /*!
8300 @brief a template for a reverse iterator class
8301 
8302 @tparam Base the base iterator type to reverse. Valid types are @ref
8303 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
8304 create @ref const_reverse_iterator).
8305 
8306 @requirement The class satisfies the following concept requirements:
8307 -
8308 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
8309   The iterator that can be moved can be moved in both directions (i.e.
8310   incremented and decremented).
8311 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
8312   It is possible to write to the pointed-to element (only if @a Base is
8313   @ref iterator).
8314 
8315 @since version 1.0.0
8316 */
8317 template<typename Base>
8318 class json_reverse_iterator : public std::reverse_iterator<Base>
8319 {
8320   public:
8321     using difference_type = std::ptrdiff_t;
8322     /// shortcut to the reverse iterator adapter
8323     using base_iterator = std::reverse_iterator<Base>;
8324     /// the reference type for the pointed-to element
8325     using reference = typename Base::reference;
8326 
8327     /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)8328     explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
8329         : base_iterator(it) {}
8330 
8331     /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)8332     explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
8333 
8334     /// post-increment (it++)
operator ++(int)8335     json_reverse_iterator const operator++(int)
8336     {
8337         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
8338     }
8339 
8340     /// pre-increment (++it)
operator ++()8341     json_reverse_iterator& operator++()
8342     {
8343         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
8344     }
8345 
8346     /// post-decrement (it--)
operator --(int)8347     json_reverse_iterator const operator--(int)
8348     {
8349         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
8350     }
8351 
8352     /// pre-decrement (--it)
operator --()8353     json_reverse_iterator& operator--()
8354     {
8355         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
8356     }
8357 
8358     /// add to iterator
operator +=(difference_type i)8359     json_reverse_iterator& operator+=(difference_type i)
8360     {
8361         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
8362     }
8363 
8364     /// add to iterator
operator +(difference_type i) const8365     json_reverse_iterator operator+(difference_type i) const
8366     {
8367         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
8368     }
8369 
8370     /// subtract from iterator
operator -(difference_type i) const8371     json_reverse_iterator operator-(difference_type i) const
8372     {
8373         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
8374     }
8375 
8376     /// return difference
operator -(const json_reverse_iterator & other) const8377     difference_type operator-(const json_reverse_iterator& other) const
8378     {
8379         return base_iterator(*this) - base_iterator(other);
8380     }
8381 
8382     /// access to successor
operator [](difference_type n) const8383     reference operator[](difference_type n) const
8384     {
8385         return *(this->operator+(n));
8386     }
8387 
8388     /// return the key of an object iterator
key() const8389     auto key() const -> decltype(std::declval<Base>().key())
8390     {
8391         auto it = --this->base();
8392         return it.key();
8393     }
8394 
8395     /// return the value of an iterator
value() const8396     reference value() const
8397     {
8398         auto it = --this->base();
8399         return it.operator * ();
8400     }
8401 };
8402 }  // namespace detail
8403 }  // namespace nlohmann
8404 
8405 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
8406 
8407 // #include <nlohmann/detail/json_pointer.hpp>
8408 
8409 
8410 #include <algorithm> // all_of
8411 #include <cassert> // assert
8412 #include <numeric> // accumulate
8413 #include <string> // string
8414 #include <utility> // move
8415 #include <vector> // vector
8416 
8417 // #include <nlohmann/detail/exceptions.hpp>
8418 
8419 // #include <nlohmann/detail/macro_scope.hpp>
8420 
8421 // #include <nlohmann/detail/value_t.hpp>
8422 
8423 
8424 namespace nlohmann
8425 {
8426 template<typename BasicJsonType>
8427 class json_pointer
8428 {
8429     // allow basic_json to access private members
8430     NLOHMANN_BASIC_JSON_TPL_DECLARATION
8431     friend class basic_json;
8432 
8433   public:
8434     /*!
8435     @brief create JSON pointer
8436 
8437     Create a JSON pointer according to the syntax described in
8438     [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
8439 
8440     @param[in] s  string representing the JSON pointer; if omitted, the empty
8441                   string is assumed which references the whole JSON value
8442 
8443     @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
8444                            not begin with a slash (`/`); see example below
8445 
8446     @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
8447     not followed by `0` (representing `~`) or `1` (representing `/`); see
8448     example below
8449 
8450     @liveexample{The example shows the construction several valid JSON pointers
8451     as well as the exceptional behavior.,json_pointer}
8452 
8453     @since version 2.0.0
8454     */
json_pointer(const std::string & s="")8455     explicit json_pointer(const std::string& s = "")
8456         : reference_tokens(split(s))
8457     {}
8458 
8459     /*!
8460     @brief return a string representation of the JSON pointer
8461 
8462     @invariant For each JSON pointer `ptr`, it holds:
8463     @code {.cpp}
8464     ptr == json_pointer(ptr.to_string());
8465     @endcode
8466 
8467     @return a string representation of the JSON pointer
8468 
8469     @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
8470 
8471     @since version 2.0.0
8472     */
to_string() const8473     std::string to_string() const
8474     {
8475         return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8476                                std::string{},
8477                                [](const std::string & a, const std::string & b)
8478         {
8479             return a + "/" + escape(b);
8480         });
8481     }
8482 
8483     /// @copydoc to_string()
operator std::string() const8484     operator std::string() const
8485     {
8486         return to_string();
8487     }
8488 
8489     /*!
8490     @brief append another JSON pointer at the end of this JSON pointer
8491 
8492     @param[in] ptr  JSON pointer to append
8493     @return JSON pointer with @a ptr appended
8494 
8495     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8496 
8497     @complexity Linear in the length of @a ptr.
8498 
8499     @sa @ref operator/=(std::string) to append a reference token
8500     @sa @ref operator/=(std::size_t) to append an array index
8501     @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
8502 
8503     @since version 3.6.0
8504     */
operator /=(const json_pointer & ptr)8505     json_pointer& operator/=(const json_pointer& ptr)
8506     {
8507         reference_tokens.insert(reference_tokens.end(),
8508                                 ptr.reference_tokens.begin(),
8509                                 ptr.reference_tokens.end());
8510         return *this;
8511     }
8512 
8513     /*!
8514     @brief append an unescaped reference token at the end of this JSON pointer
8515 
8516     @param[in] token  reference token to append
8517     @return JSON pointer with @a token appended without escaping @a token
8518 
8519     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8520 
8521     @complexity Amortized constant.
8522 
8523     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8524     @sa @ref operator/=(std::size_t) to append an array index
8525     @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
8526 
8527     @since version 3.6.0
8528     */
operator /=(std::string token)8529     json_pointer& operator/=(std::string token)
8530     {
8531         push_back(std::move(token));
8532         return *this;
8533     }
8534 
8535     /*!
8536     @brief append an array index at the end of this JSON pointer
8537 
8538     @param[in] array_index  array index ot append
8539     @return JSON pointer with @a array_index appended
8540 
8541     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8542 
8543     @complexity Amortized constant.
8544 
8545     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8546     @sa @ref operator/=(std::string) to append a reference token
8547     @sa @ref operator/(const json_pointer&, std::string) for a binary operator
8548 
8549     @since version 3.6.0
8550     */
operator /=(std::size_t array_index)8551     json_pointer& operator/=(std::size_t array_index)
8552     {
8553         return *this /= std::to_string(array_index);
8554     }
8555 
8556     /*!
8557     @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
8558 
8559     @param[in] lhs  JSON pointer
8560     @param[in] rhs  JSON pointer
8561     @return a new JSON pointer with @a rhs appended to @a lhs
8562 
8563     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8564 
8565     @complexity Linear in the length of @a lhs and @a rhs.
8566 
8567     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8568 
8569     @since version 3.6.0
8570     */
operator /(const json_pointer & lhs,const json_pointer & rhs)8571     friend json_pointer operator/(const json_pointer& lhs,
8572                                   const json_pointer& rhs)
8573     {
8574         return json_pointer(lhs) /= rhs;
8575     }
8576 
8577     /*!
8578     @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
8579 
8580     @param[in] ptr  JSON pointer
8581     @param[in] token  reference token
8582     @return a new JSON pointer with unescaped @a token appended to @a ptr
8583 
8584     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8585 
8586     @complexity Linear in the length of @a ptr.
8587 
8588     @sa @ref operator/=(std::string) to append a reference token
8589 
8590     @since version 3.6.0
8591     */
operator /(const json_pointer & ptr,std::string token)8592     friend json_pointer operator/(const json_pointer& ptr, std::string token)
8593     {
8594         return json_pointer(ptr) /= std::move(token);
8595     }
8596 
8597     /*!
8598     @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
8599 
8600     @param[in] ptr  JSON pointer
8601     @param[in] array_index  array index
8602     @return a new JSON pointer with @a array_index appended to @a ptr
8603 
8604     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8605 
8606     @complexity Linear in the length of @a ptr.
8607 
8608     @sa @ref operator/=(std::size_t) to append an array index
8609 
8610     @since version 3.6.0
8611     */
operator /(const json_pointer & ptr,std::size_t array_index)8612     friend json_pointer operator/(const json_pointer& ptr, std::size_t array_index)
8613     {
8614         return json_pointer(ptr) /= array_index;
8615     }
8616 
8617     /*!
8618     @brief returns the parent of this JSON pointer
8619 
8620     @return parent of this JSON pointer; in case this JSON pointer is the root,
8621             the root itself is returned
8622 
8623     @complexity Linear in the length of the JSON pointer.
8624 
8625     @liveexample{The example shows the result of `parent_pointer` for different
8626     JSON Pointers.,json_pointer__parent_pointer}
8627 
8628     @since version 3.6.0
8629     */
parent_pointer() const8630     json_pointer parent_pointer() const
8631     {
8632         if (empty())
8633         {
8634             return *this;
8635         }
8636 
8637         json_pointer res = *this;
8638         res.pop_back();
8639         return res;
8640     }
8641 
8642     /*!
8643     @brief remove last reference token
8644 
8645     @pre not `empty()`
8646 
8647     @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
8648 
8649     @complexity Constant.
8650 
8651     @throw out_of_range.405 if JSON pointer has no parent
8652 
8653     @since version 3.6.0
8654     */
pop_back()8655     void pop_back()
8656     {
8657         if (JSON_UNLIKELY(empty()))
8658         {
8659             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8660         }
8661 
8662         reference_tokens.pop_back();
8663     }
8664 
8665     /*!
8666     @brief return last reference token
8667 
8668     @pre not `empty()`
8669     @return last reference token
8670 
8671     @liveexample{The example shows the usage of `back`.,json_pointer__back}
8672 
8673     @complexity Constant.
8674 
8675     @throw out_of_range.405 if JSON pointer has no parent
8676 
8677     @since version 3.6.0
8678     */
back()8679     const std::string& back()
8680     {
8681         if (JSON_UNLIKELY(empty()))
8682         {
8683             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8684         }
8685 
8686         return reference_tokens.back();
8687     }
8688 
8689     /*!
8690     @brief append an unescaped token at the end of the reference pointer
8691 
8692     @param[in] token  token to add
8693 
8694     @complexity Amortized constant.
8695 
8696     @liveexample{The example shows the result of `push_back` for different
8697     JSON Pointers.,json_pointer__push_back}
8698 
8699     @since version 3.6.0
8700     */
push_back(const std::string & token)8701     void push_back(const std::string& token)
8702     {
8703         reference_tokens.push_back(token);
8704     }
8705 
8706     /// @copydoc push_back(const std::string&)
push_back(std::string && token)8707     void push_back(std::string&& token)
8708     {
8709         reference_tokens.push_back(std::move(token));
8710     }
8711 
8712     /*!
8713     @brief return whether pointer points to the root document
8714 
8715     @return true iff the JSON pointer points to the root document
8716 
8717     @complexity Constant.
8718 
8719     @exceptionsafety No-throw guarantee: this function never throws exceptions.
8720 
8721     @liveexample{The example shows the result of `empty` for different JSON
8722     Pointers.,json_pointer__empty}
8723 
8724     @since version 3.6.0
8725     */
empty() const8726     bool empty() const noexcept
8727     {
8728         return reference_tokens.empty();
8729     }
8730 
8731   private:
8732     /*!
8733     @param[in] s  reference token to be converted into an array index
8734 
8735     @return integer representation of @a s
8736 
8737     @throw out_of_range.404 if string @a s could not be converted to an integer
8738     */
array_index(const std::string & s)8739     static int array_index(const std::string& s)
8740     {
8741         std::size_t processed_chars = 0;
8742         const int res = std::stoi(s, &processed_chars);
8743 
8744         // check if the string was completely read
8745         if (JSON_UNLIKELY(processed_chars != s.size()))
8746         {
8747             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
8748         }
8749 
8750         return res;
8751     }
8752 
top() const8753     json_pointer top() const
8754     {
8755         if (JSON_UNLIKELY(empty()))
8756         {
8757             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8758         }
8759 
8760         json_pointer result = *this;
8761         result.reference_tokens = {reference_tokens[0]};
8762         return result;
8763     }
8764 
8765     /*!
8766     @brief create and return a reference to the pointed to value
8767 
8768     @complexity Linear in the number of reference tokens.
8769 
8770     @throw parse_error.109 if array index is not a number
8771     @throw type_error.313 if value cannot be unflattened
8772     */
get_and_create(BasicJsonType & j) const8773     BasicJsonType& get_and_create(BasicJsonType& j) const
8774     {
8775         using size_type = typename BasicJsonType::size_type;
8776         auto result = &j;
8777 
8778         // in case no reference tokens exist, return a reference to the JSON value
8779         // j which will be overwritten by a primitive value
8780         for (const auto& reference_token : reference_tokens)
8781         {
8782             switch (result->m_type)
8783             {
8784                 case detail::value_t::null:
8785                 {
8786                     if (reference_token == "0")
8787                     {
8788                         // start a new array if reference token is 0
8789                         result = &result->operator[](0);
8790                     }
8791                     else
8792                     {
8793                         // start a new object otherwise
8794                         result = &result->operator[](reference_token);
8795                     }
8796                     break;
8797                 }
8798 
8799                 case detail::value_t::object:
8800                 {
8801                     // create an entry in the object
8802                     result = &result->operator[](reference_token);
8803                     break;
8804                 }
8805 
8806                 case detail::value_t::array:
8807                 {
8808                     // create an entry in the array
8809                     JSON_TRY
8810                     {
8811                         result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
8812                     }
8813                     JSON_CATCH(std::invalid_argument&)
8814                     {
8815                         JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8816                     }
8817                     break;
8818                 }
8819 
8820                 /*
8821                 The following code is only reached if there exists a reference
8822                 token _and_ the current value is primitive. In this case, we have
8823                 an error situation, because primitive values may only occur as
8824                 single value; that is, with an empty list of reference tokens.
8825                 */
8826                 default:
8827                     JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
8828             }
8829         }
8830 
8831         return *result;
8832     }
8833 
8834     /*!
8835     @brief return a reference to the pointed to value
8836 
8837     @note This version does not throw if a value is not present, but tries to
8838           create nested values instead. For instance, calling this function
8839           with pointer `"/this/that"` on a null value is equivalent to calling
8840           `operator[]("this").operator[]("that")` on that value, effectively
8841           changing the null value to an object.
8842 
8843     @param[in] ptr  a JSON value
8844 
8845     @return reference to the JSON value pointed to by the JSON pointer
8846 
8847     @complexity Linear in the length of the JSON pointer.
8848 
8849     @throw parse_error.106   if an array index begins with '0'
8850     @throw parse_error.109   if an array index was not a number
8851     @throw out_of_range.404  if the JSON pointer can not be resolved
8852     */
get_unchecked(BasicJsonType * ptr) const8853     BasicJsonType& get_unchecked(BasicJsonType* ptr) const
8854     {
8855         using size_type = typename BasicJsonType::size_type;
8856         for (const auto& reference_token : reference_tokens)
8857         {
8858             // convert null values to arrays or objects before continuing
8859             if (ptr->m_type == detail::value_t::null)
8860             {
8861                 // check if reference token is a number
8862                 const bool nums =
8863                     std::all_of(reference_token.begin(), reference_token.end(),
8864                                 [](const char x)
8865                 {
8866                     return x >= '0' and x <= '9';
8867                 });
8868 
8869                 // change value to array for numbers or "-" or to object otherwise
8870                 *ptr = (nums or reference_token == "-")
8871                        ? detail::value_t::array
8872                        : detail::value_t::object;
8873             }
8874 
8875             switch (ptr->m_type)
8876             {
8877                 case detail::value_t::object:
8878                 {
8879                     // use unchecked object access
8880                     ptr = &ptr->operator[](reference_token);
8881                     break;
8882                 }
8883 
8884                 case detail::value_t::array:
8885                 {
8886                     // error condition (cf. RFC 6901, Sect. 4)
8887                     if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
8888                     {
8889                         JSON_THROW(detail::parse_error::create(106, 0,
8890                                                                "array index '" + reference_token +
8891                                                                "' must not begin with '0'"));
8892                     }
8893 
8894                     if (reference_token == "-")
8895                     {
8896                         // explicitly treat "-" as index beyond the end
8897                         ptr = &ptr->operator[](ptr->m_value.array->size());
8898                     }
8899                     else
8900                     {
8901                         // convert array index to number; unchecked access
8902                         JSON_TRY
8903                         {
8904                             ptr = &ptr->operator[](
8905                                 static_cast<size_type>(array_index(reference_token)));
8906                         }
8907                         JSON_CATCH(std::invalid_argument&)
8908                         {
8909                             JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8910                         }
8911                     }
8912                     break;
8913                 }
8914 
8915                 default:
8916                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8917             }
8918         }
8919 
8920         return *ptr;
8921     }
8922 
8923     /*!
8924     @throw parse_error.106   if an array index begins with '0'
8925     @throw parse_error.109   if an array index was not a number
8926     @throw out_of_range.402  if the array index '-' is used
8927     @throw out_of_range.404  if the JSON pointer can not be resolved
8928     */
get_checked(BasicJsonType * ptr) const8929     BasicJsonType& get_checked(BasicJsonType* ptr) const
8930     {
8931         using size_type = typename BasicJsonType::size_type;
8932         for (const auto& reference_token : reference_tokens)
8933         {
8934             switch (ptr->m_type)
8935             {
8936                 case detail::value_t::object:
8937                 {
8938                     // note: at performs range check
8939                     ptr = &ptr->at(reference_token);
8940                     break;
8941                 }
8942 
8943                 case detail::value_t::array:
8944                 {
8945                     if (JSON_UNLIKELY(reference_token == "-"))
8946                     {
8947                         // "-" always fails the range check
8948                         JSON_THROW(detail::out_of_range::create(402,
8949                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
8950                                                                 ") is out of range"));
8951                     }
8952 
8953                     // error condition (cf. RFC 6901, Sect. 4)
8954                     if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
8955                     {
8956                         JSON_THROW(detail::parse_error::create(106, 0,
8957                                                                "array index '" + reference_token +
8958                                                                "' must not begin with '0'"));
8959                     }
8960 
8961                     // note: at performs range check
8962                     JSON_TRY
8963                     {
8964                         ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
8965                     }
8966                     JSON_CATCH(std::invalid_argument&)
8967                     {
8968                         JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8969                     }
8970                     break;
8971                 }
8972 
8973                 default:
8974                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8975             }
8976         }
8977 
8978         return *ptr;
8979     }
8980 
8981     /*!
8982     @brief return a const reference to the pointed to value
8983 
8984     @param[in] ptr  a JSON value
8985 
8986     @return const reference to the JSON value pointed to by the JSON
8987     pointer
8988 
8989     @throw parse_error.106   if an array index begins with '0'
8990     @throw parse_error.109   if an array index was not a number
8991     @throw out_of_range.402  if the array index '-' is used
8992     @throw out_of_range.404  if the JSON pointer can not be resolved
8993     */
get_unchecked(const BasicJsonType * ptr) const8994     const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
8995     {
8996         using size_type = typename BasicJsonType::size_type;
8997         for (const auto& reference_token : reference_tokens)
8998         {
8999             switch (ptr->m_type)
9000             {
9001                 case detail::value_t::object:
9002                 {
9003                     // use unchecked object access
9004                     ptr = &ptr->operator[](reference_token);
9005                     break;
9006                 }
9007 
9008                 case detail::value_t::array:
9009                 {
9010                     if (JSON_UNLIKELY(reference_token == "-"))
9011                     {
9012                         // "-" cannot be used for const access
9013                         JSON_THROW(detail::out_of_range::create(402,
9014                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9015                                                                 ") is out of range"));
9016                     }
9017 
9018                     // error condition (cf. RFC 6901, Sect. 4)
9019                     if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9020                     {
9021                         JSON_THROW(detail::parse_error::create(106, 0,
9022                                                                "array index '" + reference_token +
9023                                                                "' must not begin with '0'"));
9024                     }
9025 
9026                     // use unchecked array access
9027                     JSON_TRY
9028                     {
9029                         ptr = &ptr->operator[](
9030                             static_cast<size_type>(array_index(reference_token)));
9031                     }
9032                     JSON_CATCH(std::invalid_argument&)
9033                     {
9034                         JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9035                     }
9036                     break;
9037                 }
9038 
9039                 default:
9040                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9041             }
9042         }
9043 
9044         return *ptr;
9045     }
9046 
9047     /*!
9048     @throw parse_error.106   if an array index begins with '0'
9049     @throw parse_error.109   if an array index was not a number
9050     @throw out_of_range.402  if the array index '-' is used
9051     @throw out_of_range.404  if the JSON pointer can not be resolved
9052     */
get_checked(const BasicJsonType * ptr) const9053     const BasicJsonType& get_checked(const BasicJsonType* ptr) const
9054     {
9055         using size_type = typename BasicJsonType::size_type;
9056         for (const auto& reference_token : reference_tokens)
9057         {
9058             switch (ptr->m_type)
9059             {
9060                 case detail::value_t::object:
9061                 {
9062                     // note: at performs range check
9063                     ptr = &ptr->at(reference_token);
9064                     break;
9065                 }
9066 
9067                 case detail::value_t::array:
9068                 {
9069                     if (JSON_UNLIKELY(reference_token == "-"))
9070                     {
9071                         // "-" always fails the range check
9072                         JSON_THROW(detail::out_of_range::create(402,
9073                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9074                                                                 ") is out of range"));
9075                     }
9076 
9077                     // error condition (cf. RFC 6901, Sect. 4)
9078                     if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9079                     {
9080                         JSON_THROW(detail::parse_error::create(106, 0,
9081                                                                "array index '" + reference_token +
9082                                                                "' must not begin with '0'"));
9083                     }
9084 
9085                     // note: at performs range check
9086                     JSON_TRY
9087                     {
9088                         ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9089                     }
9090                     JSON_CATCH(std::invalid_argument&)
9091                     {
9092                         JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9093                     }
9094                     break;
9095                 }
9096 
9097                 default:
9098                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9099             }
9100         }
9101 
9102         return *ptr;
9103     }
9104 
9105     /*!
9106     @brief split the string input to reference tokens
9107 
9108     @note This function is only called by the json_pointer constructor.
9109           All exceptions below are documented there.
9110 
9111     @throw parse_error.107  if the pointer is not empty or begins with '/'
9112     @throw parse_error.108  if character '~' is not followed by '0' or '1'
9113     */
split(const std::string & reference_string)9114     static std::vector<std::string> split(const std::string& reference_string)
9115     {
9116         std::vector<std::string> result;
9117 
9118         // special case: empty reference string -> no reference tokens
9119         if (reference_string.empty())
9120         {
9121             return result;
9122         }
9123 
9124         // check if nonempty reference string begins with slash
9125         if (JSON_UNLIKELY(reference_string[0] != '/'))
9126         {
9127             JSON_THROW(detail::parse_error::create(107, 1,
9128                                                    "JSON pointer must be empty or begin with '/' - was: '" +
9129                                                    reference_string + "'"));
9130         }
9131 
9132         // extract the reference tokens:
9133         // - slash: position of the last read slash (or end of string)
9134         // - start: position after the previous slash
9135         for (
9136             // search for the first slash after the first character
9137             std::size_t slash = reference_string.find_first_of('/', 1),
9138             // set the beginning of the first reference token
9139             start = 1;
9140             // we can stop if start == 0 (if slash == std::string::npos)
9141             start != 0;
9142             // set the beginning of the next reference token
9143             // (will eventually be 0 if slash == std::string::npos)
9144             start = (slash == std::string::npos) ? 0 : slash + 1,
9145             // find next slash
9146             slash = reference_string.find_first_of('/', start))
9147         {
9148             // use the text between the beginning of the reference token
9149             // (start) and the last slash (slash).
9150             auto reference_token = reference_string.substr(start, slash - start);
9151 
9152             // check reference tokens are properly escaped
9153             for (std::size_t pos = reference_token.find_first_of('~');
9154                     pos != std::string::npos;
9155                     pos = reference_token.find_first_of('~', pos + 1))
9156             {
9157                 assert(reference_token[pos] == '~');
9158 
9159                 // ~ must be followed by 0 or 1
9160                 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
9161                                   (reference_token[pos + 1] != '0' and
9162                                    reference_token[pos + 1] != '1')))
9163                 {
9164                     JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
9165                 }
9166             }
9167 
9168             // finally, store the reference token
9169             unescape(reference_token);
9170             result.push_back(reference_token);
9171         }
9172 
9173         return result;
9174     }
9175 
9176     /*!
9177     @brief replace all occurrences of a substring by another string
9178 
9179     @param[in,out] s  the string to manipulate; changed so that all
9180                    occurrences of @a f are replaced with @a t
9181     @param[in]     f  the substring to replace with @a t
9182     @param[in]     t  the string to replace @a f
9183 
9184     @pre The search string @a f must not be empty. **This precondition is
9185     enforced with an assertion.**
9186 
9187     @since version 2.0.0
9188     */
replace_substring(std::string & s,const std::string & f,const std::string & t)9189     static void replace_substring(std::string& s, const std::string& f,
9190                                   const std::string& t)
9191     {
9192         assert(not f.empty());
9193         for (auto pos = s.find(f);                // find first occurrence of f
9194                 pos != std::string::npos;         // make sure f was found
9195                 s.replace(pos, f.size(), t),      // replace with t, and
9196                 pos = s.find(f, pos + t.size()))  // find next occurrence of f
9197         {}
9198     }
9199 
9200     /// escape "~" to "~0" and "/" to "~1"
escape(std::string s)9201     static std::string escape(std::string s)
9202     {
9203         replace_substring(s, "~", "~0");
9204         replace_substring(s, "/", "~1");
9205         return s;
9206     }
9207 
9208     /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)9209     static void unescape(std::string& s)
9210     {
9211         replace_substring(s, "~1", "/");
9212         replace_substring(s, "~0", "~");
9213     }
9214 
9215     /*!
9216     @param[in] reference_string  the reference string to the current value
9217     @param[in] value             the value to consider
9218     @param[in,out] result        the result object to insert values to
9219 
9220     @note Empty objects or arrays are flattened to `null`.
9221     */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)9222     static void flatten(const std::string& reference_string,
9223                         const BasicJsonType& value,
9224                         BasicJsonType& result)
9225     {
9226         switch (value.m_type)
9227         {
9228             case detail::value_t::array:
9229             {
9230                 if (value.m_value.array->empty())
9231                 {
9232                     // flatten empty array as null
9233                     result[reference_string] = nullptr;
9234                 }
9235                 else
9236                 {
9237                     // iterate array and use index as reference string
9238                     for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
9239                     {
9240                         flatten(reference_string + "/" + std::to_string(i),
9241                                 value.m_value.array->operator[](i), result);
9242                     }
9243                 }
9244                 break;
9245             }
9246 
9247             case detail::value_t::object:
9248             {
9249                 if (value.m_value.object->empty())
9250                 {
9251                     // flatten empty object as null
9252                     result[reference_string] = nullptr;
9253                 }
9254                 else
9255                 {
9256                     // iterate object and use keys as reference string
9257                     for (const auto& element : *value.m_value.object)
9258                     {
9259                         flatten(reference_string + "/" + escape(element.first), element.second, result);
9260                     }
9261                 }
9262                 break;
9263             }
9264 
9265             default:
9266             {
9267                 // add primitive value with its reference string
9268                 result[reference_string] = value;
9269                 break;
9270             }
9271         }
9272     }
9273 
9274     /*!
9275     @param[in] value  flattened JSON
9276 
9277     @return unflattened JSON
9278 
9279     @throw parse_error.109 if array index is not a number
9280     @throw type_error.314  if value is not an object
9281     @throw type_error.315  if object values are not primitive
9282     @throw type_error.313  if value cannot be unflattened
9283     */
9284     static BasicJsonType
unflatten(const BasicJsonType & value)9285     unflatten(const BasicJsonType& value)
9286     {
9287         if (JSON_UNLIKELY(not value.is_object()))
9288         {
9289             JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
9290         }
9291 
9292         BasicJsonType result;
9293 
9294         // iterate the JSON object values
9295         for (const auto& element : *value.m_value.object)
9296         {
9297             if (JSON_UNLIKELY(not element.second.is_primitive()))
9298             {
9299                 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
9300             }
9301 
9302             // assign value to reference pointed to by JSON pointer; Note that if
9303             // the JSON pointer is "" (i.e., points to the whole value), function
9304             // get_and_create returns a reference to result itself. An assignment
9305             // will then create a primitive value.
9306             json_pointer(element.first).get_and_create(result) = element.second;
9307         }
9308 
9309         return result;
9310     }
9311 
9312     /*!
9313     @brief compares two JSON pointers for equality
9314 
9315     @param[in] lhs  JSON pointer to compare
9316     @param[in] rhs  JSON pointer to compare
9317     @return whether @a lhs is equal to @a rhs
9318 
9319     @complexity Linear in the length of the JSON pointer
9320 
9321     @exceptionsafety No-throw guarantee: this function never throws exceptions.
9322     */
operator ==(json_pointer const & lhs,json_pointer const & rhs)9323     friend bool operator==(json_pointer const& lhs,
9324                            json_pointer const& rhs) noexcept
9325     {
9326         return lhs.reference_tokens == rhs.reference_tokens;
9327     }
9328 
9329     /*!
9330     @brief compares two JSON pointers for inequality
9331 
9332     @param[in] lhs  JSON pointer to compare
9333     @param[in] rhs  JSON pointer to compare
9334     @return whether @a lhs is not equal @a rhs
9335 
9336     @complexity Linear in the length of the JSON pointer
9337 
9338     @exceptionsafety No-throw guarantee: this function never throws exceptions.
9339     */
operator !=(json_pointer const & lhs,json_pointer const & rhs)9340     friend bool operator!=(json_pointer const& lhs,
9341                            json_pointer const& rhs) noexcept
9342     {
9343         return not (lhs == rhs);
9344     }
9345 
9346     /// the reference tokens
9347     std::vector<std::string> reference_tokens;
9348 };
9349 }  // namespace nlohmann
9350 
9351 // #include <nlohmann/detail/json_ref.hpp>
9352 
9353 
9354 #include <initializer_list>
9355 #include <utility>
9356 
9357 // #include <nlohmann/detail/meta/type_traits.hpp>
9358 
9359 
9360 namespace nlohmann
9361 {
9362 namespace detail
9363 {
9364 template<typename BasicJsonType>
9365 class json_ref
9366 {
9367   public:
9368     using value_type = BasicJsonType;
9369 
json_ref(value_type && value)9370     json_ref(value_type&& value)
9371         : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
9372     {}
9373 
json_ref(const value_type & value)9374     json_ref(const value_type& value)
9375         : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
9376     {}
9377 
json_ref(std::initializer_list<json_ref> init)9378     json_ref(std::initializer_list<json_ref> init)
9379         : owned_value(init), value_ref(&owned_value), is_rvalue(true)
9380     {}
9381 
9382     template <
9383         class... Args,
9384         enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
json_ref(Args &&...args)9385     json_ref(Args && ... args)
9386         : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
9387           is_rvalue(true) {}
9388 
9389     // class should be movable only
9390     json_ref(json_ref&&) = default;
9391     json_ref(const json_ref&) = delete;
9392     json_ref& operator=(const json_ref&) = delete;
9393     json_ref& operator=(json_ref&&) = delete;
9394     ~json_ref() = default;
9395 
moved_or_copied() const9396     value_type moved_or_copied() const
9397     {
9398         if (is_rvalue)
9399         {
9400             return std::move(*value_ref);
9401         }
9402         return *value_ref;
9403     }
9404 
operator *() const9405     value_type const& operator*() const
9406     {
9407         return *static_cast<value_type const*>(value_ref);
9408     }
9409 
operator ->() const9410     value_type const* operator->() const
9411     {
9412         return static_cast<value_type const*>(value_ref);
9413     }
9414 
9415   private:
9416     mutable value_type owned_value = nullptr;
9417     value_type* value_ref = nullptr;
9418     const bool is_rvalue;
9419 };
9420 }  // namespace detail
9421 }  // namespace nlohmann
9422 
9423 // #include <nlohmann/detail/macro_scope.hpp>
9424 
9425 // #include <nlohmann/detail/meta/cpp_future.hpp>
9426 
9427 // #include <nlohmann/detail/meta/type_traits.hpp>
9428 
9429 // #include <nlohmann/detail/output/binary_writer.hpp>
9430 
9431 
9432 #include <algorithm> // reverse
9433 #include <array> // array
9434 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
9435 #include <cstring> // memcpy
9436 #include <limits> // numeric_limits
9437 #include <string> // string
9438 
9439 // #include <nlohmann/detail/input/binary_reader.hpp>
9440 
9441 // #include <nlohmann/detail/output/output_adapters.hpp>
9442 
9443 
9444 #include <algorithm> // copy
9445 #include <cstddef> // size_t
9446 #include <ios> // streamsize
9447 #include <iterator> // back_inserter
9448 #include <memory> // shared_ptr, make_shared
9449 #include <ostream> // basic_ostream
9450 #include <string> // basic_string
9451 #include <vector> // vector
9452 
9453 namespace nlohmann
9454 {
9455 namespace detail
9456 {
9457 /// abstract output adapter interface
9458 template<typename CharType> struct output_adapter_protocol
9459 {
9460     virtual void write_character(CharType c) = 0;
9461     virtual void write_characters(const CharType* s, std::size_t length) = 0;
9462     virtual ~output_adapter_protocol() = default;
9463 };
9464 
9465 /// a type to simplify interfaces
9466 template<typename CharType>
9467 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
9468 
9469 /// output adapter for byte vectors
9470 template<typename CharType>
9471 class output_vector_adapter : public output_adapter_protocol<CharType>
9472 {
9473   public:
output_vector_adapter(std::vector<CharType> & vec)9474     explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
9475         : v(vec)
9476     {}
9477 
write_character(CharType c)9478     void write_character(CharType c) override
9479     {
9480         v.push_back(c);
9481     }
9482 
write_characters(const CharType * s,std::size_t length)9483     void write_characters(const CharType* s, std::size_t length) override
9484     {
9485         std::copy(s, s + length, std::back_inserter(v));
9486     }
9487 
9488   private:
9489     std::vector<CharType>& v;
9490 };
9491 
9492 /// output adapter for output streams
9493 template<typename CharType>
9494 class output_stream_adapter : public output_adapter_protocol<CharType>
9495 {
9496   public:
output_stream_adapter(std::basic_ostream<CharType> & s)9497     explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
9498         : stream(s)
9499     {}
9500 
write_character(CharType c)9501     void write_character(CharType c) override
9502     {
9503         stream.put(c);
9504     }
9505 
write_characters(const CharType * s,std::size_t length)9506     void write_characters(const CharType* s, std::size_t length) override
9507     {
9508         stream.write(s, static_cast<std::streamsize>(length));
9509     }
9510 
9511   private:
9512     std::basic_ostream<CharType>& stream;
9513 };
9514 
9515 /// output adapter for basic_string
9516 template<typename CharType, typename StringType = std::basic_string<CharType>>
9517 class output_string_adapter : public output_adapter_protocol<CharType>
9518 {
9519   public:
output_string_adapter(StringType & s)9520     explicit output_string_adapter(StringType& s) noexcept
9521         : str(s)
9522     {}
9523 
write_character(CharType c)9524     void write_character(CharType c) override
9525     {
9526         str.push_back(c);
9527     }
9528 
write_characters(const CharType * s,std::size_t length)9529     void write_characters(const CharType* s, std::size_t length) override
9530     {
9531         str.append(s, length);
9532     }
9533 
9534   private:
9535     StringType& str;
9536 };
9537 
9538 template<typename CharType, typename StringType = std::basic_string<CharType>>
9539 class output_adapter
9540 {
9541   public:
output_adapter(std::vector<CharType> & vec)9542     output_adapter(std::vector<CharType>& vec)
9543         : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
9544 
output_adapter(std::basic_ostream<CharType> & s)9545     output_adapter(std::basic_ostream<CharType>& s)
9546         : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
9547 
output_adapter(StringType & s)9548     output_adapter(StringType& s)
9549         : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
9550 
operator output_adapter_t<CharType>()9551     operator output_adapter_t<CharType>()
9552     {
9553         return oa;
9554     }
9555 
9556   private:
9557     output_adapter_t<CharType> oa = nullptr;
9558 };
9559 }  // namespace detail
9560 }  // namespace nlohmann
9561 
9562 
9563 namespace nlohmann
9564 {
9565 namespace detail
9566 {
9567 ///////////////////
9568 // binary writer //
9569 ///////////////////
9570 
9571 /*!
9572 @brief serialization to CBOR and MessagePack values
9573 */
9574 template<typename BasicJsonType, typename CharType>
9575 class binary_writer
9576 {
9577     using string_t = typename BasicJsonType::string_t;
9578 
9579   public:
9580     /*!
9581     @brief create a binary writer
9582 
9583     @param[in] adapter  output adapter to write to
9584     */
binary_writer(output_adapter_t<CharType> adapter)9585     explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
9586     {
9587         assert(oa);
9588     }
9589 
9590     /*!
9591     @param[in] j  JSON value to serialize
9592     @pre       j.type() == value_t::object
9593     */
write_bson(const BasicJsonType & j)9594     void write_bson(const BasicJsonType& j)
9595     {
9596         switch (j.type())
9597         {
9598             case value_t::object:
9599             {
9600                 write_bson_object(*j.m_value.object);
9601                 break;
9602             }
9603 
9604             default:
9605             {
9606                 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
9607             }
9608         }
9609     }
9610 
9611     /*!
9612     @param[in] j  JSON value to serialize
9613     */
write_cbor(const BasicJsonType & j)9614     void write_cbor(const BasicJsonType& j)
9615     {
9616         switch (j.type())
9617         {
9618             case value_t::null:
9619             {
9620                 oa->write_character(to_char_type(0xF6));
9621                 break;
9622             }
9623 
9624             case value_t::boolean:
9625             {
9626                 oa->write_character(j.m_value.boolean
9627                                     ? to_char_type(0xF5)
9628                                     : to_char_type(0xF4));
9629                 break;
9630             }
9631 
9632             case value_t::number_integer:
9633             {
9634                 if (j.m_value.number_integer >= 0)
9635                 {
9636                     // CBOR does not differentiate between positive signed
9637                     // integers and unsigned integers. Therefore, we used the
9638                     // code from the value_t::number_unsigned case here.
9639                     if (j.m_value.number_integer <= 0x17)
9640                     {
9641                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9642                     }
9643                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
9644                     {
9645                         oa->write_character(to_char_type(0x18));
9646                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9647                     }
9648                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
9649                     {
9650                         oa->write_character(to_char_type(0x19));
9651                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
9652                     }
9653                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
9654                     {
9655                         oa->write_character(to_char_type(0x1A));
9656                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
9657                     }
9658                     else
9659                     {
9660                         oa->write_character(to_char_type(0x1B));
9661                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
9662                     }
9663                 }
9664                 else
9665                 {
9666                     // The conversions below encode the sign in the first
9667                     // byte, and the value is converted to a positive number.
9668                     const auto positive_number = -1 - j.m_value.number_integer;
9669                     if (j.m_value.number_integer >= -24)
9670                     {
9671                         write_number(static_cast<std::uint8_t>(0x20 + positive_number));
9672                     }
9673                     else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
9674                     {
9675                         oa->write_character(to_char_type(0x38));
9676                         write_number(static_cast<std::uint8_t>(positive_number));
9677                     }
9678                     else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
9679                     {
9680                         oa->write_character(to_char_type(0x39));
9681                         write_number(static_cast<std::uint16_t>(positive_number));
9682                     }
9683                     else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
9684                     {
9685                         oa->write_character(to_char_type(0x3A));
9686                         write_number(static_cast<std::uint32_t>(positive_number));
9687                     }
9688                     else
9689                     {
9690                         oa->write_character(to_char_type(0x3B));
9691                         write_number(static_cast<std::uint64_t>(positive_number));
9692                     }
9693                 }
9694                 break;
9695             }
9696 
9697             case value_t::number_unsigned:
9698             {
9699                 if (j.m_value.number_unsigned <= 0x17)
9700                 {
9701                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
9702                 }
9703                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9704                 {
9705                     oa->write_character(to_char_type(0x18));
9706                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
9707                 }
9708                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9709                 {
9710                     oa->write_character(to_char_type(0x19));
9711                     write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
9712                 }
9713                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9714                 {
9715                     oa->write_character(to_char_type(0x1A));
9716                     write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
9717                 }
9718                 else
9719                 {
9720                     oa->write_character(to_char_type(0x1B));
9721                     write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
9722                 }
9723                 break;
9724             }
9725 
9726             case value_t::number_float:
9727             {
9728                 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
9729                 write_number(j.m_value.number_float);
9730                 break;
9731             }
9732 
9733             case value_t::string:
9734             {
9735                 // step 1: write control byte and the string length
9736                 const auto N = j.m_value.string->size();
9737                 if (N <= 0x17)
9738                 {
9739                     write_number(static_cast<std::uint8_t>(0x60 + N));
9740                 }
9741                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9742                 {
9743                     oa->write_character(to_char_type(0x78));
9744                     write_number(static_cast<std::uint8_t>(N));
9745                 }
9746                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9747                 {
9748                     oa->write_character(to_char_type(0x79));
9749                     write_number(static_cast<std::uint16_t>(N));
9750                 }
9751                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9752                 {
9753                     oa->write_character(to_char_type(0x7A));
9754                     write_number(static_cast<std::uint32_t>(N));
9755                 }
9756                 // LCOV_EXCL_START
9757                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9758                 {
9759                     oa->write_character(to_char_type(0x7B));
9760                     write_number(static_cast<std::uint64_t>(N));
9761                 }
9762                 // LCOV_EXCL_STOP
9763 
9764                 // step 2: write the string
9765                 oa->write_characters(
9766                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
9767                     j.m_value.string->size());
9768                 break;
9769             }
9770 
9771             case value_t::array:
9772             {
9773                 // step 1: write control byte and the array size
9774                 const auto N = j.m_value.array->size();
9775                 if (N <= 0x17)
9776                 {
9777                     write_number(static_cast<std::uint8_t>(0x80 + N));
9778                 }
9779                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9780                 {
9781                     oa->write_character(to_char_type(0x98));
9782                     write_number(static_cast<std::uint8_t>(N));
9783                 }
9784                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9785                 {
9786                     oa->write_character(to_char_type(0x99));
9787                     write_number(static_cast<std::uint16_t>(N));
9788                 }
9789                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9790                 {
9791                     oa->write_character(to_char_type(0x9A));
9792                     write_number(static_cast<std::uint32_t>(N));
9793                 }
9794                 // LCOV_EXCL_START
9795                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9796                 {
9797                     oa->write_character(to_char_type(0x9B));
9798                     write_number(static_cast<std::uint64_t>(N));
9799                 }
9800                 // LCOV_EXCL_STOP
9801 
9802                 // step 2: write each element
9803                 for (const auto& el : *j.m_value.array)
9804                 {
9805                     write_cbor(el);
9806                 }
9807                 break;
9808             }
9809 
9810             case value_t::object:
9811             {
9812                 // step 1: write control byte and the object size
9813                 const auto N = j.m_value.object->size();
9814                 if (N <= 0x17)
9815                 {
9816                     write_number(static_cast<std::uint8_t>(0xA0 + N));
9817                 }
9818                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9819                 {
9820                     oa->write_character(to_char_type(0xB8));
9821                     write_number(static_cast<std::uint8_t>(N));
9822                 }
9823                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9824                 {
9825                     oa->write_character(to_char_type(0xB9));
9826                     write_number(static_cast<std::uint16_t>(N));
9827                 }
9828                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9829                 {
9830                     oa->write_character(to_char_type(0xBA));
9831                     write_number(static_cast<std::uint32_t>(N));
9832                 }
9833                 // LCOV_EXCL_START
9834                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9835                 {
9836                     oa->write_character(to_char_type(0xBB));
9837                     write_number(static_cast<std::uint64_t>(N));
9838                 }
9839                 // LCOV_EXCL_STOP
9840 
9841                 // step 2: write each element
9842                 for (const auto& el : *j.m_value.object)
9843                 {
9844                     write_cbor(el.first);
9845                     write_cbor(el.second);
9846                 }
9847                 break;
9848             }
9849 
9850             default:
9851                 break;
9852         }
9853     }
9854 
9855     /*!
9856     @param[in] j  JSON value to serialize
9857     */
write_msgpack(const BasicJsonType & j)9858     void write_msgpack(const BasicJsonType& j)
9859     {
9860         switch (j.type())
9861         {
9862             case value_t::null: // nil
9863             {
9864                 oa->write_character(to_char_type(0xC0));
9865                 break;
9866             }
9867 
9868             case value_t::boolean: // true and false
9869             {
9870                 oa->write_character(j.m_value.boolean
9871                                     ? to_char_type(0xC3)
9872                                     : to_char_type(0xC2));
9873                 break;
9874             }
9875 
9876             case value_t::number_integer:
9877             {
9878                 if (j.m_value.number_integer >= 0)
9879                 {
9880                     // MessagePack does not differentiate between positive
9881                     // signed integers and unsigned integers. Therefore, we used
9882                     // the code from the value_t::number_unsigned case here.
9883                     if (j.m_value.number_unsigned < 128)
9884                     {
9885                         // positive fixnum
9886                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9887                     }
9888                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9889                     {
9890                         // uint 8
9891                         oa->write_character(to_char_type(0xCC));
9892                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9893                     }
9894                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9895                     {
9896                         // uint 16
9897                         oa->write_character(to_char_type(0xCD));
9898                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
9899                     }
9900                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9901                     {
9902                         // uint 32
9903                         oa->write_character(to_char_type(0xCE));
9904                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
9905                     }
9906                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9907                     {
9908                         // uint 64
9909                         oa->write_character(to_char_type(0xCF));
9910                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
9911                     }
9912                 }
9913                 else
9914                 {
9915                     if (j.m_value.number_integer >= -32)
9916                     {
9917                         // negative fixnum
9918                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
9919                     }
9920                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
9921                              j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
9922                     {
9923                         // int 8
9924                         oa->write_character(to_char_type(0xD0));
9925                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
9926                     }
9927                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
9928                              j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
9929                     {
9930                         // int 16
9931                         oa->write_character(to_char_type(0xD1));
9932                         write_number(static_cast<std::int16_t>(j.m_value.number_integer));
9933                     }
9934                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
9935                              j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
9936                     {
9937                         // int 32
9938                         oa->write_character(to_char_type(0xD2));
9939                         write_number(static_cast<std::int32_t>(j.m_value.number_integer));
9940                     }
9941                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
9942                              j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
9943                     {
9944                         // int 64
9945                         oa->write_character(to_char_type(0xD3));
9946                         write_number(static_cast<std::int64_t>(j.m_value.number_integer));
9947                     }
9948                 }
9949                 break;
9950             }
9951 
9952             case value_t::number_unsigned:
9953             {
9954                 if (j.m_value.number_unsigned < 128)
9955                 {
9956                     // positive fixnum
9957                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9958                 }
9959                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9960                 {
9961                     // uint 8
9962                     oa->write_character(to_char_type(0xCC));
9963                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9964                 }
9965                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9966                 {
9967                     // uint 16
9968                     oa->write_character(to_char_type(0xCD));
9969                     write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
9970                 }
9971                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9972                 {
9973                     // uint 32
9974                     oa->write_character(to_char_type(0xCE));
9975                     write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
9976                 }
9977                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9978                 {
9979                     // uint 64
9980                     oa->write_character(to_char_type(0xCF));
9981                     write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
9982                 }
9983                 break;
9984             }
9985 
9986             case value_t::number_float:
9987             {
9988                 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
9989                 write_number(j.m_value.number_float);
9990                 break;
9991             }
9992 
9993             case value_t::string:
9994             {
9995                 // step 1: write control byte and the string length
9996                 const auto N = j.m_value.string->size();
9997                 if (N <= 31)
9998                 {
9999                     // fixstr
10000                     write_number(static_cast<std::uint8_t>(0xA0 | N));
10001                 }
10002                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
10003                 {
10004                     // str 8
10005                     oa->write_character(to_char_type(0xD9));
10006                     write_number(static_cast<std::uint8_t>(N));
10007                 }
10008                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10009                 {
10010                     // str 16
10011                     oa->write_character(to_char_type(0xDA));
10012                     write_number(static_cast<std::uint16_t>(N));
10013                 }
10014                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10015                 {
10016                     // str 32
10017                     oa->write_character(to_char_type(0xDB));
10018                     write_number(static_cast<std::uint32_t>(N));
10019                 }
10020 
10021                 // step 2: write the string
10022                 oa->write_characters(
10023                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
10024                     j.m_value.string->size());
10025                 break;
10026             }
10027 
10028             case value_t::array:
10029             {
10030                 // step 1: write control byte and the array size
10031                 const auto N = j.m_value.array->size();
10032                 if (N <= 15)
10033                 {
10034                     // fixarray
10035                     write_number(static_cast<std::uint8_t>(0x90 | N));
10036                 }
10037                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10038                 {
10039                     // array 16
10040                     oa->write_character(to_char_type(0xDC));
10041                     write_number(static_cast<std::uint16_t>(N));
10042                 }
10043                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10044                 {
10045                     // array 32
10046                     oa->write_character(to_char_type(0xDD));
10047                     write_number(static_cast<std::uint32_t>(N));
10048                 }
10049 
10050                 // step 2: write each element
10051                 for (const auto& el : *j.m_value.array)
10052                 {
10053                     write_msgpack(el);
10054                 }
10055                 break;
10056             }
10057 
10058             case value_t::object:
10059             {
10060                 // step 1: write control byte and the object size
10061                 const auto N = j.m_value.object->size();
10062                 if (N <= 15)
10063                 {
10064                     // fixmap
10065                     write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
10066                 }
10067                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10068                 {
10069                     // map 16
10070                     oa->write_character(to_char_type(0xDE));
10071                     write_number(static_cast<std::uint16_t>(N));
10072                 }
10073                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10074                 {
10075                     // map 32
10076                     oa->write_character(to_char_type(0xDF));
10077                     write_number(static_cast<std::uint32_t>(N));
10078                 }
10079 
10080                 // step 2: write each element
10081                 for (const auto& el : *j.m_value.object)
10082                 {
10083                     write_msgpack(el.first);
10084                     write_msgpack(el.second);
10085                 }
10086                 break;
10087             }
10088 
10089             default:
10090                 break;
10091         }
10092     }
10093 
10094     /*!
10095     @param[in] j  JSON value to serialize
10096     @param[in] use_count   whether to use '#' prefixes (optimized format)
10097     @param[in] use_type    whether to use '$' prefixes (optimized format)
10098     @param[in] add_prefix  whether prefixes need to be used for this value
10099     */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)10100     void write_ubjson(const BasicJsonType& j, const bool use_count,
10101                       const bool use_type, const bool add_prefix = true)
10102     {
10103         switch (j.type())
10104         {
10105             case value_t::null:
10106             {
10107                 if (add_prefix)
10108                 {
10109                     oa->write_character(to_char_type('Z'));
10110                 }
10111                 break;
10112             }
10113 
10114             case value_t::boolean:
10115             {
10116                 if (add_prefix)
10117                 {
10118                     oa->write_character(j.m_value.boolean
10119                                         ? to_char_type('T')
10120                                         : to_char_type('F'));
10121                 }
10122                 break;
10123             }
10124 
10125             case value_t::number_integer:
10126             {
10127                 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
10128                 break;
10129             }
10130 
10131             case value_t::number_unsigned:
10132             {
10133                 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
10134                 break;
10135             }
10136 
10137             case value_t::number_float:
10138             {
10139                 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
10140                 break;
10141             }
10142 
10143             case value_t::string:
10144             {
10145                 if (add_prefix)
10146                 {
10147                     oa->write_character(to_char_type('S'));
10148                 }
10149                 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
10150                 oa->write_characters(
10151                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
10152                     j.m_value.string->size());
10153                 break;
10154             }
10155 
10156             case value_t::array:
10157             {
10158                 if (add_prefix)
10159                 {
10160                     oa->write_character(to_char_type('['));
10161                 }
10162 
10163                 bool prefix_required = true;
10164                 if (use_type and not j.m_value.array->empty())
10165                 {
10166                     assert(use_count);
10167                     const CharType first_prefix = ubjson_prefix(j.front());
10168                     const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
10169                                                          [this, first_prefix](const BasicJsonType & v)
10170                     {
10171                         return ubjson_prefix(v) == first_prefix;
10172                     });
10173 
10174                     if (same_prefix)
10175                     {
10176                         prefix_required = false;
10177                         oa->write_character(to_char_type('$'));
10178                         oa->write_character(first_prefix);
10179                     }
10180                 }
10181 
10182                 if (use_count)
10183                 {
10184                     oa->write_character(to_char_type('#'));
10185                     write_number_with_ubjson_prefix(j.m_value.array->size(), true);
10186                 }
10187 
10188                 for (const auto& el : *j.m_value.array)
10189                 {
10190                     write_ubjson(el, use_count, use_type, prefix_required);
10191                 }
10192 
10193                 if (not use_count)
10194                 {
10195                     oa->write_character(to_char_type(']'));
10196                 }
10197 
10198                 break;
10199             }
10200 
10201             case value_t::object:
10202             {
10203                 if (add_prefix)
10204                 {
10205                     oa->write_character(to_char_type('{'));
10206                 }
10207 
10208                 bool prefix_required = true;
10209                 if (use_type and not j.m_value.object->empty())
10210                 {
10211                     assert(use_count);
10212                     const CharType first_prefix = ubjson_prefix(j.front());
10213                     const bool same_prefix = std::all_of(j.begin(), j.end(),
10214                                                          [this, first_prefix](const BasicJsonType & v)
10215                     {
10216                         return ubjson_prefix(v) == first_prefix;
10217                     });
10218 
10219                     if (same_prefix)
10220                     {
10221                         prefix_required = false;
10222                         oa->write_character(to_char_type('$'));
10223                         oa->write_character(first_prefix);
10224                     }
10225                 }
10226 
10227                 if (use_count)
10228                 {
10229                     oa->write_character(to_char_type('#'));
10230                     write_number_with_ubjson_prefix(j.m_value.object->size(), true);
10231                 }
10232 
10233                 for (const auto& el : *j.m_value.object)
10234                 {
10235                     write_number_with_ubjson_prefix(el.first.size(), true);
10236                     oa->write_characters(
10237                         reinterpret_cast<const CharType*>(el.first.c_str()),
10238                         el.first.size());
10239                     write_ubjson(el.second, use_count, use_type, prefix_required);
10240                 }
10241 
10242                 if (not use_count)
10243                 {
10244                     oa->write_character(to_char_type('}'));
10245                 }
10246 
10247                 break;
10248             }
10249 
10250             default:
10251                 break;
10252         }
10253     }
10254 
10255   private:
10256     //////////
10257     // BSON //
10258     //////////
10259 
10260     /*!
10261     @return The size of a BSON document entry header, including the id marker
10262             and the entry name size (and its null-terminator).
10263     */
calc_bson_entry_header_size(const string_t & name)10264     static std::size_t calc_bson_entry_header_size(const string_t& name)
10265     {
10266         const auto it = name.find(static_cast<typename string_t::value_type>(0));
10267         if (JSON_UNLIKELY(it != BasicJsonType::string_t::npos))
10268         {
10269             JSON_THROW(out_of_range::create(409,
10270                                             "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
10271         }
10272 
10273         return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
10274     }
10275 
10276     /*!
10277     @brief Writes the given @a element_type and @a name to the output adapter
10278     */
write_bson_entry_header(const string_t & name,const std::uint8_t element_type)10279     void write_bson_entry_header(const string_t& name,
10280                                  const std::uint8_t element_type)
10281     {
10282         oa->write_character(to_char_type(element_type)); // boolean
10283         oa->write_characters(
10284             reinterpret_cast<const CharType*>(name.c_str()),
10285             name.size() + 1u);
10286     }
10287 
10288     /*!
10289     @brief Writes a BSON element with key @a name and boolean value @a value
10290     */
write_bson_boolean(const string_t & name,const bool value)10291     void write_bson_boolean(const string_t& name,
10292                             const bool value)
10293     {
10294         write_bson_entry_header(name, 0x08);
10295         oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
10296     }
10297 
10298     /*!
10299     @brief Writes a BSON element with key @a name and double value @a value
10300     */
write_bson_double(const string_t & name,const double value)10301     void write_bson_double(const string_t& name,
10302                            const double value)
10303     {
10304         write_bson_entry_header(name, 0x01);
10305         write_number<double, true>(value);
10306     }
10307 
10308     /*!
10309     @return The size of the BSON-encoded string in @a value
10310     */
calc_bson_string_size(const string_t & value)10311     static std::size_t calc_bson_string_size(const string_t& value)
10312     {
10313         return sizeof(std::int32_t) + value.size() + 1ul;
10314     }
10315 
10316     /*!
10317     @brief Writes a BSON element with key @a name and string value @a value
10318     */
write_bson_string(const string_t & name,const string_t & value)10319     void write_bson_string(const string_t& name,
10320                            const string_t& value)
10321     {
10322         write_bson_entry_header(name, 0x02);
10323 
10324         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
10325         oa->write_characters(
10326             reinterpret_cast<const CharType*>(value.c_str()),
10327             value.size() + 1);
10328     }
10329 
10330     /*!
10331     @brief Writes a BSON element with key @a name and null value
10332     */
write_bson_null(const string_t & name)10333     void write_bson_null(const string_t& name)
10334     {
10335         write_bson_entry_header(name, 0x0A);
10336     }
10337 
10338     /*!
10339     @return The size of the BSON-encoded integer @a value
10340     */
calc_bson_integer_size(const std::int64_t value)10341     static std::size_t calc_bson_integer_size(const std::int64_t value)
10342     {
10343         return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
10344                ? sizeof(std::int32_t)
10345                : sizeof(std::int64_t);
10346     }
10347 
10348     /*!
10349     @brief Writes a BSON element with key @a name and integer @a value
10350     */
write_bson_integer(const string_t & name,const std::int64_t value)10351     void write_bson_integer(const string_t& name,
10352                             const std::int64_t value)
10353     {
10354         if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
10355         {
10356             write_bson_entry_header(name, 0x10); // int32
10357             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
10358         }
10359         else
10360         {
10361             write_bson_entry_header(name, 0x12); // int64
10362             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
10363         }
10364     }
10365 
10366     /*!
10367     @return The size of the BSON-encoded unsigned integer in @a j
10368     */
calc_bson_unsigned_size(const std::uint64_t value)10369     static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
10370     {
10371         return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10372                ? sizeof(std::int32_t)
10373                : sizeof(std::int64_t);
10374     }
10375 
10376     /*!
10377     @brief Writes a BSON element with key @a name and unsigned @a value
10378     */
write_bson_unsigned(const string_t & name,const std::uint64_t value)10379     void write_bson_unsigned(const string_t& name,
10380                              const std::uint64_t value)
10381     {
10382         if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10383         {
10384             write_bson_entry_header(name, 0x10 /* int32 */);
10385             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
10386         }
10387         else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
10388         {
10389             write_bson_entry_header(name, 0x12 /* int64 */);
10390             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
10391         }
10392         else
10393         {
10394             JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
10395         }
10396     }
10397 
10398     /*!
10399     @brief Writes a BSON element with key @a name and object @a value
10400     */
write_bson_object_entry(const string_t & name,const typename BasicJsonType::object_t & value)10401     void write_bson_object_entry(const string_t& name,
10402                                  const typename BasicJsonType::object_t& value)
10403     {
10404         write_bson_entry_header(name, 0x03); // object
10405         write_bson_object(value);
10406     }
10407 
10408     /*!
10409     @return The size of the BSON-encoded array @a value
10410     */
calc_bson_array_size(const typename BasicJsonType::array_t & value)10411     static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
10412     {
10413         std::size_t embedded_document_size = 0ul;
10414         std::size_t array_index = 0ul;
10415 
10416         for (const auto& el : value)
10417         {
10418             embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
10419         }
10420 
10421         return sizeof(std::int32_t) + embedded_document_size + 1ul;
10422     }
10423 
10424     /*!
10425     @brief Writes a BSON element with key @a name and array @a value
10426     */
write_bson_array(const string_t & name,const typename BasicJsonType::array_t & value)10427     void write_bson_array(const string_t& name,
10428                           const typename BasicJsonType::array_t& value)
10429     {
10430         write_bson_entry_header(name, 0x04); // array
10431         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
10432 
10433         std::size_t array_index = 0ul;
10434 
10435         for (const auto& el : value)
10436         {
10437             write_bson_element(std::to_string(array_index++), el);
10438         }
10439 
10440         oa->write_character(to_char_type(0x00));
10441     }
10442 
10443     /*!
10444     @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
10445     @return The calculated size for the BSON document entry for @a j with the given @a name.
10446     */
calc_bson_element_size(const string_t & name,const BasicJsonType & j)10447     static std::size_t calc_bson_element_size(const string_t& name,
10448             const BasicJsonType& j)
10449     {
10450         const auto header_size = calc_bson_entry_header_size(name);
10451         switch (j.type())
10452         {
10453             case value_t::object:
10454                 return header_size + calc_bson_object_size(*j.m_value.object);
10455 
10456             case value_t::array:
10457                 return header_size + calc_bson_array_size(*j.m_value.array);
10458 
10459             case value_t::boolean:
10460                 return header_size + 1ul;
10461 
10462             case value_t::number_float:
10463                 return header_size + 8ul;
10464 
10465             case value_t::number_integer:
10466                 return header_size + calc_bson_integer_size(j.m_value.number_integer);
10467 
10468             case value_t::number_unsigned:
10469                 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
10470 
10471             case value_t::string:
10472                 return header_size + calc_bson_string_size(*j.m_value.string);
10473 
10474             case value_t::null:
10475                 return header_size + 0ul;
10476 
10477             // LCOV_EXCL_START
10478             default:
10479                 assert(false);
10480                 return 0ul;
10481                 // LCOV_EXCL_STOP
10482         }
10483     }
10484 
10485     /*!
10486     @brief Serializes the JSON value @a j to BSON and associates it with the
10487            key @a name.
10488     @param name The name to associate with the JSON entity @a j within the
10489                 current BSON document
10490     @return The size of the BSON entry
10491     */
write_bson_element(const string_t & name,const BasicJsonType & j)10492     void write_bson_element(const string_t& name,
10493                             const BasicJsonType& j)
10494     {
10495         switch (j.type())
10496         {
10497             case value_t::object:
10498                 return write_bson_object_entry(name, *j.m_value.object);
10499 
10500             case value_t::array:
10501                 return write_bson_array(name, *j.m_value.array);
10502 
10503             case value_t::boolean:
10504                 return write_bson_boolean(name, j.m_value.boolean);
10505 
10506             case value_t::number_float:
10507                 return write_bson_double(name, j.m_value.number_float);
10508 
10509             case value_t::number_integer:
10510                 return write_bson_integer(name, j.m_value.number_integer);
10511 
10512             case value_t::number_unsigned:
10513                 return write_bson_unsigned(name, j.m_value.number_unsigned);
10514 
10515             case value_t::string:
10516                 return write_bson_string(name, *j.m_value.string);
10517 
10518             case value_t::null:
10519                 return write_bson_null(name);
10520 
10521             // LCOV_EXCL_START
10522             default:
10523                 assert(false);
10524                 return;
10525                 // LCOV_EXCL_STOP
10526         }
10527     }
10528 
10529     /*!
10530     @brief Calculates the size of the BSON serialization of the given
10531            JSON-object @a j.
10532     @param[in] j  JSON value to serialize
10533     @pre       j.type() == value_t::object
10534     */
calc_bson_object_size(const typename BasicJsonType::object_t & value)10535     static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
10536     {
10537         std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
10538                                     [](size_t result, const typename BasicJsonType::object_t::value_type & el)
10539         {
10540             return result += calc_bson_element_size(el.first, el.second);
10541         });
10542 
10543         return sizeof(std::int32_t) + document_size + 1ul;
10544     }
10545 
10546     /*!
10547     @param[in] j  JSON value to serialize
10548     @pre       j.type() == value_t::object
10549     */
write_bson_object(const typename BasicJsonType::object_t & value)10550     void write_bson_object(const typename BasicJsonType::object_t& value)
10551     {
10552         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
10553 
10554         for (const auto& el : value)
10555         {
10556             write_bson_element(el.first, el.second);
10557         }
10558 
10559         oa->write_character(to_char_type(0x00));
10560     }
10561 
10562     //////////
10563     // CBOR //
10564     //////////
10565 
get_cbor_float_prefix(float)10566     static constexpr CharType get_cbor_float_prefix(float /*unused*/)
10567     {
10568         return to_char_type(0xFA);  // Single-Precision Float
10569     }
10570 
get_cbor_float_prefix(double)10571     static constexpr CharType get_cbor_float_prefix(double /*unused*/)
10572     {
10573         return to_char_type(0xFB);  // Double-Precision Float
10574     }
10575 
10576     /////////////
10577     // MsgPack //
10578     /////////////
10579 
get_msgpack_float_prefix(float)10580     static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
10581     {
10582         return to_char_type(0xCA);  // float 32
10583     }
10584 
get_msgpack_float_prefix(double)10585     static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
10586     {
10587         return to_char_type(0xCB);  // float 64
10588     }
10589 
10590     ////////////
10591     // UBJSON //
10592     ////////////
10593 
10594     // UBJSON: write number (floating point)
10595     template<typename NumberType, typename std::enable_if<
10596                  std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10597     void write_number_with_ubjson_prefix(const NumberType n,
10598                                          const bool add_prefix)
10599     {
10600         if (add_prefix)
10601         {
10602             oa->write_character(get_ubjson_float_prefix(n));
10603         }
10604         write_number(n);
10605     }
10606 
10607     // UBJSON: write number (unsigned integer)
10608     template<typename NumberType, typename std::enable_if<
10609                  std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10610     void write_number_with_ubjson_prefix(const NumberType n,
10611                                          const bool add_prefix)
10612     {
10613         if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
10614         {
10615             if (add_prefix)
10616             {
10617                 oa->write_character(to_char_type('i'));  // int8
10618             }
10619             write_number(static_cast<std::uint8_t>(n));
10620         }
10621         else if (n <= (std::numeric_limits<std::uint8_t>::max)())
10622         {
10623             if (add_prefix)
10624             {
10625                 oa->write_character(to_char_type('U'));  // uint8
10626             }
10627             write_number(static_cast<std::uint8_t>(n));
10628         }
10629         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
10630         {
10631             if (add_prefix)
10632             {
10633                 oa->write_character(to_char_type('I'));  // int16
10634             }
10635             write_number(static_cast<std::int16_t>(n));
10636         }
10637         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10638         {
10639             if (add_prefix)
10640             {
10641                 oa->write_character(to_char_type('l'));  // int32
10642             }
10643             write_number(static_cast<std::int32_t>(n));
10644         }
10645         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
10646         {
10647             if (add_prefix)
10648             {
10649                 oa->write_character(to_char_type('L'));  // int64
10650             }
10651             write_number(static_cast<std::int64_t>(n));
10652         }
10653         else
10654         {
10655             JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
10656         }
10657     }
10658 
10659     // UBJSON: write number (signed integer)
10660     template<typename NumberType, typename std::enable_if<
10661                  std::is_signed<NumberType>::value and
10662                  not std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10663     void write_number_with_ubjson_prefix(const NumberType n,
10664                                          const bool add_prefix)
10665     {
10666         if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
10667         {
10668             if (add_prefix)
10669             {
10670                 oa->write_character(to_char_type('i'));  // int8
10671             }
10672             write_number(static_cast<std::int8_t>(n));
10673         }
10674         else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
10675         {
10676             if (add_prefix)
10677             {
10678                 oa->write_character(to_char_type('U'));  // uint8
10679             }
10680             write_number(static_cast<std::uint8_t>(n));
10681         }
10682         else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
10683         {
10684             if (add_prefix)
10685             {
10686                 oa->write_character(to_char_type('I'));  // int16
10687             }
10688             write_number(static_cast<std::int16_t>(n));
10689         }
10690         else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
10691         {
10692             if (add_prefix)
10693             {
10694                 oa->write_character(to_char_type('l'));  // int32
10695             }
10696             write_number(static_cast<std::int32_t>(n));
10697         }
10698         else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
10699         {
10700             if (add_prefix)
10701             {
10702                 oa->write_character(to_char_type('L'));  // int64
10703             }
10704             write_number(static_cast<std::int64_t>(n));
10705         }
10706         // LCOV_EXCL_START
10707         else
10708         {
10709             JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
10710         }
10711         // LCOV_EXCL_STOP
10712     }
10713 
10714     /*!
10715     @brief determine the type prefix of container values
10716 
10717     @note This function does not need to be 100% accurate when it comes to
10718           integer limits. In case a number exceeds the limits of int64_t,
10719           this will be detected by a later call to function
10720           write_number_with_ubjson_prefix. Therefore, we return 'L' for any
10721           value that does not fit the previous limits.
10722     */
ubjson_prefix(const BasicJsonType & j) const10723     CharType ubjson_prefix(const BasicJsonType& j) const noexcept
10724     {
10725         switch (j.type())
10726         {
10727             case value_t::null:
10728                 return 'Z';
10729 
10730             case value_t::boolean:
10731                 return j.m_value.boolean ? 'T' : 'F';
10732 
10733             case value_t::number_integer:
10734             {
10735                 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
10736                 {
10737                     return 'i';
10738                 }
10739                 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
10740                 {
10741                     return 'U';
10742                 }
10743                 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
10744                 {
10745                     return 'I';
10746                 }
10747                 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
10748                 {
10749                     return 'l';
10750                 }
10751                 // no check and assume int64_t (see note above)
10752                 return 'L';
10753             }
10754 
10755             case value_t::number_unsigned:
10756             {
10757                 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int8_t>::max)())
10758                 {
10759                     return 'i';
10760                 }
10761                 if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
10762                 {
10763                     return 'U';
10764                 }
10765                 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int16_t>::max)())
10766                 {
10767                     return 'I';
10768                 }
10769                 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int32_t>::max)())
10770                 {
10771                     return 'l';
10772                 }
10773                 // no check and assume int64_t (see note above)
10774                 return 'L';
10775             }
10776 
10777             case value_t::number_float:
10778                 return get_ubjson_float_prefix(j.m_value.number_float);
10779 
10780             case value_t::string:
10781                 return 'S';
10782 
10783             case value_t::array:
10784                 return '[';
10785 
10786             case value_t::object:
10787                 return '{';
10788 
10789             default:  // discarded values
10790                 return 'N';
10791         }
10792     }
10793 
get_ubjson_float_prefix(float)10794     static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
10795     {
10796         return 'd';  // float 32
10797     }
10798 
get_ubjson_float_prefix(double)10799     static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
10800     {
10801         return 'D';  // float 64
10802     }
10803 
10804     ///////////////////////
10805     // Utility functions //
10806     ///////////////////////
10807 
10808     /*
10809     @brief write a number to output input
10810     @param[in] n number of type @a NumberType
10811     @tparam NumberType the type of the number
10812     @tparam OutputIsLittleEndian Set to true if output data is
10813                                  required to be little endian
10814 
10815     @note This function needs to respect the system's endianess, because bytes
10816           in CBOR, MessagePack, and UBJSON are stored in network order (big
10817           endian) and therefore need reordering on little endian systems.
10818     */
10819     template<typename NumberType, bool OutputIsLittleEndian = false>
write_number(const NumberType n)10820     void write_number(const NumberType n)
10821     {
10822         // step 1: write number to array of length NumberType
10823         std::array<CharType, sizeof(NumberType)> vec;
10824         std::memcpy(vec.data(), &n, sizeof(NumberType));
10825 
10826         // step 2: write array to output (with possible reordering)
10827         if (is_little_endian != OutputIsLittleEndian)
10828         {
10829             // reverse byte order prior to conversion if necessary
10830             std::reverse(vec.begin(), vec.end());
10831         }
10832 
10833         oa->write_characters(vec.data(), sizeof(NumberType));
10834     }
10835 
10836   public:
10837     // The following to_char_type functions are implement the conversion
10838     // between uint8_t and CharType. In case CharType is not unsigned,
10839     // such a conversion is required to allow values greater than 128.
10840     // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
10841     template < typename C = CharType,
10842                enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
to_char_type(std::uint8_t x)10843     static constexpr CharType to_char_type(std::uint8_t x) noexcept
10844     {
10845         return *reinterpret_cast<char*>(&x);
10846     }
10847 
10848     template < typename C = CharType,
10849                enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
to_char_type(std::uint8_t x)10850     static CharType to_char_type(std::uint8_t x) noexcept
10851     {
10852         static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
10853         static_assert(std::is_pod<CharType>::value, "CharType must be POD");
10854         CharType result;
10855         std::memcpy(&result, &x, sizeof(x));
10856         return result;
10857     }
10858 
10859     template<typename C = CharType,
10860              enable_if_t<std::is_unsigned<C>::value>* = nullptr>
to_char_type(std::uint8_t x)10861     static constexpr CharType to_char_type(std::uint8_t x) noexcept
10862     {
10863         return x;
10864     }
10865 
10866     template < typename InputCharType, typename C = CharType,
10867                enable_if_t <
10868                    std::is_signed<C>::value and
10869                    std::is_signed<char>::value and
10870                    std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
10871                    > * = nullptr >
to_char_type(InputCharType x)10872     static constexpr CharType to_char_type(InputCharType x) noexcept
10873     {
10874         return x;
10875     }
10876 
10877   private:
10878     /// whether we can assume little endianess
10879     const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
10880 
10881     /// the output
10882     output_adapter_t<CharType> oa = nullptr;
10883 };
10884 }  // namespace detail
10885 }  // namespace nlohmann
10886 
10887 // #include <nlohmann/detail/output/output_adapters.hpp>
10888 
10889 // #include <nlohmann/detail/output/serializer.hpp>
10890 
10891 
10892 #include <algorithm> // reverse, remove, fill, find, none_of
10893 #include <array> // array
10894 #include <cassert> // assert
10895 #include <ciso646> // and, or
10896 #include <clocale> // localeconv, lconv
10897 #include <cmath> // labs, isfinite, isnan, signbit
10898 #include <cstddef> // size_t, ptrdiff_t
10899 #include <cstdint> // uint8_t
10900 #include <cstdio> // snprintf
10901 #include <limits> // numeric_limits
10902 #include <string> // string
10903 #include <type_traits> // is_same
10904 #include <utility> // move
10905 
10906 // #include <nlohmann/detail/conversions/to_chars.hpp>
10907 
10908 
10909 #include <array> // array
10910 #include <cassert> // assert
10911 #include <ciso646> // or, and, not
10912 #include <cmath>   // signbit, isfinite
10913 #include <cstdint> // intN_t, uintN_t
10914 #include <cstring> // memcpy, memmove
10915 #include <limits> // numeric_limits
10916 #include <type_traits> // conditional
10917 
10918 namespace nlohmann
10919 {
10920 namespace detail
10921 {
10922 
10923 /*!
10924 @brief implements the Grisu2 algorithm for binary to decimal floating-point
10925 conversion.
10926 
10927 This implementation is a slightly modified version of the reference
10928 implementation which may be obtained from
10929 http://florian.loitsch.com/publications (bench.tar.gz).
10930 
10931 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
10932 
10933 For a detailed description of the algorithm see:
10934 
10935 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
10936     Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
10937     Language Design and Implementation, PLDI 2010
10938 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
10939     Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
10940     Design and Implementation, PLDI 1996
10941 */
10942 namespace dtoa_impl
10943 {
10944 
10945 template <typename Target, typename Source>
10946 Target reinterpret_bits(const Source source)
10947 {
10948     static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
10949 
10950     Target target;
10951     std::memcpy(&target, &source, sizeof(Source));
10952     return target;
10953 }
10954 
10955 struct diyfp // f * 2^e
10956 {
10957     static constexpr int kPrecision = 64; // = q
10958 
10959     std::uint64_t f = 0;
10960     int e = 0;
10961 
diyfpnlohmann::detail::dtoa_impl::diyfp10962     constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
10963 
10964     /*!
10965     @brief returns x - y
10966     @pre x.e == y.e and x.f >= y.f
10967     */
subnlohmann::detail::dtoa_impl::diyfp10968     static diyfp sub(const diyfp& x, const diyfp& y) noexcept
10969     {
10970         assert(x.e == y.e);
10971         assert(x.f >= y.f);
10972 
10973         return {x.f - y.f, x.e};
10974     }
10975 
10976     /*!
10977     @brief returns x * y
10978     @note The result is rounded. (Only the upper q bits are returned.)
10979     */
mulnlohmann::detail::dtoa_impl::diyfp10980     static diyfp mul(const diyfp& x, const diyfp& y) noexcept
10981     {
10982         static_assert(kPrecision == 64, "internal error");
10983 
10984         // Computes:
10985         //  f = round((x.f * y.f) / 2^q)
10986         //  e = x.e + y.e + q
10987 
10988         // Emulate the 64-bit * 64-bit multiplication:
10989         //
10990         // p = u * v
10991         //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
10992         //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
10993         //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
10994         //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
10995         //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
10996         //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
10997         //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
10998         //
10999         // (Since Q might be larger than 2^32 - 1)
11000         //
11001         //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
11002         //
11003         // (Q_hi + H does not overflow a 64-bit int)
11004         //
11005         //   = p_lo + 2^64 p_hi
11006 
11007         const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
11008         const std::uint64_t u_hi = x.f >> 32u;
11009         const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
11010         const std::uint64_t v_hi = y.f >> 32u;
11011 
11012         const std::uint64_t p0 = u_lo * v_lo;
11013         const std::uint64_t p1 = u_lo * v_hi;
11014         const std::uint64_t p2 = u_hi * v_lo;
11015         const std::uint64_t p3 = u_hi * v_hi;
11016 
11017         const std::uint64_t p0_hi = p0 >> 32u;
11018         const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
11019         const std::uint64_t p1_hi = p1 >> 32u;
11020         const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
11021         const std::uint64_t p2_hi = p2 >> 32u;
11022 
11023         std::uint64_t Q = p0_hi + p1_lo + p2_lo;
11024 
11025         // The full product might now be computed as
11026         //
11027         // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
11028         // p_lo = p0_lo + (Q << 32)
11029         //
11030         // But in this particular case here, the full p_lo is not required.
11031         // Effectively we only need to add the highest bit in p_lo to p_hi (and
11032         // Q_hi + 1 does not overflow).
11033 
11034         Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
11035 
11036         const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
11037 
11038         return {h, x.e + y.e + 64};
11039     }
11040 
11041     /*!
11042     @brief normalize x such that the significand is >= 2^(q-1)
11043     @pre x.f != 0
11044     */
normalizenlohmann::detail::dtoa_impl::diyfp11045     static diyfp normalize(diyfp x) noexcept
11046     {
11047         assert(x.f != 0);
11048 
11049         while ((x.f >> 63u) == 0)
11050         {
11051             x.f <<= 1u;
11052             x.e--;
11053         }
11054 
11055         return x;
11056     }
11057 
11058     /*!
11059     @brief normalize x such that the result has the exponent E
11060     @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
11061     */
normalize_tonlohmann::detail::dtoa_impl::diyfp11062     static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
11063     {
11064         const int delta = x.e - target_exponent;
11065 
11066         assert(delta >= 0);
11067         assert(((x.f << delta) >> delta) == x.f);
11068 
11069         return {x.f << delta, target_exponent};
11070     }
11071 };
11072 
11073 struct boundaries
11074 {
11075     diyfp w;
11076     diyfp minus;
11077     diyfp plus;
11078 };
11079 
11080 /*!
11081 Compute the (normalized) diyfp representing the input number 'value' and its
11082 boundaries.
11083 
11084 @pre value must be finite and positive
11085 */
11086 template <typename FloatType>
compute_boundaries(FloatType value)11087 boundaries compute_boundaries(FloatType value)
11088 {
11089     assert(std::isfinite(value));
11090     assert(value > 0);
11091 
11092     // Convert the IEEE representation into a diyfp.
11093     //
11094     // If v is denormal:
11095     //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
11096     // If v is normalized:
11097     //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
11098 
11099     static_assert(std::numeric_limits<FloatType>::is_iec559,
11100                   "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
11101 
11102     constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
11103     constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
11104     constexpr int      kMinExp    = 1 - kBias;
11105     constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
11106 
11107     using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
11108 
11109     const std::uint64_t bits = reinterpret_bits<bits_type>(value);
11110     const std::uint64_t E = bits >> (kPrecision - 1);
11111     const std::uint64_t F = bits & (kHiddenBit - 1);
11112 
11113     const bool is_denormal = E == 0;
11114     const diyfp v = is_denormal
11115                     ? diyfp(F, kMinExp)
11116                     : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
11117 
11118     // Compute the boundaries m- and m+ of the floating-point value
11119     // v = f * 2^e.
11120     //
11121     // Determine v- and v+, the floating-point predecessor and successor if v,
11122     // respectively.
11123     //
11124     //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
11125     //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
11126     //
11127     //      v+ = v + 2^e
11128     //
11129     // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
11130     // between m- and m+ round to v, regardless of how the input rounding
11131     // algorithm breaks ties.
11132     //
11133     //      ---+-------------+-------------+-------------+-------------+---  (A)
11134     //         v-            m-            v             m+            v+
11135     //
11136     //      -----------------+------+------+-------------+-------------+---  (B)
11137     //                       v-     m-     v             m+            v+
11138 
11139     const bool lower_boundary_is_closer = F == 0 and E > 1;
11140     const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
11141     const diyfp m_minus = lower_boundary_is_closer
11142                           ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
11143                           : diyfp(2 * v.f - 1, v.e - 1); // (A)
11144 
11145     // Determine the normalized w+ = m+.
11146     const diyfp w_plus = diyfp::normalize(m_plus);
11147 
11148     // Determine w- = m- such that e_(w-) = e_(w+).
11149     const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
11150 
11151     return {diyfp::normalize(v), w_minus, w_plus};
11152 }
11153 
11154 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
11155 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
11156 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
11157 //
11158 //      alpha <= e = e_c + e_w + q <= gamma
11159 //
11160 // or
11161 //
11162 //      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
11163 //                          <= f_c * f_w * 2^gamma
11164 //
11165 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
11166 //
11167 //      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
11168 //
11169 // or
11170 //
11171 //      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
11172 //
11173 // The choice of (alpha,gamma) determines the size of the table and the form of
11174 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
11175 // in practice:
11176 //
11177 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
11178 // processed independently: An integral part p1, and a fractional part p2:
11179 //
11180 //      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
11181 //              = (f div 2^-e) + (f mod 2^-e) * 2^e
11182 //              = p1 + p2 * 2^e
11183 //
11184 // The conversion of p1 into decimal form requires a series of divisions and
11185 // modulos by (a power of) 10. These operations are faster for 32-bit than for
11186 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
11187 // achieved by choosing
11188 //
11189 //      -e >= 32   or   e <= -32 := gamma
11190 //
11191 // In order to convert the fractional part
11192 //
11193 //      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
11194 //
11195 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
11196 // d[-i] are extracted in order:
11197 //
11198 //      (10 * p2) div 2^-e = d[-1]
11199 //      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
11200 //
11201 // The multiplication by 10 must not overflow. It is sufficient to choose
11202 //
11203 //      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
11204 //
11205 // Since p2 = f mod 2^-e < 2^-e,
11206 //
11207 //      -e <= 60   or   e >= -60 := alpha
11208 
11209 constexpr int kAlpha = -60;
11210 constexpr int kGamma = -32;
11211 
11212 struct cached_power // c = f * 2^e ~= 10^k
11213 {
11214     std::uint64_t f;
11215     int e;
11216     int k;
11217 };
11218 
11219 /*!
11220 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
11221 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
11222 satisfies (Definition 3.2 from [1])
11223 
11224      alpha <= e_c + e + q <= gamma.
11225 */
get_cached_power_for_binary_exponent(int e)11226 inline cached_power get_cached_power_for_binary_exponent(int e)
11227 {
11228     // Now
11229     //
11230     //      alpha <= e_c + e + q <= gamma                                    (1)
11231     //      ==> f_c * 2^alpha <= c * 2^e * 2^q
11232     //
11233     // and since the c's are normalized, 2^(q-1) <= f_c,
11234     //
11235     //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
11236     //      ==> 2^(alpha - e - 1) <= c
11237     //
11238     // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
11239     //
11240     //      k = ceil( log_10( 2^(alpha - e - 1) ) )
11241     //        = ceil( (alpha - e - 1) * log_10(2) )
11242     //
11243     // From the paper:
11244     // "In theory the result of the procedure could be wrong since c is rounded,
11245     //  and the computation itself is approximated [...]. In practice, however,
11246     //  this simple function is sufficient."
11247     //
11248     // For IEEE double precision floating-point numbers converted into
11249     // normalized diyfp's w = f * 2^e, with q = 64,
11250     //
11251     //      e >= -1022      (min IEEE exponent)
11252     //           -52        (p - 1)
11253     //           -52        (p - 1, possibly normalize denormal IEEE numbers)
11254     //           -11        (normalize the diyfp)
11255     //         = -1137
11256     //
11257     // and
11258     //
11259     //      e <= +1023      (max IEEE exponent)
11260     //           -52        (p - 1)
11261     //           -11        (normalize the diyfp)
11262     //         = 960
11263     //
11264     // This binary exponent range [-1137,960] results in a decimal exponent
11265     // range [-307,324]. One does not need to store a cached power for each
11266     // k in this range. For each such k it suffices to find a cached power
11267     // such that the exponent of the product lies in [alpha,gamma].
11268     // This implies that the difference of the decimal exponents of adjacent
11269     // table entries must be less than or equal to
11270     //
11271     //      floor( (gamma - alpha) * log_10(2) ) = 8.
11272     //
11273     // (A smaller distance gamma-alpha would require a larger table.)
11274 
11275     // NB:
11276     // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
11277 
11278     constexpr int kCachedPowersMinDecExp = -300;
11279     constexpr int kCachedPowersDecStep = 8;
11280 
11281     static constexpr std::array<cached_power, 79> kCachedPowers =
11282     {
11283         {
11284             { 0xAB70FE17C79AC6CA, -1060, -300 },
11285             { 0xFF77B1FCBEBCDC4F, -1034, -292 },
11286             { 0xBE5691EF416BD60C, -1007, -284 },
11287             { 0x8DD01FAD907FFC3C,  -980, -276 },
11288             { 0xD3515C2831559A83,  -954, -268 },
11289             { 0x9D71AC8FADA6C9B5,  -927, -260 },
11290             { 0xEA9C227723EE8BCB,  -901, -252 },
11291             { 0xAECC49914078536D,  -874, -244 },
11292             { 0x823C12795DB6CE57,  -847, -236 },
11293             { 0xC21094364DFB5637,  -821, -228 },
11294             { 0x9096EA6F3848984F,  -794, -220 },
11295             { 0xD77485CB25823AC7,  -768, -212 },
11296             { 0xA086CFCD97BF97F4,  -741, -204 },
11297             { 0xEF340A98172AACE5,  -715, -196 },
11298             { 0xB23867FB2A35B28E,  -688, -188 },
11299             { 0x84C8D4DFD2C63F3B,  -661, -180 },
11300             { 0xC5DD44271AD3CDBA,  -635, -172 },
11301             { 0x936B9FCEBB25C996,  -608, -164 },
11302             { 0xDBAC6C247D62A584,  -582, -156 },
11303             { 0xA3AB66580D5FDAF6,  -555, -148 },
11304             { 0xF3E2F893DEC3F126,  -529, -140 },
11305             { 0xB5B5ADA8AAFF80B8,  -502, -132 },
11306             { 0x87625F056C7C4A8B,  -475, -124 },
11307             { 0xC9BCFF6034C13053,  -449, -116 },
11308             { 0x964E858C91BA2655,  -422, -108 },
11309             { 0xDFF9772470297EBD,  -396, -100 },
11310             { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
11311             { 0xF8A95FCF88747D94,  -343,  -84 },
11312             { 0xB94470938FA89BCF,  -316,  -76 },
11313             { 0x8A08F0F8BF0F156B,  -289,  -68 },
11314             { 0xCDB02555653131B6,  -263,  -60 },
11315             { 0x993FE2C6D07B7FAC,  -236,  -52 },
11316             { 0xE45C10C42A2B3B06,  -210,  -44 },
11317             { 0xAA242499697392D3,  -183,  -36 },
11318             { 0xFD87B5F28300CA0E,  -157,  -28 },
11319             { 0xBCE5086492111AEB,  -130,  -20 },
11320             { 0x8CBCCC096F5088CC,  -103,  -12 },
11321             { 0xD1B71758E219652C,   -77,   -4 },
11322             { 0x9C40000000000000,   -50,    4 },
11323             { 0xE8D4A51000000000,   -24,   12 },
11324             { 0xAD78EBC5AC620000,     3,   20 },
11325             { 0x813F3978F8940984,    30,   28 },
11326             { 0xC097CE7BC90715B3,    56,   36 },
11327             { 0x8F7E32CE7BEA5C70,    83,   44 },
11328             { 0xD5D238A4ABE98068,   109,   52 },
11329             { 0x9F4F2726179A2245,   136,   60 },
11330             { 0xED63A231D4C4FB27,   162,   68 },
11331             { 0xB0DE65388CC8ADA8,   189,   76 },
11332             { 0x83C7088E1AAB65DB,   216,   84 },
11333             { 0xC45D1DF942711D9A,   242,   92 },
11334             { 0x924D692CA61BE758,   269,  100 },
11335             { 0xDA01EE641A708DEA,   295,  108 },
11336             { 0xA26DA3999AEF774A,   322,  116 },
11337             { 0xF209787BB47D6B85,   348,  124 },
11338             { 0xB454E4A179DD1877,   375,  132 },
11339             { 0x865B86925B9BC5C2,   402,  140 },
11340             { 0xC83553C5C8965D3D,   428,  148 },
11341             { 0x952AB45CFA97A0B3,   455,  156 },
11342             { 0xDE469FBD99A05FE3,   481,  164 },
11343             { 0xA59BC234DB398C25,   508,  172 },
11344             { 0xF6C69A72A3989F5C,   534,  180 },
11345             { 0xB7DCBF5354E9BECE,   561,  188 },
11346             { 0x88FCF317F22241E2,   588,  196 },
11347             { 0xCC20CE9BD35C78A5,   614,  204 },
11348             { 0x98165AF37B2153DF,   641,  212 },
11349             { 0xE2A0B5DC971F303A,   667,  220 },
11350             { 0xA8D9D1535CE3B396,   694,  228 },
11351             { 0xFB9B7CD9A4A7443C,   720,  236 },
11352             { 0xBB764C4CA7A44410,   747,  244 },
11353             { 0x8BAB8EEFB6409C1A,   774,  252 },
11354             { 0xD01FEF10A657842C,   800,  260 },
11355             { 0x9B10A4E5E9913129,   827,  268 },
11356             { 0xE7109BFBA19C0C9D,   853,  276 },
11357             { 0xAC2820D9623BF429,   880,  284 },
11358             { 0x80444B5E7AA7CF85,   907,  292 },
11359             { 0xBF21E44003ACDD2D,   933,  300 },
11360             { 0x8E679C2F5E44FF8F,   960,  308 },
11361             { 0xD433179D9C8CB841,   986,  316 },
11362             { 0x9E19DB92B4E31BA9,  1013,  324 },
11363         }
11364     };
11365 
11366     // This computation gives exactly the same results for k as
11367     //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
11368     // for |e| <= 1500, but doesn't require floating-point operations.
11369     // NB: log_10(2) ~= 78913 / 2^18
11370     assert(e >= -1500);
11371     assert(e <=  1500);
11372     const int f = kAlpha - e - 1;
11373     const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
11374 
11375     const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
11376     assert(index >= 0);
11377     assert(static_cast<std::size_t>(index) < kCachedPowers.size());
11378 
11379     const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
11380     assert(kAlpha <= cached.e + e + 64);
11381     assert(kGamma >= cached.e + e + 64);
11382 
11383     return cached;
11384 }
11385 
11386 /*!
11387 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
11388 For n == 0, returns 1 and sets pow10 := 1.
11389 */
find_largest_pow10(const std::uint32_t n,std::uint32_t & pow10)11390 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
11391 {
11392     // LCOV_EXCL_START
11393     if (n >= 1000000000)
11394     {
11395         pow10 = 1000000000;
11396         return 10;
11397     }
11398     // LCOV_EXCL_STOP
11399     else if (n >= 100000000)
11400     {
11401         pow10 = 100000000;
11402         return  9;
11403     }
11404     else if (n >= 10000000)
11405     {
11406         pow10 = 10000000;
11407         return  8;
11408     }
11409     else if (n >= 1000000)
11410     {
11411         pow10 = 1000000;
11412         return  7;
11413     }
11414     else if (n >= 100000)
11415     {
11416         pow10 = 100000;
11417         return  6;
11418     }
11419     else if (n >= 10000)
11420     {
11421         pow10 = 10000;
11422         return  5;
11423     }
11424     else if (n >= 1000)
11425     {
11426         pow10 = 1000;
11427         return  4;
11428     }
11429     else if (n >= 100)
11430     {
11431         pow10 = 100;
11432         return  3;
11433     }
11434     else if (n >= 10)
11435     {
11436         pow10 = 10;
11437         return  2;
11438     }
11439     else
11440     {
11441         pow10 = 1;
11442         return 1;
11443     }
11444 }
11445 
grisu2_round(char * buf,int len,std::uint64_t dist,std::uint64_t delta,std::uint64_t rest,std::uint64_t ten_k)11446 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
11447                          std::uint64_t rest, std::uint64_t ten_k)
11448 {
11449     assert(len >= 1);
11450     assert(dist <= delta);
11451     assert(rest <= delta);
11452     assert(ten_k > 0);
11453 
11454     //               <--------------------------- delta ---->
11455     //                                  <---- dist --------->
11456     // --------------[------------------+-------------------]--------------
11457     //               M-                 w                   M+
11458     //
11459     //                                  ten_k
11460     //                                <------>
11461     //                                       <---- rest ---->
11462     // --------------[------------------+----+--------------]--------------
11463     //                                  w    V
11464     //                                       = buf * 10^k
11465     //
11466     // ten_k represents a unit-in-the-last-place in the decimal representation
11467     // stored in buf.
11468     // Decrement buf by ten_k while this takes buf closer to w.
11469 
11470     // The tests are written in this order to avoid overflow in unsigned
11471     // integer arithmetic.
11472 
11473     while (rest < dist
11474             and delta - rest >= ten_k
11475             and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
11476     {
11477         assert(buf[len - 1] != '0');
11478         buf[len - 1]--;
11479         rest += ten_k;
11480     }
11481 }
11482 
11483 /*!
11484 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
11485 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
11486 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)11487 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
11488                              diyfp M_minus, diyfp w, diyfp M_plus)
11489 {
11490     static_assert(kAlpha >= -60, "internal error");
11491     static_assert(kGamma <= -32, "internal error");
11492 
11493     // Generates the digits (and the exponent) of a decimal floating-point
11494     // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
11495     // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
11496     //
11497     //               <--------------------------- delta ---->
11498     //                                  <---- dist --------->
11499     // --------------[------------------+-------------------]--------------
11500     //               M-                 w                   M+
11501     //
11502     // Grisu2 generates the digits of M+ from left to right and stops as soon as
11503     // V is in [M-,M+].
11504 
11505     assert(M_plus.e >= kAlpha);
11506     assert(M_plus.e <= kGamma);
11507 
11508     std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
11509     std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
11510 
11511     // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
11512     //
11513     //      M+ = f * 2^e
11514     //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
11515     //         = ((p1        ) * 2^-e + (p2        )) * 2^e
11516     //         = p1 + p2 * 2^e
11517 
11518     const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
11519 
11520     auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
11521     std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
11522 
11523     // 1)
11524     //
11525     // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
11526 
11527     assert(p1 > 0);
11528 
11529     std::uint32_t pow10;
11530     const int k = find_largest_pow10(p1, pow10);
11531 
11532     //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
11533     //
11534     //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
11535     //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
11536     //
11537     //      M+ = p1                                             + p2 * 2^e
11538     //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
11539     //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
11540     //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
11541     //
11542     // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
11543     //
11544     //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
11545     //
11546     // but stop as soon as
11547     //
11548     //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
11549 
11550     int n = k;
11551     while (n > 0)
11552     {
11553         // Invariants:
11554         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
11555         //      pow10 = 10^(n-1) <= p1 < 10^n
11556         //
11557         const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
11558         const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
11559         //
11560         //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
11561         //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
11562         //
11563         assert(d <= 9);
11564         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
11565         //
11566         //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
11567         //
11568         p1 = r;
11569         n--;
11570         //
11571         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
11572         //      pow10 = 10^n
11573         //
11574 
11575         // Now check if enough digits have been generated.
11576         // Compute
11577         //
11578         //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
11579         //
11580         // Note:
11581         // Since rest and delta share the same exponent e, it suffices to
11582         // compare the significands.
11583         const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
11584         if (rest <= delta)
11585         {
11586             // V = buffer * 10^n, with M- <= V <= M+.
11587 
11588             decimal_exponent += n;
11589 
11590             // We may now just stop. But instead look if the buffer could be
11591             // decremented to bring V closer to w.
11592             //
11593             // pow10 = 10^n is now 1 ulp in the decimal representation V.
11594             // The rounding procedure works with diyfp's with an implicit
11595             // exponent of e.
11596             //
11597             //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
11598             //
11599             const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
11600             grisu2_round(buffer, length, dist, delta, rest, ten_n);
11601 
11602             return;
11603         }
11604 
11605         pow10 /= 10;
11606         //
11607         //      pow10 = 10^(n-1) <= p1 < 10^n
11608         // Invariants restored.
11609     }
11610 
11611     // 2)
11612     //
11613     // The digits of the integral part have been generated:
11614     //
11615     //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
11616     //         = buffer            + p2 * 2^e
11617     //
11618     // Now generate the digits of the fractional part p2 * 2^e.
11619     //
11620     // Note:
11621     // No decimal point is generated: the exponent is adjusted instead.
11622     //
11623     // p2 actually represents the fraction
11624     //
11625     //      p2 * 2^e
11626     //          = p2 / 2^-e
11627     //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
11628     //
11629     // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
11630     //
11631     //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
11632     //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
11633     //
11634     // using
11635     //
11636     //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
11637     //                = (                   d) * 2^-e + (                   r)
11638     //
11639     // or
11640     //      10^m * p2 * 2^e = d + r * 2^e
11641     //
11642     // i.e.
11643     //
11644     //      M+ = buffer + p2 * 2^e
11645     //         = buffer + 10^-m * (d + r * 2^e)
11646     //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
11647     //
11648     // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
11649 
11650     assert(p2 > delta);
11651 
11652     int m = 0;
11653     for (;;)
11654     {
11655         // Invariant:
11656         //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
11657         //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
11658         //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
11659         //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
11660         //
11661         assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
11662         p2 *= 10;
11663         const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
11664         const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
11665         //
11666         //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
11667         //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
11668         //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
11669         //
11670         assert(d <= 9);
11671         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
11672         //
11673         //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
11674         //
11675         p2 = r;
11676         m++;
11677         //
11678         //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
11679         // Invariant restored.
11680 
11681         // Check if enough digits have been generated.
11682         //
11683         //      10^-m * p2 * 2^e <= delta * 2^e
11684         //              p2 * 2^e <= 10^m * delta * 2^e
11685         //                    p2 <= 10^m * delta
11686         delta *= 10;
11687         dist  *= 10;
11688         if (p2 <= delta)
11689         {
11690             break;
11691         }
11692     }
11693 
11694     // V = buffer * 10^-m, with M- <= V <= M+.
11695 
11696     decimal_exponent -= m;
11697 
11698     // 1 ulp in the decimal representation is now 10^-m.
11699     // Since delta and dist are now scaled by 10^m, we need to do the
11700     // same with ulp in order to keep the units in sync.
11701     //
11702     //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
11703     //
11704     const std::uint64_t ten_m = one.f;
11705     grisu2_round(buffer, length, dist, delta, p2, ten_m);
11706 
11707     // By construction this algorithm generates the shortest possible decimal
11708     // number (Loitsch, Theorem 6.2) which rounds back to w.
11709     // For an input number of precision p, at least
11710     //
11711     //      N = 1 + ceil(p * log_10(2))
11712     //
11713     // decimal digits are sufficient to identify all binary floating-point
11714     // numbers (Matula, "In-and-Out conversions").
11715     // This implies that the algorithm does not produce more than N decimal
11716     // digits.
11717     //
11718     //      N = 17 for p = 53 (IEEE double precision)
11719     //      N = 9  for p = 24 (IEEE single precision)
11720 }
11721 
11722 /*!
11723 v = buf * 10^decimal_exponent
11724 len is the length of the buffer (number of decimal digits)
11725 The buffer must be large enough, i.e. >= max_digits10.
11726 */
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)11727 inline void grisu2(char* buf, int& len, int& decimal_exponent,
11728                    diyfp m_minus, diyfp v, diyfp m_plus)
11729 {
11730     assert(m_plus.e == m_minus.e);
11731     assert(m_plus.e == v.e);
11732 
11733     //  --------(-----------------------+-----------------------)--------    (A)
11734     //          m-                      v                       m+
11735     //
11736     //  --------------------(-----------+-----------------------)--------    (B)
11737     //                      m-          v                       m+
11738     //
11739     // First scale v (and m- and m+) such that the exponent is in the range
11740     // [alpha, gamma].
11741 
11742     const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
11743 
11744     const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
11745 
11746     // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
11747     const diyfp w       = diyfp::mul(v,       c_minus_k);
11748     const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
11749     const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
11750 
11751     //  ----(---+---)---------------(---+---)---------------(---+---)----
11752     //          w-                      w                       w+
11753     //          = c*m-                  = c*v                   = c*m+
11754     //
11755     // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
11756     // w+ are now off by a small amount.
11757     // In fact:
11758     //
11759     //      w - v * 10^k < 1 ulp
11760     //
11761     // To account for this inaccuracy, add resp. subtract 1 ulp.
11762     //
11763     //  --------+---[---------------(---+---)---------------]---+--------
11764     //          w-  M-                  w                   M+  w+
11765     //
11766     // Now any number in [M-, M+] (bounds included) will round to w when input,
11767     // regardless of how the input rounding algorithm breaks ties.
11768     //
11769     // And digit_gen generates the shortest possible such number in [M-, M+].
11770     // Note that this does not mean that Grisu2 always generates the shortest
11771     // possible number in the interval (m-, m+).
11772     const diyfp M_minus(w_minus.f + 1, w_minus.e);
11773     const diyfp M_plus (w_plus.f  - 1, w_plus.e );
11774 
11775     decimal_exponent = -cached.k; // = -(-k) = k
11776 
11777     grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
11778 }
11779 
11780 /*!
11781 v = buf * 10^decimal_exponent
11782 len is the length of the buffer (number of decimal digits)
11783 The buffer must be large enough, i.e. >= max_digits10.
11784 */
11785 template <typename FloatType>
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)11786 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
11787 {
11788     static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
11789                   "internal error: not enough precision");
11790 
11791     assert(std::isfinite(value));
11792     assert(value > 0);
11793 
11794     // If the neighbors (and boundaries) of 'value' are always computed for double-precision
11795     // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
11796     // decimal representations are not exactly "short".
11797     //
11798     // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
11799     // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
11800     // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
11801     // does.
11802     // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
11803     // representation using the corresponding std::from_chars function recovers value exactly". That
11804     // indicates that single precision floating-point numbers should be recovered using
11805     // 'std::strtof'.
11806     //
11807     // NB: If the neighbors are computed for single-precision numbers, there is a single float
11808     //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
11809     //     value is off by 1 ulp.
11810 #if 0
11811     const boundaries w = compute_boundaries(static_cast<double>(value));
11812 #else
11813     const boundaries w = compute_boundaries(value);
11814 #endif
11815 
11816     grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
11817 }
11818 
11819 /*!
11820 @brief appends a decimal representation of e to buf
11821 @return a pointer to the element following the exponent.
11822 @pre -1000 < e < 1000
11823 */
append_exponent(char * buf,int e)11824 inline char* append_exponent(char* buf, int e)
11825 {
11826     assert(e > -1000);
11827     assert(e <  1000);
11828 
11829     if (e < 0)
11830     {
11831         e = -e;
11832         *buf++ = '-';
11833     }
11834     else
11835     {
11836         *buf++ = '+';
11837     }
11838 
11839     auto k = static_cast<std::uint32_t>(e);
11840     if (k < 10)
11841     {
11842         // Always print at least two digits in the exponent.
11843         // This is for compatibility with printf("%g").
11844         *buf++ = '0';
11845         *buf++ = static_cast<char>('0' + k);
11846     }
11847     else if (k < 100)
11848     {
11849         *buf++ = static_cast<char>('0' + k / 10);
11850         k %= 10;
11851         *buf++ = static_cast<char>('0' + k);
11852     }
11853     else
11854     {
11855         *buf++ = static_cast<char>('0' + k / 100);
11856         k %= 100;
11857         *buf++ = static_cast<char>('0' + k / 10);
11858         k %= 10;
11859         *buf++ = static_cast<char>('0' + k);
11860     }
11861 
11862     return buf;
11863 }
11864 
11865 /*!
11866 @brief prettify v = buf * 10^decimal_exponent
11867 
11868 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
11869 notation. Otherwise it will be printed in exponential notation.
11870 
11871 @pre min_exp < 0
11872 @pre max_exp > 0
11873 */
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)11874 inline char* format_buffer(char* buf, int len, int decimal_exponent,
11875                            int min_exp, int max_exp)
11876 {
11877     assert(min_exp < 0);
11878     assert(max_exp > 0);
11879 
11880     const int k = len;
11881     const int n = len + decimal_exponent;
11882 
11883     // v = buf * 10^(n-k)
11884     // k is the length of the buffer (number of decimal digits)
11885     // n is the position of the decimal point relative to the start of the buffer.
11886 
11887     if (k <= n and n <= max_exp)
11888     {
11889         // digits[000]
11890         // len <= max_exp + 2
11891 
11892         std::memset(buf + k, '0', static_cast<size_t>(n - k));
11893         // Make it look like a floating-point number (#362, #378)
11894         buf[n + 0] = '.';
11895         buf[n + 1] = '0';
11896         return buf + (n + 2);
11897     }
11898 
11899     if (0 < n and n <= max_exp)
11900     {
11901         // dig.its
11902         // len <= max_digits10 + 1
11903 
11904         assert(k > n);
11905 
11906         std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
11907         buf[n] = '.';
11908         return buf + (k + 1);
11909     }
11910 
11911     if (min_exp < n and n <= 0)
11912     {
11913         // 0.[000]digits
11914         // len <= 2 + (-min_exp - 1) + max_digits10
11915 
11916         std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
11917         buf[0] = '0';
11918         buf[1] = '.';
11919         std::memset(buf + 2, '0', static_cast<size_t>(-n));
11920         return buf + (2 + (-n) + k);
11921     }
11922 
11923     if (k == 1)
11924     {
11925         // dE+123
11926         // len <= 1 + 5
11927 
11928         buf += 1;
11929     }
11930     else
11931     {
11932         // d.igitsE+123
11933         // len <= max_digits10 + 1 + 5
11934 
11935         std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
11936         buf[1] = '.';
11937         buf += 1 + k;
11938     }
11939 
11940     *buf++ = 'e';
11941     return append_exponent(buf, n - 1);
11942 }
11943 
11944 } // namespace dtoa_impl
11945 
11946 /*!
11947 @brief generates a decimal representation of the floating-point number value in [first, last).
11948 
11949 The format of the resulting decimal representation is similar to printf's %g
11950 format. Returns an iterator pointing past-the-end of the decimal representation.
11951 
11952 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
11953 @note The buffer must be large enough.
11954 @note The result is NOT null-terminated.
11955 */
11956 template <typename FloatType>
to_chars(char * first,const char * last,FloatType value)11957 char* to_chars(char* first, const char* last, FloatType value)
11958 {
11959     static_cast<void>(last); // maybe unused - fix warning
11960     assert(std::isfinite(value));
11961 
11962     // Use signbit(value) instead of (value < 0) since signbit works for -0.
11963     if (std::signbit(value))
11964     {
11965         value = -value;
11966         *first++ = '-';
11967     }
11968 
11969     if (value == 0) // +-0
11970     {
11971         *first++ = '0';
11972         // Make it look like a floating-point number (#362, #378)
11973         *first++ = '.';
11974         *first++ = '0';
11975         return first;
11976     }
11977 
11978     assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
11979 
11980     // Compute v = buffer * 10^decimal_exponent.
11981     // The decimal digits are stored in the buffer, which needs to be interpreted
11982     // as an unsigned decimal integer.
11983     // len is the length of the buffer, i.e. the number of decimal digits.
11984     int len = 0;
11985     int decimal_exponent = 0;
11986     dtoa_impl::grisu2(first, len, decimal_exponent, value);
11987 
11988     assert(len <= std::numeric_limits<FloatType>::max_digits10);
11989 
11990     // Format the buffer like printf("%.*g", prec, value)
11991     constexpr int kMinExp = -4;
11992     // Use digits10 here to increase compatibility with version 2.
11993     constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
11994 
11995     assert(last - first >= kMaxExp + 2);
11996     assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
11997     assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
11998 
11999     return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
12000 }
12001 
12002 } // namespace detail
12003 } // namespace nlohmann
12004 
12005 // #include <nlohmann/detail/exceptions.hpp>
12006 
12007 // #include <nlohmann/detail/macro_scope.hpp>
12008 
12009 // #include <nlohmann/detail/meta/cpp_future.hpp>
12010 
12011 // #include <nlohmann/detail/output/binary_writer.hpp>
12012 
12013 // #include <nlohmann/detail/output/output_adapters.hpp>
12014 
12015 // #include <nlohmann/detail/value_t.hpp>
12016 
12017 
12018 namespace nlohmann
12019 {
12020 namespace detail
12021 {
12022 ///////////////////
12023 // serialization //
12024 ///////////////////
12025 
12026 /// how to treat decoding errors
12027 enum class error_handler_t
12028 {
12029     strict,  ///< throw a type_error exception in case of invalid UTF-8
12030     replace, ///< replace invalid UTF-8 sequences with U+FFFD
12031     ignore   ///< ignore invalid UTF-8 sequences
12032 };
12033 
12034 template<typename BasicJsonType>
12035 class serializer
12036 {
12037     using string_t = typename BasicJsonType::string_t;
12038     using number_float_t = typename BasicJsonType::number_float_t;
12039     using number_integer_t = typename BasicJsonType::number_integer_t;
12040     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12041     static constexpr std::uint8_t UTF8_ACCEPT = 0;
12042     static constexpr std::uint8_t UTF8_REJECT = 1;
12043 
12044   public:
12045     /*!
12046     @param[in] s  output stream to serialize to
12047     @param[in] ichar  indentation character to use
12048     @param[in] error_handler_  how to react on decoding errors
12049     */
serializer(output_adapter_t<char> s,const char ichar,error_handler_t error_handler_=error_handler_t::strict)12050     serializer(output_adapter_t<char> s, const char ichar,
12051                error_handler_t error_handler_ = error_handler_t::strict)
12052         : o(std::move(s))
12053         , loc(std::localeconv())
12054         , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
12055         , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
12056         , indent_char(ichar)
12057         , indent_string(512, indent_char)
12058         , error_handler(error_handler_)
12059     {}
12060 
12061     // delete because of pointer members
12062     serializer(const serializer&) = delete;
12063     serializer& operator=(const serializer&) = delete;
12064     serializer(serializer&&) = delete;
12065     serializer& operator=(serializer&&) = delete;
12066     ~serializer() = default;
12067 
12068     /*!
12069     @brief internal implementation of the serialization function
12070 
12071     This function is called by the public member function dump and organizes
12072     the serialization internally. The indentation level is propagated as
12073     additional parameter. In case of arrays and objects, the function is
12074     called recursively.
12075 
12076     - strings and object keys are escaped using `escape_string()`
12077     - integer numbers are converted implicitly via `operator<<`
12078     - floating-point numbers are converted to a string using `"%g"` format
12079 
12080     @param[in] val             value to serialize
12081     @param[in] pretty_print    whether the output shall be pretty-printed
12082     @param[in] indent_step     the indent level
12083     @param[in] current_indent  the current indent level (only used internally)
12084     */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)12085     void dump(const BasicJsonType& val, const bool pretty_print,
12086               const bool ensure_ascii,
12087               const unsigned int indent_step,
12088               const unsigned int current_indent = 0)
12089     {
12090         switch (val.m_type)
12091         {
12092             case value_t::object:
12093             {
12094                 if (val.m_value.object->empty())
12095                 {
12096                     o->write_characters("{}", 2);
12097                     return;
12098                 }
12099 
12100                 if (pretty_print)
12101                 {
12102                     o->write_characters("{\n", 2);
12103 
12104                     // variable to hold indentation for recursive calls
12105                     const auto new_indent = current_indent + indent_step;
12106                     if (JSON_UNLIKELY(indent_string.size() < new_indent))
12107                     {
12108                         indent_string.resize(indent_string.size() * 2, ' ');
12109                     }
12110 
12111                     // first n-1 elements
12112                     auto i = val.m_value.object->cbegin();
12113                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12114                     {
12115                         o->write_characters(indent_string.c_str(), new_indent);
12116                         o->write_character('\"');
12117                         dump_escaped(i->first, ensure_ascii);
12118                         o->write_characters("\": ", 3);
12119                         dump(i->second, true, ensure_ascii, indent_step, new_indent);
12120                         o->write_characters(",\n", 2);
12121                     }
12122 
12123                     // last element
12124                     assert(i != val.m_value.object->cend());
12125                     assert(std::next(i) == val.m_value.object->cend());
12126                     o->write_characters(indent_string.c_str(), new_indent);
12127                     o->write_character('\"');
12128                     dump_escaped(i->first, ensure_ascii);
12129                     o->write_characters("\": ", 3);
12130                     dump(i->second, true, ensure_ascii, indent_step, new_indent);
12131 
12132                     o->write_character('\n');
12133                     o->write_characters(indent_string.c_str(), current_indent);
12134                     o->write_character('}');
12135                 }
12136                 else
12137                 {
12138                     o->write_character('{');
12139 
12140                     // first n-1 elements
12141                     auto i = val.m_value.object->cbegin();
12142                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12143                     {
12144                         o->write_character('\"');
12145                         dump_escaped(i->first, ensure_ascii);
12146                         o->write_characters("\":", 2);
12147                         dump(i->second, false, ensure_ascii, indent_step, current_indent);
12148                         o->write_character(',');
12149                     }
12150 
12151                     // last element
12152                     assert(i != val.m_value.object->cend());
12153                     assert(std::next(i) == val.m_value.object->cend());
12154                     o->write_character('\"');
12155                     dump_escaped(i->first, ensure_ascii);
12156                     o->write_characters("\":", 2);
12157                     dump(i->second, false, ensure_ascii, indent_step, current_indent);
12158 
12159                     o->write_character('}');
12160                 }
12161 
12162                 return;
12163             }
12164 
12165             case value_t::array:
12166             {
12167                 if (val.m_value.array->empty())
12168                 {
12169                     o->write_characters("[]", 2);
12170                     return;
12171                 }
12172 
12173                 if (pretty_print)
12174                 {
12175                     o->write_characters("[\n", 2);
12176 
12177                     // variable to hold indentation for recursive calls
12178                     const auto new_indent = current_indent + indent_step;
12179                     if (JSON_UNLIKELY(indent_string.size() < new_indent))
12180                     {
12181                         indent_string.resize(indent_string.size() * 2, ' ');
12182                     }
12183 
12184                     // first n-1 elements
12185                     for (auto i = val.m_value.array->cbegin();
12186                             i != val.m_value.array->cend() - 1; ++i)
12187                     {
12188                         o->write_characters(indent_string.c_str(), new_indent);
12189                         dump(*i, true, ensure_ascii, indent_step, new_indent);
12190                         o->write_characters(",\n", 2);
12191                     }
12192 
12193                     // last element
12194                     assert(not val.m_value.array->empty());
12195                     o->write_characters(indent_string.c_str(), new_indent);
12196                     dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
12197 
12198                     o->write_character('\n');
12199                     o->write_characters(indent_string.c_str(), current_indent);
12200                     o->write_character(']');
12201                 }
12202                 else
12203                 {
12204                     o->write_character('[');
12205 
12206                     // first n-1 elements
12207                     for (auto i = val.m_value.array->cbegin();
12208                             i != val.m_value.array->cend() - 1; ++i)
12209                     {
12210                         dump(*i, false, ensure_ascii, indent_step, current_indent);
12211                         o->write_character(',');
12212                     }
12213 
12214                     // last element
12215                     assert(not val.m_value.array->empty());
12216                     dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
12217 
12218                     o->write_character(']');
12219                 }
12220 
12221                 return;
12222             }
12223 
12224             case value_t::string:
12225             {
12226                 o->write_character('\"');
12227                 dump_escaped(*val.m_value.string, ensure_ascii);
12228                 o->write_character('\"');
12229                 return;
12230             }
12231 
12232             case value_t::boolean:
12233             {
12234                 if (val.m_value.boolean)
12235                 {
12236                     o->write_characters("true", 4);
12237                 }
12238                 else
12239                 {
12240                     o->write_characters("false", 5);
12241                 }
12242                 return;
12243             }
12244 
12245             case value_t::number_integer:
12246             {
12247                 dump_integer(val.m_value.number_integer);
12248                 return;
12249             }
12250 
12251             case value_t::number_unsigned:
12252             {
12253                 dump_integer(val.m_value.number_unsigned);
12254                 return;
12255             }
12256 
12257             case value_t::number_float:
12258             {
12259                 dump_float(val.m_value.number_float);
12260                 return;
12261             }
12262 
12263             case value_t::discarded:
12264             {
12265                 o->write_characters("<discarded>", 11);
12266                 return;
12267             }
12268 
12269             case value_t::null:
12270             {
12271                 o->write_characters("null", 4);
12272                 return;
12273             }
12274 
12275             default:            // LCOV_EXCL_LINE
12276                 assert(false);  // LCOV_EXCL_LINE
12277         }
12278     }
12279 
12280   private:
12281     /*!
12282     @brief dump escaped string
12283 
12284     Escape a string by replacing certain special characters by a sequence of an
12285     escape character (backslash) and another character and other control
12286     characters by a sequence of "\u" followed by a four-digit hex
12287     representation. The escaped string is written to output stream @a o.
12288 
12289     @param[in] s  the string to escape
12290     @param[in] ensure_ascii  whether to escape non-ASCII characters with
12291                              \uXXXX sequences
12292 
12293     @complexity Linear in the length of string @a s.
12294     */
dump_escaped(const string_t & s,const bool ensure_ascii)12295     void dump_escaped(const string_t& s, const bool ensure_ascii)
12296     {
12297         std::uint32_t codepoint;
12298         std::uint8_t state = UTF8_ACCEPT;
12299         std::size_t bytes = 0;  // number of bytes written to string_buffer
12300 
12301         // number of bytes written at the point of the last valid byte
12302         std::size_t bytes_after_last_accept = 0;
12303         std::size_t undumped_chars = 0;
12304 
12305         for (std::size_t i = 0; i < s.size(); ++i)
12306         {
12307             const auto byte = static_cast<uint8_t>(s[i]);
12308 
12309             switch (decode(state, codepoint, byte))
12310             {
12311                 case UTF8_ACCEPT:  // decode found a new code point
12312                 {
12313                     switch (codepoint)
12314                     {
12315                         case 0x08: // backspace
12316                         {
12317                             string_buffer[bytes++] = '\\';
12318                             string_buffer[bytes++] = 'b';
12319                             break;
12320                         }
12321 
12322                         case 0x09: // horizontal tab
12323                         {
12324                             string_buffer[bytes++] = '\\';
12325                             string_buffer[bytes++] = 't';
12326                             break;
12327                         }
12328 
12329                         case 0x0A: // newline
12330                         {
12331                             string_buffer[bytes++] = '\\';
12332                             string_buffer[bytes++] = 'n';
12333                             break;
12334                         }
12335 
12336                         case 0x0C: // formfeed
12337                         {
12338                             string_buffer[bytes++] = '\\';
12339                             string_buffer[bytes++] = 'f';
12340                             break;
12341                         }
12342 
12343                         case 0x0D: // carriage return
12344                         {
12345                             string_buffer[bytes++] = '\\';
12346                             string_buffer[bytes++] = 'r';
12347                             break;
12348                         }
12349 
12350                         case 0x22: // quotation mark
12351                         {
12352                             string_buffer[bytes++] = '\\';
12353                             string_buffer[bytes++] = '\"';
12354                             break;
12355                         }
12356 
12357                         case 0x5C: // reverse solidus
12358                         {
12359                             string_buffer[bytes++] = '\\';
12360                             string_buffer[bytes++] = '\\';
12361                             break;
12362                         }
12363 
12364                         default:
12365                         {
12366                             // escape control characters (0x00..0x1F) or, if
12367                             // ensure_ascii parameter is used, non-ASCII characters
12368                             if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
12369                             {
12370                                 if (codepoint <= 0xFFFF)
12371                                 {
12372                                     (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
12373                                                     static_cast<std::uint16_t>(codepoint));
12374                                     bytes += 6;
12375                                 }
12376                                 else
12377                                 {
12378                                     (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
12379                                                     static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
12380                                                     static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
12381                                     bytes += 12;
12382                                 }
12383                             }
12384                             else
12385                             {
12386                                 // copy byte to buffer (all previous bytes
12387                                 // been copied have in default case above)
12388                                 string_buffer[bytes++] = s[i];
12389                             }
12390                             break;
12391                         }
12392                     }
12393 
12394                     // write buffer and reset index; there must be 13 bytes
12395                     // left, as this is the maximal number of bytes to be
12396                     // written ("\uxxxx\uxxxx\0") for one code point
12397                     if (string_buffer.size() - bytes < 13)
12398                     {
12399                         o->write_characters(string_buffer.data(), bytes);
12400                         bytes = 0;
12401                     }
12402 
12403                     // remember the byte position of this accept
12404                     bytes_after_last_accept = bytes;
12405                     undumped_chars = 0;
12406                     break;
12407                 }
12408 
12409                 case UTF8_REJECT:  // decode found invalid UTF-8 byte
12410                 {
12411                     switch (error_handler)
12412                     {
12413                         case error_handler_t::strict:
12414                         {
12415                             std::string sn(3, '\0');
12416                             (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
12417                             JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
12418                         }
12419 
12420                         case error_handler_t::ignore:
12421                         case error_handler_t::replace:
12422                         {
12423                             // in case we saw this character the first time, we
12424                             // would like to read it again, because the byte
12425                             // may be OK for itself, but just not OK for the
12426                             // previous sequence
12427                             if (undumped_chars > 0)
12428                             {
12429                                 --i;
12430                             }
12431 
12432                             // reset length buffer to the last accepted index;
12433                             // thus removing/ignoring the invalid characters
12434                             bytes = bytes_after_last_accept;
12435 
12436                             if (error_handler == error_handler_t::replace)
12437                             {
12438                                 // add a replacement character
12439                                 if (ensure_ascii)
12440                                 {
12441                                     string_buffer[bytes++] = '\\';
12442                                     string_buffer[bytes++] = 'u';
12443                                     string_buffer[bytes++] = 'f';
12444                                     string_buffer[bytes++] = 'f';
12445                                     string_buffer[bytes++] = 'f';
12446                                     string_buffer[bytes++] = 'd';
12447                                 }
12448                                 else
12449                                 {
12450                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
12451                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
12452                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
12453                                 }
12454 
12455                                 // write buffer and reset index; there must be 13 bytes
12456                                 // left, as this is the maximal number of bytes to be
12457                                 // written ("\uxxxx\uxxxx\0") for one code point
12458                                 if (string_buffer.size() - bytes < 13)
12459                                 {
12460                                     o->write_characters(string_buffer.data(), bytes);
12461                                     bytes = 0;
12462                                 }
12463 
12464                                 bytes_after_last_accept = bytes;
12465                             }
12466 
12467                             undumped_chars = 0;
12468 
12469                             // continue processing the string
12470                             state = UTF8_ACCEPT;
12471                             break;
12472                         }
12473 
12474                         default:            // LCOV_EXCL_LINE
12475                             assert(false);  // LCOV_EXCL_LINE
12476                     }
12477                     break;
12478                 }
12479 
12480                 default:  // decode found yet incomplete multi-byte code point
12481                 {
12482                     if (not ensure_ascii)
12483                     {
12484                         // code point will not be escaped - copy byte to buffer
12485                         string_buffer[bytes++] = s[i];
12486                     }
12487                     ++undumped_chars;
12488                     break;
12489                 }
12490             }
12491         }
12492 
12493         // we finished processing the string
12494         if (JSON_LIKELY(state == UTF8_ACCEPT))
12495         {
12496             // write buffer
12497             if (bytes > 0)
12498             {
12499                 o->write_characters(string_buffer.data(), bytes);
12500             }
12501         }
12502         else
12503         {
12504             // we finish reading, but do not accept: string was incomplete
12505             switch (error_handler)
12506             {
12507                 case error_handler_t::strict:
12508                 {
12509                     std::string sn(3, '\0');
12510                     (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
12511                     JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
12512                 }
12513 
12514                 case error_handler_t::ignore:
12515                 {
12516                     // write all accepted bytes
12517                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
12518                     break;
12519                 }
12520 
12521                 case error_handler_t::replace:
12522                 {
12523                     // write all accepted bytes
12524                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
12525                     // add a replacement character
12526                     if (ensure_ascii)
12527                     {
12528                         o->write_characters("\\ufffd", 6);
12529                     }
12530                     else
12531                     {
12532                         o->write_characters("\xEF\xBF\xBD", 3);
12533                     }
12534                     break;
12535                 }
12536 
12537                 default:            // LCOV_EXCL_LINE
12538                     assert(false);  // LCOV_EXCL_LINE
12539             }
12540         }
12541     }
12542 
12543     /*!
12544     @brief count digits
12545 
12546     Count the number of decimal (base 10) digits for an input unsigned integer.
12547 
12548     @param[in] x  unsigned integer number to count its digits
12549     @return    number of decimal digits
12550     */
count_digits(number_unsigned_t x)12551     inline unsigned int count_digits(number_unsigned_t x) noexcept
12552     {
12553         unsigned int n_digits = 1;
12554         for (;;)
12555         {
12556             if (x < 10)
12557             {
12558                 return n_digits;
12559             }
12560             if (x < 100)
12561             {
12562                 return n_digits + 1;
12563             }
12564             if (x < 1000)
12565             {
12566                 return n_digits + 2;
12567             }
12568             if (x < 10000)
12569             {
12570                 return n_digits + 3;
12571             }
12572             x = x / 10000u;
12573             n_digits += 4;
12574         }
12575     }
12576 
12577     /*!
12578     @brief dump an integer
12579 
12580     Dump a given integer to output stream @a o. Works internally with
12581     @a number_buffer.
12582 
12583     @param[in] x  integer number (signed or unsigned) to dump
12584     @tparam NumberType either @a number_integer_t or @a number_unsigned_t
12585     */
12586     template<typename NumberType, detail::enable_if_t<
12587                  std::is_same<NumberType, number_unsigned_t>::value or
12588                  std::is_same<NumberType, number_integer_t>::value,
12589                  int> = 0>
dump_integer(NumberType x)12590     void dump_integer(NumberType x)
12591     {
12592         static constexpr std::array<std::array<char, 2>, 100> digits_to_99
12593         {
12594             {
12595                 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
12596                 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
12597                 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
12598                 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
12599                 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
12600                 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
12601                 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
12602                 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
12603                 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
12604                 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
12605             }
12606         };
12607 
12608         // special case for "0"
12609         if (x == 0)
12610         {
12611             o->write_character('0');
12612             return;
12613         }
12614 
12615         // use a pointer to fill the buffer
12616         auto buffer_ptr = number_buffer.begin();
12617 
12618         const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
12619         number_unsigned_t abs_value;
12620 
12621         unsigned int n_chars;
12622 
12623         if (is_negative)
12624         {
12625             *buffer_ptr = '-';
12626             abs_value = static_cast<number_unsigned_t>(std::abs(static_cast<std::intmax_t>(x)));
12627 
12628             // account one more byte for the minus sign
12629             n_chars = 1 + count_digits(abs_value);
12630         }
12631         else
12632         {
12633             abs_value = static_cast<number_unsigned_t>(x);
12634             n_chars = count_digits(abs_value);
12635         }
12636 
12637         // spare 1 byte for '\0'
12638         assert(n_chars < number_buffer.size() - 1);
12639 
12640         // jump to the end to generate the string from backward
12641         // so we later avoid reversing the result
12642         buffer_ptr += n_chars;
12643 
12644         // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
12645         // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
12646         while (abs_value >= 100)
12647         {
12648             const auto digits_index = static_cast<unsigned>((abs_value % 100));
12649             abs_value /= 100;
12650             *(--buffer_ptr) = digits_to_99[digits_index][1];
12651             *(--buffer_ptr) = digits_to_99[digits_index][0];
12652         }
12653 
12654         if (abs_value >= 10)
12655         {
12656             const auto digits_index = static_cast<unsigned>(abs_value);
12657             *(--buffer_ptr) = digits_to_99[digits_index][1];
12658             *(--buffer_ptr) = digits_to_99[digits_index][0];
12659         }
12660         else
12661         {
12662             *(--buffer_ptr) = static_cast<char>('0' + abs_value);
12663         }
12664 
12665         o->write_characters(number_buffer.data(), n_chars);
12666     }
12667 
12668     /*!
12669     @brief dump a floating-point number
12670 
12671     Dump a given floating-point number to output stream @a o. Works internally
12672     with @a number_buffer.
12673 
12674     @param[in] x  floating-point number to dump
12675     */
dump_float(number_float_t x)12676     void dump_float(number_float_t x)
12677     {
12678         // NaN / inf
12679         if (not std::isfinite(x))
12680         {
12681             o->write_characters("null", 4);
12682             return;
12683         }
12684 
12685         // If number_float_t is an IEEE-754 single or double precision number,
12686         // use the Grisu2 algorithm to produce short numbers which are
12687         // guaranteed to round-trip, using strtof and strtod, resp.
12688         //
12689         // NB: The test below works if <long double> == <double>.
12690         static constexpr bool is_ieee_single_or_double
12691             = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
12692               (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
12693 
12694         dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
12695     }
12696 
dump_float(number_float_t x,std::true_type)12697     void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
12698     {
12699         char* begin = number_buffer.data();
12700         char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
12701 
12702         o->write_characters(begin, static_cast<size_t>(end - begin));
12703     }
12704 
dump_float(number_float_t x,std::false_type)12705     void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
12706     {
12707         // get number of digits for a float -> text -> float round-trip
12708         static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
12709 
12710         // the actual conversion
12711         std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
12712 
12713         // negative value indicates an error
12714         assert(len > 0);
12715         // check if buffer was large enough
12716         assert(static_cast<std::size_t>(len) < number_buffer.size());
12717 
12718         // erase thousands separator
12719         if (thousands_sep != '\0')
12720         {
12721             const auto end = std::remove(number_buffer.begin(),
12722                                          number_buffer.begin() + len, thousands_sep);
12723             std::fill(end, number_buffer.end(), '\0');
12724             assert((end - number_buffer.begin()) <= len);
12725             len = (end - number_buffer.begin());
12726         }
12727 
12728         // convert decimal point to '.'
12729         if (decimal_point != '\0' and decimal_point != '.')
12730         {
12731             const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
12732             if (dec_pos != number_buffer.end())
12733             {
12734                 *dec_pos = '.';
12735             }
12736         }
12737 
12738         o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
12739 
12740         // determine if need to append ".0"
12741         const bool value_is_int_like =
12742             std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
12743                          [](char c)
12744         {
12745             return c == '.' or c == 'e';
12746         });
12747 
12748         if (value_is_int_like)
12749         {
12750             o->write_characters(".0", 2);
12751         }
12752     }
12753 
12754     /*!
12755     @brief check whether a string is UTF-8 encoded
12756 
12757     The function checks each byte of a string whether it is UTF-8 encoded. The
12758     result of the check is stored in the @a state parameter. The function must
12759     be called initially with state 0 (accept). State 1 means the string must
12760     be rejected, because the current byte is not allowed. If the string is
12761     completely processed, but the state is non-zero, the string ended
12762     prematurely; that is, the last byte indicated more bytes should have
12763     followed.
12764 
12765     @param[in,out] state  the state of the decoding
12766     @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
12767     @param[in] byte       next byte to decode
12768     @return               new state
12769 
12770     @note The function has been edited: a std::array is used.
12771 
12772     @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
12773     @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
12774     */
decode(std::uint8_t & state,std::uint32_t & codep,const std::uint8_t byte)12775     static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
12776     {
12777         static const std::array<std::uint8_t, 400> utf8d =
12778         {
12779             {
12780                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
12781                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
12782                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
12783                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
12784                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
12785                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
12786                 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
12787                 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
12788                 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
12789                 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
12790                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
12791                 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
12792                 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
12793                 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
12794             }
12795         };
12796 
12797         const std::uint8_t type = utf8d[byte];
12798 
12799         codep = (state != UTF8_ACCEPT)
12800                 ? (byte & 0x3fu) | (codep << 6u)
12801                 : (0xFFu >> type) & (byte);
12802 
12803         state = utf8d[256u + state * 16u + type];
12804         return state;
12805     }
12806 
12807   private:
12808     /// the output of the serializer
12809     output_adapter_t<char> o = nullptr;
12810 
12811     /// a (hopefully) large enough character buffer
12812     std::array<char, 64> number_buffer{{}};
12813 
12814     /// the locale
12815     const std::lconv* loc = nullptr;
12816     /// the locale's thousand separator character
12817     const char thousands_sep = '\0';
12818     /// the locale's decimal point character
12819     const char decimal_point = '\0';
12820 
12821     /// string buffer
12822     std::array<char, 512> string_buffer{{}};
12823 
12824     /// the indentation character
12825     const char indent_char;
12826     /// the indentation string
12827     string_t indent_string;
12828 
12829     /// error_handler how to react on decoding errors
12830     const error_handler_t error_handler;
12831 };
12832 }  // namespace detail
12833 }  // namespace nlohmann
12834 
12835 // #include <nlohmann/detail/value_t.hpp>
12836 
12837 // #include <nlohmann/json_fwd.hpp>
12838 
12839 
12840 /*!
12841 @brief namespace for Niels Lohmann
12842 @see https://github.com/nlohmann
12843 @since version 1.0.0
12844 */
12845 namespace nlohmann
12846 {
12847 
12848 /*!
12849 @brief a class to store JSON values
12850 
12851 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
12852 in @ref object_t)
12853 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
12854 in @ref array_t)
12855 @tparam StringType type for JSON strings and object keys (`std::string` by
12856 default; will be used in @ref string_t)
12857 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
12858 in @ref boolean_t)
12859 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
12860 default; will be used in @ref number_integer_t)
12861 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
12862 `uint64_t` by default; will be used in @ref number_unsigned_t)
12863 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
12864 default; will be used in @ref number_float_t)
12865 @tparam AllocatorType type of the allocator to use (`std::allocator` by
12866 default)
12867 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
12868 and `from_json()` (@ref adl_serializer by default)
12869 
12870 @requirement The class satisfies the following concept requirements:
12871 - Basic
12872  - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
12873    JSON values can be default constructed. The result will be a JSON null
12874    value.
12875  - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
12876    A JSON value can be constructed from an rvalue argument.
12877  - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
12878    A JSON value can be copy-constructed from an lvalue expression.
12879  - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
12880    A JSON value van be assigned from an rvalue argument.
12881  - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
12882    A JSON value can be copy-assigned from an lvalue expression.
12883  - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
12884    JSON values can be destructed.
12885 - Layout
12886  - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
12887    JSON values have
12888    [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
12889    All non-static data members are private and standard layout types, the
12890    class has no virtual functions or (virtual) base classes.
12891 - Library-wide
12892  - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
12893    JSON values can be compared with `==`, see @ref
12894    operator==(const_reference,const_reference).
12895  - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
12896    JSON values can be compared with `<`, see @ref
12897    operator<(const_reference,const_reference).
12898  - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
12899    Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
12900    other compatible types, using unqualified function call @ref swap().
12901  - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
12902    JSON values can be compared against `std::nullptr_t` objects which are used
12903    to model the `null` value.
12904 - Container
12905  - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
12906    JSON values can be used like STL containers and provide iterator access.
12907  - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
12908    JSON values can be used like STL containers and provide reverse iterator
12909    access.
12910 
12911 @invariant The member variables @a m_value and @a m_type have the following
12912 relationship:
12913 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
12914 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
12915 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
12916 The invariants are checked by member function assert_invariant().
12917 
12918 @internal
12919 @note ObjectType trick from http://stackoverflow.com/a/9860911
12920 @endinternal
12921 
12922 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
12923 Format](http://rfc7159.net/rfc7159)
12924 
12925 @since version 1.0.0
12926 
12927 @nosubgrouping
12928 */
12929 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12930 class basic_json
12931 {
12932   private:
12933     template<detail::value_t> friend struct detail::external_constructor;
12934     friend ::nlohmann::json_pointer<basic_json>;
12935     friend ::nlohmann::detail::parser<basic_json>;
12936     friend ::nlohmann::detail::serializer<basic_json>;
12937     template<typename BasicJsonType>
12938     friend class ::nlohmann::detail::iter_impl;
12939     template<typename BasicJsonType, typename CharType>
12940     friend class ::nlohmann::detail::binary_writer;
12941     template<typename BasicJsonType, typename SAX>
12942     friend class ::nlohmann::detail::binary_reader;
12943     template<typename BasicJsonType>
12944     friend class ::nlohmann::detail::json_sax_dom_parser;
12945     template<typename BasicJsonType>
12946     friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12947 
12948     /// workaround type for MSVC
12949     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
12950 
12951     // convenience aliases for types residing in namespace detail;
12952     using lexer = ::nlohmann::detail::lexer<basic_json>;
12953     using parser = ::nlohmann::detail::parser<basic_json>;
12954 
12955     using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
12956     template<typename BasicJsonType>
12957     using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
12958     template<typename BasicJsonType>
12959     using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
12960     template<typename Iterator>
12961     using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
12962     template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
12963 
12964     template<typename CharType>
12965     using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
12966 
12967     using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
12968     template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
12969 
12970     using serializer = ::nlohmann::detail::serializer<basic_json>;
12971 
12972   public:
12973     using value_t = detail::value_t;
12974     /// JSON Pointer, see @ref nlohmann::json_pointer
12975     using json_pointer = ::nlohmann::json_pointer<basic_json>;
12976     template<typename T, typename SFINAE>
12977     using json_serializer = JSONSerializer<T, SFINAE>;
12978     /// how to treat decoding errors
12979     using error_handler_t = detail::error_handler_t;
12980     /// helper type for initializer lists of basic_json values
12981     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
12982 
12983     using input_format_t = detail::input_format_t;
12984     /// SAX interface type, see @ref nlohmann::json_sax
12985     using json_sax_t = json_sax<basic_json>;
12986 
12987     ////////////////
12988     // exceptions //
12989     ////////////////
12990 
12991     /// @name exceptions
12992     /// Classes to implement user-defined exceptions.
12993     /// @{
12994 
12995     /// @copydoc detail::exception
12996     using exception = detail::exception;
12997     /// @copydoc detail::parse_error
12998     using parse_error = detail::parse_error;
12999     /// @copydoc detail::invalid_iterator
13000     using invalid_iterator = detail::invalid_iterator;
13001     /// @copydoc detail::type_error
13002     using type_error = detail::type_error;
13003     /// @copydoc detail::out_of_range
13004     using out_of_range = detail::out_of_range;
13005     /// @copydoc detail::other_error
13006     using other_error = detail::other_error;
13007 
13008     /// @}
13009 
13010 
13011     /////////////////////
13012     // container types //
13013     /////////////////////
13014 
13015     /// @name container types
13016     /// The canonic container types to use @ref basic_json like any other STL
13017     /// container.
13018     /// @{
13019 
13020     /// the type of elements in a basic_json container
13021     using value_type = basic_json;
13022 
13023     /// the type of an element reference
13024     using reference = value_type&;
13025     /// the type of an element const reference
13026     using const_reference = const value_type&;
13027 
13028     /// a type to represent differences between iterators
13029     using difference_type = std::ptrdiff_t;
13030     /// a type to represent container sizes
13031     using size_type = std::size_t;
13032 
13033     /// the allocator type
13034     using allocator_type = AllocatorType<basic_json>;
13035 
13036     /// the type of an element pointer
13037     using pointer = typename std::allocator_traits<allocator_type>::pointer;
13038     /// the type of an element const pointer
13039     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
13040 
13041     /// an iterator for a basic_json container
13042     using iterator = iter_impl<basic_json>;
13043     /// a const iterator for a basic_json container
13044     using const_iterator = iter_impl<const basic_json>;
13045     /// a reverse iterator for a basic_json container
13046     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
13047     /// a const reverse iterator for a basic_json container
13048     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
13049 
13050     /// @}
13051 
13052 
13053     /*!
13054     @brief returns the allocator associated with the container
13055     */
get_allocator()13056     static allocator_type get_allocator()
13057     {
13058         return allocator_type();
13059     }
13060 
13061     /*!
13062     @brief returns version information on the library
13063 
13064     This function returns a JSON object with information about the library,
13065     including the version number and information on the platform and compiler.
13066 
13067     @return JSON object holding version information
13068     key         | description
13069     ----------- | ---------------
13070     `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).
13071     `copyright` | The copyright line for the library as string.
13072     `name`      | The name of the library as string.
13073     `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
13074     `url`       | The URL of the project as string.
13075     `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).
13076 
13077     @liveexample{The following code shows an example output of the `meta()`
13078     function.,meta}
13079 
13080     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13081     changes to any JSON value.
13082 
13083     @complexity Constant.
13084 
13085     @since 2.1.0
13086     */
13087     JSON_NODISCARD
meta()13088     static basic_json meta()
13089     {
13090         basic_json result;
13091 
13092         result["copyright"] = "(C) 2013-2017 Niels Lohmann";
13093         result["name"] = "JSON for Modern C++";
13094         result["url"] = "https://github.com/nlohmann/json";
13095         result["version"]["string"] =
13096             std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
13097             std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
13098             std::to_string(NLOHMANN_JSON_VERSION_PATCH);
13099         result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
13100         result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
13101         result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
13102 
13103 #ifdef _WIN32
13104         result["platform"] = "win32";
13105 #elif defined __linux__
13106         result["platform"] = "linux";
13107 #elif defined __APPLE__
13108         result["platform"] = "apple";
13109 #elif defined __unix__
13110         result["platform"] = "unix";
13111 #else
13112         result["platform"] = "unknown";
13113 #endif
13114 
13115 #if defined(__ICC) || defined(__INTEL_COMPILER)
13116         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
13117 #elif defined(__clang__)
13118         result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
13119 #elif defined(__GNUC__) || defined(__GNUG__)
13120         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
13121 #elif defined(__HP_cc) || defined(__HP_aCC)
13122         result["compiler"] = "hp"
13123 #elif defined(__IBMCPP__)
13124         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
13125 #elif defined(_MSC_VER)
13126         result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
13127 #elif defined(__PGI)
13128         result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
13129 #elif defined(__SUNPRO_CC)
13130         result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
13131 #else
13132         result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
13133 #endif
13134 
13135 #ifdef __cplusplus
13136         result["compiler"]["c++"] = std::to_string(__cplusplus);
13137 #else
13138         result["compiler"]["c++"] = "unknown";
13139 #endif
13140         return result;
13141     }
13142 
13143 
13144     ///////////////////////////
13145     // JSON value data types //
13146     ///////////////////////////
13147 
13148     /// @name JSON value data types
13149     /// The data types to store a JSON value. These types are derived from
13150     /// the template arguments passed to class @ref basic_json.
13151     /// @{
13152 
13153 #if defined(JSON_HAS_CPP_14)
13154     // Use transparent comparator if possible, combined with perfect forwarding
13155     // on find() and count() calls prevents unnecessary string construction.
13156     using object_comparator_t = std::less<>;
13157 #else
13158     using object_comparator_t = std::less<StringType>;
13159 #endif
13160 
13161     /*!
13162     @brief a type for an object
13163 
13164     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
13165     > An object is an unordered collection of zero or more name/value pairs,
13166     > where a name is a string and a value is a string, number, boolean, null,
13167     > object, or array.
13168 
13169     To store objects in C++, a type is defined by the template parameters
13170     described below.
13171 
13172     @tparam ObjectType  the container to store objects (e.g., `std::map` or
13173     `std::unordered_map`)
13174     @tparam StringType the type of the keys or names (e.g., `std::string`).
13175     The comparison function `std::less<StringType>` is used to order elements
13176     inside the container.
13177     @tparam AllocatorType the allocator to use for objects (e.g.,
13178     `std::allocator`)
13179 
13180     #### Default type
13181 
13182     With the default values for @a ObjectType (`std::map`), @a StringType
13183     (`std::string`), and @a AllocatorType (`std::allocator`), the default
13184     value for @a object_t is:
13185 
13186     @code {.cpp}
13187     std::map<
13188       std::string, // key_type
13189       basic_json, // value_type
13190       std::less<std::string>, // key_compare
13191       std::allocator<std::pair<const std::string, basic_json>> // allocator_type
13192     >
13193     @endcode
13194 
13195     #### Behavior
13196 
13197     The choice of @a object_t influences the behavior of the JSON class. With
13198     the default type, objects have the following behavior:
13199 
13200     - When all names are unique, objects will be interoperable in the sense
13201       that all software implementations receiving that object will agree on
13202       the name-value mappings.
13203     - When the names within an object are not unique, it is unspecified which
13204       one of the values for a given key will be chosen. For instance,
13205       `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
13206       `{"key": 2}`.
13207     - Internally, name/value pairs are stored in lexicographical order of the
13208       names. Objects will also be serialized (see @ref dump) in this order.
13209       For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
13210       and serialized as `{"a": 2, "b": 1}`.
13211     - When comparing objects, the order of the name/value pairs is irrelevant.
13212       This makes objects interoperable in the sense that they will not be
13213       affected by these differences. For instance, `{"b": 1, "a": 2}` and
13214       `{"a": 2, "b": 1}` will be treated as equal.
13215 
13216     #### Limits
13217 
13218     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13219     > An implementation may set limits on the maximum depth of nesting.
13220 
13221     In this class, the object's limit of nesting is not explicitly constrained.
13222     However, a maximum depth of nesting may be introduced by the compiler or
13223     runtime environment. A theoretical limit can be queried by calling the
13224     @ref max_size function of a JSON object.
13225 
13226     #### Storage
13227 
13228     Objects are stored as pointers in a @ref basic_json type. That is, for any
13229     access to object values, a pointer of type `object_t*` must be
13230     dereferenced.
13231 
13232     @sa @ref array_t -- type for an array value
13233 
13234     @since version 1.0.0
13235 
13236     @note The order name/value pairs are added to the object is *not*
13237     preserved by the library. Therefore, iterating an object may return
13238     name/value pairs in a different order than they were originally stored. In
13239     fact, keys will be traversed in alphabetical order as `std::map` with
13240     `std::less` is used by default. Please note this behavior conforms to [RFC
13241     7159](http://rfc7159.net/rfc7159), because any order implements the
13242     specified "unordered" nature of JSON objects.
13243     */
13244     using object_t = ObjectType<StringType,
13245           basic_json,
13246           object_comparator_t,
13247           AllocatorType<std::pair<const StringType,
13248           basic_json>>>;
13249 
13250     /*!
13251     @brief a type for an array
13252 
13253     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
13254     > An array is an ordered sequence of zero or more values.
13255 
13256     To store objects in C++, a type is defined by the template parameters
13257     explained below.
13258 
13259     @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
13260     `std::list`)
13261     @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
13262 
13263     #### Default type
13264 
13265     With the default values for @a ArrayType (`std::vector`) and @a
13266     AllocatorType (`std::allocator`), the default value for @a array_t is:
13267 
13268     @code {.cpp}
13269     std::vector<
13270       basic_json, // value_type
13271       std::allocator<basic_json> // allocator_type
13272     >
13273     @endcode
13274 
13275     #### Limits
13276 
13277     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13278     > An implementation may set limits on the maximum depth of nesting.
13279 
13280     In this class, the array's limit of nesting is not explicitly constrained.
13281     However, a maximum depth of nesting may be introduced by the compiler or
13282     runtime environment. A theoretical limit can be queried by calling the
13283     @ref max_size function of a JSON array.
13284 
13285     #### Storage
13286 
13287     Arrays are stored as pointers in a @ref basic_json type. That is, for any
13288     access to array values, a pointer of type `array_t*` must be dereferenced.
13289 
13290     @sa @ref object_t -- type for an object value
13291 
13292     @since version 1.0.0
13293     */
13294     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
13295 
13296     /*!
13297     @brief a type for a string
13298 
13299     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
13300     > A string is a sequence of zero or more Unicode characters.
13301 
13302     To store objects in C++, a type is defined by the template parameter
13303     described below. Unicode values are split by the JSON class into
13304     byte-sized characters during deserialization.
13305 
13306     @tparam StringType  the container to store strings (e.g., `std::string`).
13307     Note this container is used for keys/names in objects, see @ref object_t.
13308 
13309     #### Default type
13310 
13311     With the default values for @a StringType (`std::string`), the default
13312     value for @a string_t is:
13313 
13314     @code {.cpp}
13315     std::string
13316     @endcode
13317 
13318     #### Encoding
13319 
13320     Strings are stored in UTF-8 encoding. Therefore, functions like
13321     `std::string::size()` or `std::string::length()` return the number of
13322     bytes in the string rather than the number of characters or glyphs.
13323 
13324     #### String comparison
13325 
13326     [RFC 7159](http://rfc7159.net/rfc7159) states:
13327     > Software implementations are typically required to test names of object
13328     > members for equality. Implementations that transform the textual
13329     > representation into sequences of Unicode code units and then perform the
13330     > comparison numerically, code unit by code unit, are interoperable in the
13331     > sense that implementations will agree in all cases on equality or
13332     > inequality of two strings. For example, implementations that compare
13333     > strings with escaped characters unconverted may incorrectly find that
13334     > `"a\\b"` and `"a\u005Cb"` are not equal.
13335 
13336     This implementation is interoperable as it does compare strings code unit
13337     by code unit.
13338 
13339     #### Storage
13340 
13341     String values are stored as pointers in a @ref basic_json type. That is,
13342     for any access to string values, a pointer of type `string_t*` must be
13343     dereferenced.
13344 
13345     @since version 1.0.0
13346     */
13347     using string_t = StringType;
13348 
13349     /*!
13350     @brief a type for a boolean
13351 
13352     [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
13353     type which differentiates the two literals `true` and `false`.
13354 
13355     To store objects in C++, a type is defined by the template parameter @a
13356     BooleanType which chooses the type to use.
13357 
13358     #### Default type
13359 
13360     With the default values for @a BooleanType (`bool`), the default value for
13361     @a boolean_t is:
13362 
13363     @code {.cpp}
13364     bool
13365     @endcode
13366 
13367     #### Storage
13368 
13369     Boolean values are stored directly inside a @ref basic_json type.
13370 
13371     @since version 1.0.0
13372     */
13373     using boolean_t = BooleanType;
13374 
13375     /*!
13376     @brief a type for a number (integer)
13377 
13378     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13379     > The representation of numbers is similar to that used in most
13380     > programming languages. A number is represented in base 10 using decimal
13381     > digits. It contains an integer component that may be prefixed with an
13382     > optional minus sign, which may be followed by a fraction part and/or an
13383     > exponent part. Leading zeros are not allowed. (...) Numeric values that
13384     > cannot be represented in the grammar below (such as Infinity and NaN)
13385     > are not permitted.
13386 
13387     This description includes both integer and floating-point numbers.
13388     However, C++ allows more precise storage if it is known whether the number
13389     is a signed integer, an unsigned integer or a floating-point number.
13390     Therefore, three different types, @ref number_integer_t, @ref
13391     number_unsigned_t and @ref number_float_t are used.
13392 
13393     To store integer numbers in C++, a type is defined by the template
13394     parameter @a NumberIntegerType which chooses the type to use.
13395 
13396     #### Default type
13397 
13398     With the default values for @a NumberIntegerType (`int64_t`), the default
13399     value for @a number_integer_t is:
13400 
13401     @code {.cpp}
13402     int64_t
13403     @endcode
13404 
13405     #### Default behavior
13406 
13407     - The restrictions about leading zeros is not enforced in C++. Instead,
13408       leading zeros in integer literals lead to an interpretation as octal
13409       number. Internally, the value will be stored as decimal number. For
13410       instance, the C++ integer literal `010` will be serialized to `8`.
13411       During deserialization, leading zeros yield an error.
13412     - Not-a-number (NaN) values will be serialized to `null`.
13413 
13414     #### Limits
13415 
13416     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13417     > An implementation may set limits on the range and precision of numbers.
13418 
13419     When the default type is used, the maximal integer number that can be
13420     stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
13421     that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
13422     that are out of range will yield over/underflow when used in a
13423     constructor. During deserialization, too large or small integer numbers
13424     will be automatically be stored as @ref number_unsigned_t or @ref
13425     number_float_t.
13426 
13427     [RFC 7159](http://rfc7159.net/rfc7159) further states:
13428     > Note that when such software is used, numbers that are integers and are
13429     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
13430     > that implementations will agree exactly on their numeric values.
13431 
13432     As this range is a subrange of the exactly supported range [INT64_MIN,
13433     INT64_MAX], this class's integer type is interoperable.
13434 
13435     #### Storage
13436 
13437     Integer number values are stored directly inside a @ref basic_json type.
13438 
13439     @sa @ref number_float_t -- type for number values (floating-point)
13440 
13441     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
13442 
13443     @since version 1.0.0
13444     */
13445     using number_integer_t = NumberIntegerType;
13446 
13447     /*!
13448     @brief a type for a number (unsigned)
13449 
13450     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13451     > The representation of numbers is similar to that used in most
13452     > programming languages. A number is represented in base 10 using decimal
13453     > digits. It contains an integer component that may be prefixed with an
13454     > optional minus sign, which may be followed by a fraction part and/or an
13455     > exponent part. Leading zeros are not allowed. (...) Numeric values that
13456     > cannot be represented in the grammar below (such as Infinity and NaN)
13457     > are not permitted.
13458 
13459     This description includes both integer and floating-point numbers.
13460     However, C++ allows more precise storage if it is known whether the number
13461     is a signed integer, an unsigned integer or a floating-point number.
13462     Therefore, three different types, @ref number_integer_t, @ref
13463     number_unsigned_t and @ref number_float_t are used.
13464 
13465     To store unsigned integer numbers in C++, a type is defined by the
13466     template parameter @a NumberUnsignedType which chooses the type to use.
13467 
13468     #### Default type
13469 
13470     With the default values for @a NumberUnsignedType (`uint64_t`), the
13471     default value for @a number_unsigned_t is:
13472 
13473     @code {.cpp}
13474     uint64_t
13475     @endcode
13476 
13477     #### Default behavior
13478 
13479     - The restrictions about leading zeros is not enforced in C++. Instead,
13480       leading zeros in integer literals lead to an interpretation as octal
13481       number. Internally, the value will be stored as decimal number. For
13482       instance, the C++ integer literal `010` will be serialized to `8`.
13483       During deserialization, leading zeros yield an error.
13484     - Not-a-number (NaN) values will be serialized to `null`.
13485 
13486     #### Limits
13487 
13488     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13489     > An implementation may set limits on the range and precision of numbers.
13490 
13491     When the default type is used, the maximal integer number that can be
13492     stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
13493     number that can be stored is `0`. Integer numbers that are out of range
13494     will yield over/underflow when used in a constructor. During
13495     deserialization, too large or small integer numbers will be automatically
13496     be stored as @ref number_integer_t or @ref number_float_t.
13497 
13498     [RFC 7159](http://rfc7159.net/rfc7159) further states:
13499     > Note that when such software is used, numbers that are integers and are
13500     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
13501     > that implementations will agree exactly on their numeric values.
13502 
13503     As this range is a subrange (when considered in conjunction with the
13504     number_integer_t type) of the exactly supported range [0, UINT64_MAX],
13505     this class's integer type is interoperable.
13506 
13507     #### Storage
13508 
13509     Integer number values are stored directly inside a @ref basic_json type.
13510 
13511     @sa @ref number_float_t -- type for number values (floating-point)
13512     @sa @ref number_integer_t -- type for number values (integer)
13513 
13514     @since version 2.0.0
13515     */
13516     using number_unsigned_t = NumberUnsignedType;
13517 
13518     /*!
13519     @brief a type for a number (floating-point)
13520 
13521     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13522     > The representation of numbers is similar to that used in most
13523     > programming languages. A number is represented in base 10 using decimal
13524     > digits. It contains an integer component that may be prefixed with an
13525     > optional minus sign, which may be followed by a fraction part and/or an
13526     > exponent part. Leading zeros are not allowed. (...) Numeric values that
13527     > cannot be represented in the grammar below (such as Infinity and NaN)
13528     > are not permitted.
13529 
13530     This description includes both integer and floating-point numbers.
13531     However, C++ allows more precise storage if it is known whether the number
13532     is a signed integer, an unsigned integer or a floating-point number.
13533     Therefore, three different types, @ref number_integer_t, @ref
13534     number_unsigned_t and @ref number_float_t are used.
13535 
13536     To store floating-point numbers in C++, a type is defined by the template
13537     parameter @a NumberFloatType which chooses the type to use.
13538 
13539     #### Default type
13540 
13541     With the default values for @a NumberFloatType (`double`), the default
13542     value for @a number_float_t is:
13543 
13544     @code {.cpp}
13545     double
13546     @endcode
13547 
13548     #### Default behavior
13549 
13550     - The restrictions about leading zeros is not enforced in C++. Instead,
13551       leading zeros in floating-point literals will be ignored. Internally,
13552       the value will be stored as decimal number. For instance, the C++
13553       floating-point literal `01.2` will be serialized to `1.2`. During
13554       deserialization, leading zeros yield an error.
13555     - Not-a-number (NaN) values will be serialized to `null`.
13556 
13557     #### Limits
13558 
13559     [RFC 7159](http://rfc7159.net/rfc7159) states:
13560     > This specification allows implementations to set limits on the range and
13561     > precision of numbers accepted. Since software that implements IEEE
13562     > 754-2008 binary64 (double precision) numbers is generally available and
13563     > widely used, good interoperability can be achieved by implementations
13564     > that expect no more precision or range than these provide, in the sense
13565     > that implementations will approximate JSON numbers within the expected
13566     > precision.
13567 
13568     This implementation does exactly follow this approach, as it uses double
13569     precision floating-point numbers. Note values smaller than
13570     `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
13571     will be stored as NaN internally and be serialized to `null`.
13572 
13573     #### Storage
13574 
13575     Floating-point number values are stored directly inside a @ref basic_json
13576     type.
13577 
13578     @sa @ref number_integer_t -- type for number values (integer)
13579 
13580     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
13581 
13582     @since version 1.0.0
13583     */
13584     using number_float_t = NumberFloatType;
13585 
13586     /// @}
13587 
13588   private:
13589 
13590     /// helper for exception-safe object creation
13591     template<typename T, typename... Args>
create(Args &&...args)13592     static T* create(Args&& ... args)
13593     {
13594         AllocatorType<T> alloc;
13595         using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13596 
13597         auto deleter = [&](T * object)
13598         {
13599             AllocatorTraits::deallocate(alloc, object, 1);
13600         };
13601         std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
13602         AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
13603         assert(object != nullptr);
13604         return object.release();
13605     }
13606 
13607     ////////////////////////
13608     // JSON value storage //
13609     ////////////////////////
13610 
13611     /*!
13612     @brief a JSON value
13613 
13614     The actual storage for a JSON value of the @ref basic_json class. This
13615     union combines the different storage types for the JSON value types
13616     defined in @ref value_t.
13617 
13618     JSON type | value_t type    | used type
13619     --------- | --------------- | ------------------------
13620     object    | object          | pointer to @ref object_t
13621     array     | array           | pointer to @ref array_t
13622     string    | string          | pointer to @ref string_t
13623     boolean   | boolean         | @ref boolean_t
13624     number    | number_integer  | @ref number_integer_t
13625     number    | number_unsigned | @ref number_unsigned_t
13626     number    | number_float    | @ref number_float_t
13627     null      | null            | *no value is stored*
13628 
13629     @note Variable-length types (objects, arrays, and strings) are stored as
13630     pointers. The size of the union should not exceed 64 bits if the default
13631     value types are used.
13632 
13633     @since version 1.0.0
13634     */
13635     union json_value
13636     {
13637         /// object (stored with pointer to save storage)
13638         object_t* object;
13639         /// array (stored with pointer to save storage)
13640         array_t* array;
13641         /// string (stored with pointer to save storage)
13642         string_t* string;
13643         /// boolean
13644         boolean_t boolean;
13645         /// number (integer)
13646         number_integer_t number_integer;
13647         /// number (unsigned integer)
13648         number_unsigned_t number_unsigned;
13649         /// number (floating-point)
13650         number_float_t number_float;
13651 
13652         /// default constructor (for null values)
13653         json_value() = default;
13654         /// constructor for booleans
json_value(boolean_t v)13655         json_value(boolean_t v) noexcept : boolean(v) {}
13656         /// constructor for numbers (integer)
json_value(number_integer_t v)13657         json_value(number_integer_t v) noexcept : number_integer(v) {}
13658         /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)13659         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
13660         /// constructor for numbers (floating-point)
json_value(number_float_t v)13661         json_value(number_float_t v) noexcept : number_float(v) {}
13662         /// constructor for empty values of a given type
json_value(value_t t)13663         json_value(value_t t)
13664         {
13665             switch (t)
13666             {
13667                 case value_t::object:
13668                 {
13669                     object = create<object_t>();
13670                     break;
13671                 }
13672 
13673                 case value_t::array:
13674                 {
13675                     array = create<array_t>();
13676                     break;
13677                 }
13678 
13679                 case value_t::string:
13680                 {
13681                     string = create<string_t>("");
13682                     break;
13683                 }
13684 
13685                 case value_t::boolean:
13686                 {
13687                     boolean = boolean_t(false);
13688                     break;
13689                 }
13690 
13691                 case value_t::number_integer:
13692                 {
13693                     number_integer = number_integer_t(0);
13694                     break;
13695                 }
13696 
13697                 case value_t::number_unsigned:
13698                 {
13699                     number_unsigned = number_unsigned_t(0);
13700                     break;
13701                 }
13702 
13703                 case value_t::number_float:
13704                 {
13705                     number_float = number_float_t(0.0);
13706                     break;
13707                 }
13708 
13709                 case value_t::null:
13710                 {
13711                     object = nullptr;  // silence warning, see #821
13712                     break;
13713                 }
13714 
13715                 default:
13716                 {
13717                     object = nullptr;  // silence warning, see #821
13718                     if (JSON_UNLIKELY(t == value_t::null))
13719                     {
13720                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.6.1")); // LCOV_EXCL_LINE
13721                     }
13722                     break;
13723                 }
13724             }
13725         }
13726 
13727         /// constructor for strings
json_value(const string_t & value)13728         json_value(const string_t& value)
13729         {
13730             string = create<string_t>(value);
13731         }
13732 
13733         /// constructor for rvalue strings
json_value(string_t && value)13734         json_value(string_t&& value)
13735         {
13736             string = create<string_t>(std::move(value));
13737         }
13738 
13739         /// constructor for objects
json_value(const object_t & value)13740         json_value(const object_t& value)
13741         {
13742             object = create<object_t>(value);
13743         }
13744 
13745         /// constructor for rvalue objects
json_value(object_t && value)13746         json_value(object_t&& value)
13747         {
13748             object = create<object_t>(std::move(value));
13749         }
13750 
13751         /// constructor for arrays
json_value(const array_t & value)13752         json_value(const array_t& value)
13753         {
13754             array = create<array_t>(value);
13755         }
13756 
13757         /// constructor for rvalue arrays
json_value(array_t && value)13758         json_value(array_t&& value)
13759         {
13760             array = create<array_t>(std::move(value));
13761         }
13762 
destroy(value_t t)13763         void destroy(value_t t) noexcept
13764         {
13765             switch (t)
13766             {
13767                 case value_t::object:
13768                 {
13769                     AllocatorType<object_t> alloc;
13770                     std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
13771                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
13772                     break;
13773                 }
13774 
13775                 case value_t::array:
13776                 {
13777                     AllocatorType<array_t> alloc;
13778                     std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
13779                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
13780                     break;
13781                 }
13782 
13783                 case value_t::string:
13784                 {
13785                     AllocatorType<string_t> alloc;
13786                     std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
13787                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
13788                     break;
13789                 }
13790 
13791                 default:
13792                 {
13793                     break;
13794                 }
13795             }
13796         }
13797     };
13798 
13799     /*!
13800     @brief checks the class invariants
13801 
13802     This function asserts the class invariants. It needs to be called at the
13803     end of every constructor to make sure that created objects respect the
13804     invariant. Furthermore, it has to be called each time the type of a JSON
13805     value is changed, because the invariant expresses a relationship between
13806     @a m_type and @a m_value.
13807     */
assert_invariant() const13808     void assert_invariant() const noexcept
13809     {
13810         assert(m_type != value_t::object or m_value.object != nullptr);
13811         assert(m_type != value_t::array or m_value.array != nullptr);
13812         assert(m_type != value_t::string or m_value.string != nullptr);
13813     }
13814 
13815   public:
13816     //////////////////////////
13817     // JSON parser callback //
13818     //////////////////////////
13819 
13820     /*!
13821     @brief parser event types
13822 
13823     The parser callback distinguishes the following events:
13824     - `object_start`: the parser read `{` and started to process a JSON object
13825     - `key`: the parser read a key of a value in an object
13826     - `object_end`: the parser read `}` and finished processing a JSON object
13827     - `array_start`: the parser read `[` and started to process a JSON array
13828     - `array_end`: the parser read `]` and finished processing a JSON array
13829     - `value`: the parser finished reading a JSON value
13830 
13831     @image html callback_events.png "Example when certain parse events are triggered"
13832 
13833     @sa @ref parser_callback_t for more information and examples
13834     */
13835     using parse_event_t = typename parser::parse_event_t;
13836 
13837     /*!
13838     @brief per-element parser callback type
13839 
13840     With a parser callback function, the result of parsing a JSON text can be
13841     influenced. When passed to @ref parse, it is called on certain events
13842     (passed as @ref parse_event_t via parameter @a event) with a set recursion
13843     depth @a depth and context JSON value @a parsed. The return value of the
13844     callback function is a boolean indicating whether the element that emitted
13845     the callback shall be kept or not.
13846 
13847     We distinguish six scenarios (determined by the event type) in which the
13848     callback function can be called. The following table describes the values
13849     of the parameters @a depth, @a event, and @a parsed.
13850 
13851     parameter @a event | description | parameter @a depth | parameter @a parsed
13852     ------------------ | ----------- | ------------------ | -------------------
13853     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
13854     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
13855     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
13856     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
13857     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
13858     parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
13859 
13860     @image html callback_events.png "Example when certain parse events are triggered"
13861 
13862     Discarding a value (i.e., returning `false`) has different effects
13863     depending on the context in which function was called:
13864 
13865     - Discarded values in structured types are skipped. That is, the parser
13866       will behave as if the discarded value was never read.
13867     - In case a value outside a structured type is skipped, it is replaced
13868       with `null`. This case happens if the top-level element is skipped.
13869 
13870     @param[in] depth  the depth of the recursion during parsing
13871 
13872     @param[in] event  an event of type parse_event_t indicating the context in
13873     the callback function has been called
13874 
13875     @param[in,out] parsed  the current intermediate parse result; note that
13876     writing to this value has no effect for parse_event_t::key events
13877 
13878     @return Whether the JSON value which called the function during parsing
13879     should be kept (`true`) or not (`false`). In the latter case, it is either
13880     skipped completely or replaced by an empty discarded object.
13881 
13882     @sa @ref parse for examples
13883 
13884     @since version 1.0.0
13885     */
13886     using parser_callback_t = typename parser::parser_callback_t;
13887 
13888     //////////////////
13889     // constructors //
13890     //////////////////
13891 
13892     /// @name constructors and destructors
13893     /// Constructors of class @ref basic_json, copy/move constructor, copy
13894     /// assignment, static functions creating objects, and the destructor.
13895     /// @{
13896 
13897     /*!
13898     @brief create an empty value with a given type
13899 
13900     Create an empty JSON value with a given type. The value will be default
13901     initialized with an empty value which depends on the type:
13902 
13903     Value type  | initial value
13904     ----------- | -------------
13905     null        | `null`
13906     boolean     | `false`
13907     string      | `""`
13908     number      | `0`
13909     object      | `{}`
13910     array       | `[]`
13911 
13912     @param[in] v  the type of the value to create
13913 
13914     @complexity Constant.
13915 
13916     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13917     changes to any JSON value.
13918 
13919     @liveexample{The following code shows the constructor for different @ref
13920     value_t values,basic_json__value_t}
13921 
13922     @sa @ref clear() -- restores the postcondition of this constructor
13923 
13924     @since version 1.0.0
13925     */
basic_json(const value_t v)13926     basic_json(const value_t v)
13927         : m_type(v), m_value(v)
13928     {
13929         assert_invariant();
13930     }
13931 
13932     /*!
13933     @brief create a null object
13934 
13935     Create a `null` JSON value. It either takes a null pointer as parameter
13936     (explicitly creating `null`) or no parameter (implicitly creating `null`).
13937     The passed null pointer itself is not read -- it is only used to choose
13938     the right constructor.
13939 
13940     @complexity Constant.
13941 
13942     @exceptionsafety No-throw guarantee: this constructor never throws
13943     exceptions.
13944 
13945     @liveexample{The following code shows the constructor with and without a
13946     null pointer parameter.,basic_json__nullptr_t}
13947 
13948     @since version 1.0.0
13949     */
basic_json(std::nullptr_t=nullptr)13950     basic_json(std::nullptr_t = nullptr) noexcept
13951         : basic_json(value_t::null)
13952     {
13953         assert_invariant();
13954     }
13955 
13956     /*!
13957     @brief create a JSON value
13958 
13959     This is a "catch all" constructor for all compatible JSON types; that is,
13960     types for which a `to_json()` method exists. The constructor forwards the
13961     parameter @a val to that method (to `json_serializer<U>::to_json` method
13962     with `U = uncvref_t<CompatibleType>`, to be exact).
13963 
13964     Template type @a CompatibleType includes, but is not limited to, the
13965     following types:
13966     - **arrays**: @ref array_t and all kinds of compatible containers such as
13967       `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
13968       `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
13969       `std::multiset`, and `std::unordered_multiset` with a `value_type` from
13970       which a @ref basic_json value can be constructed.
13971     - **objects**: @ref object_t and all kinds of compatible associative
13972       containers such as `std::map`, `std::unordered_map`, `std::multimap`,
13973       and `std::unordered_multimap` with a `key_type` compatible to
13974       @ref string_t and a `value_type` from which a @ref basic_json value can
13975       be constructed.
13976     - **strings**: @ref string_t, string literals, and all compatible string
13977       containers can be used.
13978     - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
13979       @ref number_float_t, and all convertible number types such as `int`,
13980       `size_t`, `int64_t`, `float` or `double` can be used.
13981     - **boolean**: @ref boolean_t / `bool` can be used.
13982 
13983     See the examples below.
13984 
13985     @tparam CompatibleType a type such that:
13986     - @a CompatibleType is not derived from `std::istream`,
13987     - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
13988          constructors),
13989     - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
13990     - @a CompatibleType is not a @ref basic_json nested type (e.g.,
13991          @ref json_pointer, @ref iterator, etc ...)
13992     - @ref @ref json_serializer<U> has a
13993          `to_json(basic_json_t&, CompatibleType&&)` method
13994 
13995     @tparam U = `uncvref_t<CompatibleType>`
13996 
13997     @param[in] val the value to be forwarded to the respective constructor
13998 
13999     @complexity Usually linear in the size of the passed @a val, also
14000                 depending on the implementation of the called `to_json()`
14001                 method.
14002 
14003     @exceptionsafety Depends on the called constructor. For types directly
14004     supported by the library (i.e., all types for which no `to_json()` function
14005     was provided), strong guarantee holds: if an exception is thrown, there are
14006     no changes to any JSON value.
14007 
14008     @liveexample{The following code shows the constructor with several
14009     compatible types.,basic_json__CompatibleType}
14010 
14011     @since version 2.1.0
14012     */
14013     template <typename CompatibleType,
14014               typename U = detail::uncvref_t<CompatibleType>,
14015               detail::enable_if_t<
14016                   not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
basic_json(CompatibleType && val)14017     basic_json(CompatibleType && val) noexcept(noexcept(
14018                 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
14019                                            std::forward<CompatibleType>(val))))
14020     {
14021         JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
14022         assert_invariant();
14023     }
14024 
14025     /*!
14026     @brief create a JSON value from an existing one
14027 
14028     This is a constructor for existing @ref basic_json types.
14029     It does not hijack copy/move constructors, since the parameter has different
14030     template arguments than the current ones.
14031 
14032     The constructor tries to convert the internal @ref m_value of the parameter.
14033 
14034     @tparam BasicJsonType a type such that:
14035     - @a BasicJsonType is a @ref basic_json type.
14036     - @a BasicJsonType has different template arguments than @ref basic_json_t.
14037 
14038     @param[in] val the @ref basic_json value to be converted.
14039 
14040     @complexity Usually linear in the size of the passed @a val, also
14041                 depending on the implementation of the called `to_json()`
14042                 method.
14043 
14044     @exceptionsafety Depends on the called constructor. For types directly
14045     supported by the library (i.e., all types for which no `to_json()` function
14046     was provided), strong guarantee holds: if an exception is thrown, there are
14047     no changes to any JSON value.
14048 
14049     @since version 3.2.0
14050     */
14051     template <typename BasicJsonType,
14052               detail::enable_if_t<
14053                   detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
basic_json(const BasicJsonType & val)14054     basic_json(const BasicJsonType& val)
14055     {
14056         using other_boolean_t = typename BasicJsonType::boolean_t;
14057         using other_number_float_t = typename BasicJsonType::number_float_t;
14058         using other_number_integer_t = typename BasicJsonType::number_integer_t;
14059         using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
14060         using other_string_t = typename BasicJsonType::string_t;
14061         using other_object_t = typename BasicJsonType::object_t;
14062         using other_array_t = typename BasicJsonType::array_t;
14063 
14064         switch (val.type())
14065         {
14066             case value_t::boolean:
14067                 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
14068                 break;
14069             case value_t::number_float:
14070                 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
14071                 break;
14072             case value_t::number_integer:
14073                 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
14074                 break;
14075             case value_t::number_unsigned:
14076                 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
14077                 break;
14078             case value_t::string:
14079                 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
14080                 break;
14081             case value_t::object:
14082                 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
14083                 break;
14084             case value_t::array:
14085                 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
14086                 break;
14087             case value_t::null:
14088                 *this = nullptr;
14089                 break;
14090             case value_t::discarded:
14091                 m_type = value_t::discarded;
14092                 break;
14093             default:            // LCOV_EXCL_LINE
14094                 assert(false);  // LCOV_EXCL_LINE
14095         }
14096         assert_invariant();
14097     }
14098 
14099     /*!
14100     @brief create a container (array or object) from an initializer list
14101 
14102     Creates a JSON value of type array or object from the passed initializer
14103     list @a init. In case @a type_deduction is `true` (default), the type of
14104     the JSON value to be created is deducted from the initializer list @a init
14105     according to the following rules:
14106 
14107     1. If the list is empty, an empty JSON object value `{}` is created.
14108     2. If the list consists of pairs whose first element is a string, a JSON
14109        object value is created where the first elements of the pairs are
14110        treated as keys and the second elements are as values.
14111     3. In all other cases, an array is created.
14112 
14113     The rules aim to create the best fit between a C++ initializer list and
14114     JSON values. The rationale is as follows:
14115 
14116     1. The empty initializer list is written as `{}` which is exactly an empty
14117        JSON object.
14118     2. C++ has no way of describing mapped types other than to list a list of
14119        pairs. As JSON requires that keys must be of type string, rule 2 is the
14120        weakest constraint one can pose on initializer lists to interpret them
14121        as an object.
14122     3. In all other cases, the initializer list could not be interpreted as
14123        JSON object type, so interpreting it as JSON array type is safe.
14124 
14125     With the rules described above, the following JSON values cannot be
14126     expressed by an initializer list:
14127 
14128     - the empty array (`[]`): use @ref array(initializer_list_t)
14129       with an empty initializer list in this case
14130     - arrays whose elements satisfy rule 2: use @ref
14131       array(initializer_list_t) with the same initializer list
14132       in this case
14133 
14134     @note When used without parentheses around an empty initializer list, @ref
14135     basic_json() is called instead of this function, yielding the JSON null
14136     value.
14137 
14138     @param[in] init  initializer list with JSON values
14139 
14140     @param[in] type_deduction internal parameter; when set to `true`, the type
14141     of the JSON value is deducted from the initializer list @a init; when set
14142     to `false`, the type provided via @a manual_type is forced. This mode is
14143     used by the functions @ref array(initializer_list_t) and
14144     @ref object(initializer_list_t).
14145 
14146     @param[in] manual_type internal parameter; when @a type_deduction is set
14147     to `false`, the created JSON value will use the provided type (only @ref
14148     value_t::array and @ref value_t::object are valid); when @a type_deduction
14149     is set to `true`, this parameter has no effect
14150 
14151     @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
14152     `value_t::object`, but @a init contains an element which is not a pair
14153     whose first element is a string. In this case, the constructor could not
14154     create an object. If @a type_deduction would have be `true`, an array
14155     would have been created. See @ref object(initializer_list_t)
14156     for an example.
14157 
14158     @complexity Linear in the size of the initializer list @a init.
14159 
14160     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14161     changes to any JSON value.
14162 
14163     @liveexample{The example below shows how JSON values are created from
14164     initializer lists.,basic_json__list_init_t}
14165 
14166     @sa @ref array(initializer_list_t) -- create a JSON array
14167     value from an initializer list
14168     @sa @ref object(initializer_list_t) -- create a JSON object
14169     value from an initializer list
14170 
14171     @since version 1.0.0
14172     */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)14173     basic_json(initializer_list_t init,
14174                bool type_deduction = true,
14175                value_t manual_type = value_t::array)
14176     {
14177         // check if each element is an array with two elements whose first
14178         // element is a string
14179         bool is_an_object = std::all_of(init.begin(), init.end(),
14180                                         [](const detail::json_ref<basic_json>& element_ref)
14181         {
14182             return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
14183         });
14184 
14185         // adjust type if type deduction is not wanted
14186         if (not type_deduction)
14187         {
14188             // if array is wanted, do not create an object though possible
14189             if (manual_type == value_t::array)
14190             {
14191                 is_an_object = false;
14192             }
14193 
14194             // if object is wanted but impossible, throw an exception
14195             if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
14196             {
14197                 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
14198             }
14199         }
14200 
14201         if (is_an_object)
14202         {
14203             // the initializer list is a list of pairs -> create object
14204             m_type = value_t::object;
14205             m_value = value_t::object;
14206 
14207             std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
14208             {
14209                 auto element = element_ref.moved_or_copied();
14210                 m_value.object->emplace(
14211                     std::move(*((*element.m_value.array)[0].m_value.string)),
14212                     std::move((*element.m_value.array)[1]));
14213             });
14214         }
14215         else
14216         {
14217             // the initializer list describes an array -> create array
14218             m_type = value_t::array;
14219             m_value.array = create<array_t>(init.begin(), init.end());
14220         }
14221 
14222         assert_invariant();
14223     }
14224 
14225     /*!
14226     @brief explicitly create an array from an initializer list
14227 
14228     Creates a JSON array value from a given initializer list. That is, given a
14229     list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
14230     initializer list is empty, the empty array `[]` is created.
14231 
14232     @note This function is only needed to express two edge cases that cannot
14233     be realized with the initializer list constructor (@ref
14234     basic_json(initializer_list_t, bool, value_t)). These cases
14235     are:
14236     1. creating an array whose elements are all pairs whose first element is a
14237     string -- in this case, the initializer list constructor would create an
14238     object, taking the first elements as keys
14239     2. creating an empty array -- passing the empty initializer list to the
14240     initializer list constructor yields an empty object
14241 
14242     @param[in] init  initializer list with JSON values to create an array from
14243     (optional)
14244 
14245     @return JSON array value
14246 
14247     @complexity Linear in the size of @a init.
14248 
14249     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14250     changes to any JSON value.
14251 
14252     @liveexample{The following code shows an example for the `array`
14253     function.,array}
14254 
14255     @sa @ref basic_json(initializer_list_t, bool, value_t) --
14256     create a JSON value from an initializer list
14257     @sa @ref object(initializer_list_t) -- create a JSON object
14258     value from an initializer list
14259 
14260     @since version 1.0.0
14261     */
14262     JSON_NODISCARD
array(initializer_list_t init={})14263     static basic_json array(initializer_list_t init = {})
14264     {
14265         return basic_json(init, false, value_t::array);
14266     }
14267 
14268     /*!
14269     @brief explicitly create an object from an initializer list
14270 
14271     Creates a JSON object value from a given initializer list. The initializer
14272     lists elements must be pairs, and their first elements must be strings. If
14273     the initializer list is empty, the empty object `{}` is created.
14274 
14275     @note This function is only added for symmetry reasons. In contrast to the
14276     related function @ref array(initializer_list_t), there are
14277     no cases which can only be expressed by this function. That is, any
14278     initializer list @a init can also be passed to the initializer list
14279     constructor @ref basic_json(initializer_list_t, bool, value_t).
14280 
14281     @param[in] init  initializer list to create an object from (optional)
14282 
14283     @return JSON object value
14284 
14285     @throw type_error.301 if @a init is not a list of pairs whose first
14286     elements are strings. In this case, no object can be created. When such a
14287     value is passed to @ref basic_json(initializer_list_t, bool, value_t),
14288     an array would have been created from the passed initializer list @a init.
14289     See example below.
14290 
14291     @complexity Linear in the size of @a init.
14292 
14293     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14294     changes to any JSON value.
14295 
14296     @liveexample{The following code shows an example for the `object`
14297     function.,object}
14298 
14299     @sa @ref basic_json(initializer_list_t, bool, value_t) --
14300     create a JSON value from an initializer list
14301     @sa @ref array(initializer_list_t) -- create a JSON array
14302     value from an initializer list
14303 
14304     @since version 1.0.0
14305     */
14306     JSON_NODISCARD
object(initializer_list_t init={})14307     static basic_json object(initializer_list_t init = {})
14308     {
14309         return basic_json(init, false, value_t::object);
14310     }
14311 
14312     /*!
14313     @brief construct an array with count copies of given value
14314 
14315     Constructs a JSON array value by creating @a cnt copies of a passed value.
14316     In case @a cnt is `0`, an empty array is created.
14317 
14318     @param[in] cnt  the number of JSON copies of @a val to create
14319     @param[in] val  the JSON value to copy
14320 
14321     @post `std::distance(begin(),end()) == cnt` holds.
14322 
14323     @complexity Linear in @a cnt.
14324 
14325     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14326     changes to any JSON value.
14327 
14328     @liveexample{The following code shows examples for the @ref
14329     basic_json(size_type\, const basic_json&)
14330     constructor.,basic_json__size_type_basic_json}
14331 
14332     @since version 1.0.0
14333     */
basic_json(size_type cnt,const basic_json & val)14334     basic_json(size_type cnt, const basic_json& val)
14335         : m_type(value_t::array)
14336     {
14337         m_value.array = create<array_t>(cnt, val);
14338         assert_invariant();
14339     }
14340 
14341     /*!
14342     @brief construct a JSON container given an iterator range
14343 
14344     Constructs the JSON value with the contents of the range `[first, last)`.
14345     The semantics depends on the different types a JSON value can have:
14346     - In case of a null type, invalid_iterator.206 is thrown.
14347     - In case of other primitive types (number, boolean, or string), @a first
14348       must be `begin()` and @a last must be `end()`. In this case, the value is
14349       copied. Otherwise, invalid_iterator.204 is thrown.
14350     - In case of structured types (array, object), the constructor behaves as
14351       similar versions for `std::vector` or `std::map`; that is, a JSON array
14352       or object is constructed from the values in the range.
14353 
14354     @tparam InputIT an input iterator type (@ref iterator or @ref
14355     const_iterator)
14356 
14357     @param[in] first begin of the range to copy from (included)
14358     @param[in] last end of the range to copy from (excluded)
14359 
14360     @pre Iterators @a first and @a last must be initialized. **This
14361          precondition is enforced with an assertion (see warning).** If
14362          assertions are switched off, a violation of this precondition yields
14363          undefined behavior.
14364 
14365     @pre Range `[first, last)` is valid. Usually, this precondition cannot be
14366          checked efficiently. Only certain edge cases are detected; see the
14367          description of the exceptions below. A violation of this precondition
14368          yields undefined behavior.
14369 
14370     @warning A precondition is enforced with a runtime assertion that will
14371              result in calling `std::abort` if this precondition is not met.
14372              Assertions can be disabled by defining `NDEBUG` at compile time.
14373              See https://en.cppreference.com/w/cpp/error/assert for more
14374              information.
14375 
14376     @throw invalid_iterator.201 if iterators @a first and @a last are not
14377     compatible (i.e., do not belong to the same JSON value). In this case,
14378     the range `[first, last)` is undefined.
14379     @throw invalid_iterator.204 if iterators @a first and @a last belong to a
14380     primitive type (number, boolean, or string), but @a first does not point
14381     to the first element any more. In this case, the range `[first, last)` is
14382     undefined. See example code below.
14383     @throw invalid_iterator.206 if iterators @a first and @a last belong to a
14384     null value. In this case, the range `[first, last)` is undefined.
14385 
14386     @complexity Linear in distance between @a first and @a last.
14387 
14388     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14389     changes to any JSON value.
14390 
14391     @liveexample{The example below shows several ways to create JSON values by
14392     specifying a subrange with iterators.,basic_json__InputIt_InputIt}
14393 
14394     @since version 1.0.0
14395     */
14396     template<class InputIT, typename std::enable_if<
14397                  std::is_same<InputIT, typename basic_json_t::iterator>::value or
14398                  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)14399     basic_json(InputIT first, InputIT last)
14400     {
14401         assert(first.m_object != nullptr);
14402         assert(last.m_object != nullptr);
14403 
14404         // make sure iterator fits the current value
14405         if (JSON_UNLIKELY(first.m_object != last.m_object))
14406         {
14407             JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
14408         }
14409 
14410         // copy type from first iterator
14411         m_type = first.m_object->m_type;
14412 
14413         // check if iterator range is complete for primitive values
14414         switch (m_type)
14415         {
14416             case value_t::boolean:
14417             case value_t::number_float:
14418             case value_t::number_integer:
14419             case value_t::number_unsigned:
14420             case value_t::string:
14421             {
14422                 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
14423                                   or not last.m_it.primitive_iterator.is_end()))
14424                 {
14425                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
14426                 }
14427                 break;
14428             }
14429 
14430             default:
14431                 break;
14432         }
14433 
14434         switch (m_type)
14435         {
14436             case value_t::number_integer:
14437             {
14438                 m_value.number_integer = first.m_object->m_value.number_integer;
14439                 break;
14440             }
14441 
14442             case value_t::number_unsigned:
14443             {
14444                 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
14445                 break;
14446             }
14447 
14448             case value_t::number_float:
14449             {
14450                 m_value.number_float = first.m_object->m_value.number_float;
14451                 break;
14452             }
14453 
14454             case value_t::boolean:
14455             {
14456                 m_value.boolean = first.m_object->m_value.boolean;
14457                 break;
14458             }
14459 
14460             case value_t::string:
14461             {
14462                 m_value = *first.m_object->m_value.string;
14463                 break;
14464             }
14465 
14466             case value_t::object:
14467             {
14468                 m_value.object = create<object_t>(first.m_it.object_iterator,
14469                                                   last.m_it.object_iterator);
14470                 break;
14471             }
14472 
14473             case value_t::array:
14474             {
14475                 m_value.array = create<array_t>(first.m_it.array_iterator,
14476                                                 last.m_it.array_iterator);
14477                 break;
14478             }
14479 
14480             default:
14481                 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
14482                                                     std::string(first.m_object->type_name())));
14483         }
14484 
14485         assert_invariant();
14486     }
14487 
14488 
14489     ///////////////////////////////////////
14490     // other constructors and destructor //
14491     ///////////////////////////////////////
14492 
14493     /// @private
basic_json(const detail::json_ref<basic_json> & ref)14494     basic_json(const detail::json_ref<basic_json>& ref)
14495         : basic_json(ref.moved_or_copied())
14496     {}
14497 
14498     /*!
14499     @brief copy constructor
14500 
14501     Creates a copy of a given JSON value.
14502 
14503     @param[in] other  the JSON value to copy
14504 
14505     @post `*this == other`
14506 
14507     @complexity Linear in the size of @a other.
14508 
14509     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14510     changes to any JSON value.
14511 
14512     @requirement This function helps `basic_json` satisfying the
14513     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14514     requirements:
14515     - The complexity is linear.
14516     - As postcondition, it holds: `other == basic_json(other)`.
14517 
14518     @liveexample{The following code shows an example for the copy
14519     constructor.,basic_json__basic_json}
14520 
14521     @since version 1.0.0
14522     */
basic_json(const basic_json & other)14523     basic_json(const basic_json& other)
14524         : m_type(other.m_type)
14525     {
14526         // check of passed value is valid
14527         other.assert_invariant();
14528 
14529         switch (m_type)
14530         {
14531             case value_t::object:
14532             {
14533                 m_value = *other.m_value.object;
14534                 break;
14535             }
14536 
14537             case value_t::array:
14538             {
14539                 m_value = *other.m_value.array;
14540                 break;
14541             }
14542 
14543             case value_t::string:
14544             {
14545                 m_value = *other.m_value.string;
14546                 break;
14547             }
14548 
14549             case value_t::boolean:
14550             {
14551                 m_value = other.m_value.boolean;
14552                 break;
14553             }
14554 
14555             case value_t::number_integer:
14556             {
14557                 m_value = other.m_value.number_integer;
14558                 break;
14559             }
14560 
14561             case value_t::number_unsigned:
14562             {
14563                 m_value = other.m_value.number_unsigned;
14564                 break;
14565             }
14566 
14567             case value_t::number_float:
14568             {
14569                 m_value = other.m_value.number_float;
14570                 break;
14571             }
14572 
14573             default:
14574                 break;
14575         }
14576 
14577         assert_invariant();
14578     }
14579 
14580     /*!
14581     @brief move constructor
14582 
14583     Move constructor. Constructs a JSON value with the contents of the given
14584     value @a other using move semantics. It "steals" the resources from @a
14585     other and leaves it as JSON null value.
14586 
14587     @param[in,out] other  value to move to this object
14588 
14589     @post `*this` has the same value as @a other before the call.
14590     @post @a other is a JSON null value.
14591 
14592     @complexity Constant.
14593 
14594     @exceptionsafety No-throw guarantee: this constructor never throws
14595     exceptions.
14596 
14597     @requirement This function helps `basic_json` satisfying the
14598     [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
14599     requirements.
14600 
14601     @liveexample{The code below shows the move constructor explicitly called
14602     via std::move.,basic_json__moveconstructor}
14603 
14604     @since version 1.0.0
14605     */
basic_json(basic_json && other)14606     basic_json(basic_json&& other) noexcept
14607         : m_type(std::move(other.m_type)),
14608           m_value(std::move(other.m_value))
14609     {
14610         // check that passed value is valid
14611         other.assert_invariant();
14612 
14613         // invalidate payload
14614         other.m_type = value_t::null;
14615         other.m_value = {};
14616 
14617         assert_invariant();
14618     }
14619 
14620     /*!
14621     @brief copy assignment
14622 
14623     Copy assignment operator. Copies a JSON value via the "copy and swap"
14624     strategy: It is expressed in terms of the copy constructor, destructor,
14625     and the `swap()` member function.
14626 
14627     @param[in] other  value to copy from
14628 
14629     @complexity Linear.
14630 
14631     @requirement This function helps `basic_json` satisfying the
14632     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14633     requirements:
14634     - The complexity is linear.
14635 
14636     @liveexample{The code below shows and example for the copy assignment. It
14637     creates a copy of value `a` which is then swapped with `b`. Finally\, the
14638     copy of `a` (which is the null value after the swap) is
14639     destroyed.,basic_json__copyassignment}
14640 
14641     @since version 1.0.0
14642     */
operator =(basic_json other)14643     basic_json& operator=(basic_json other) noexcept (
14644         std::is_nothrow_move_constructible<value_t>::value and
14645         std::is_nothrow_move_assignable<value_t>::value and
14646         std::is_nothrow_move_constructible<json_value>::value and
14647         std::is_nothrow_move_assignable<json_value>::value
14648     )
14649     {
14650         // check that passed value is valid
14651         other.assert_invariant();
14652 
14653         using std::swap;
14654         swap(m_type, other.m_type);
14655         swap(m_value, other.m_value);
14656 
14657         assert_invariant();
14658         return *this;
14659     }
14660 
14661     /*!
14662     @brief destructor
14663 
14664     Destroys the JSON value and frees all allocated memory.
14665 
14666     @complexity Linear.
14667 
14668     @requirement This function helps `basic_json` satisfying the
14669     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14670     requirements:
14671     - The complexity is linear.
14672     - All stored elements are destroyed and all memory is freed.
14673 
14674     @since version 1.0.0
14675     */
~basic_json()14676     ~basic_json() noexcept
14677     {
14678         assert_invariant();
14679         m_value.destroy(m_type);
14680     }
14681 
14682     /// @}
14683 
14684   public:
14685     ///////////////////////
14686     // object inspection //
14687     ///////////////////////
14688 
14689     /// @name object inspection
14690     /// Functions to inspect the type of a JSON value.
14691     /// @{
14692 
14693     /*!
14694     @brief serialization
14695 
14696     Serialization function for JSON values. The function tries to mimic
14697     Python's `json.dumps()` function, and currently supports its @a indent
14698     and @a ensure_ascii parameters.
14699 
14700     @param[in] indent If indent is nonnegative, then array elements and object
14701     members will be pretty-printed with that indent level. An indent level of
14702     `0` will only insert newlines. `-1` (the default) selects the most compact
14703     representation.
14704     @param[in] indent_char The character to use for indentation if @a indent is
14705     greater than `0`. The default is ` ` (space).
14706     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
14707     in the output are escaped with `\uXXXX` sequences, and the result consists
14708     of ASCII characters only.
14709     @param[in] error_handler  how to react on decoding errors; there are three
14710     possible values: `strict` (throws and exception in case a decoding error
14711     occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
14712     and `ignore` (ignore invalid UTF-8 sequences during serialization).
14713 
14714     @return string containing the serialization of the JSON value
14715 
14716     @throw type_error.316 if a string stored inside the JSON value is not
14717                           UTF-8 encoded
14718 
14719     @complexity Linear.
14720 
14721     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14722     changes in the JSON value.
14723 
14724     @liveexample{The following example shows the effect of different @a indent\,
14725     @a indent_char\, and @a ensure_ascii parameters to the result of the
14726     serialization.,dump}
14727 
14728     @see https://docs.python.org/2/library/json.html#json.dump
14729 
14730     @since version 1.0.0; indentation character @a indent_char, option
14731            @a ensure_ascii and exceptions added in version 3.0.0; error
14732            handlers added in version 3.4.0.
14733     */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const14734     string_t dump(const int indent = -1,
14735                   const char indent_char = ' ',
14736                   const bool ensure_ascii = false,
14737                   const error_handler_t error_handler = error_handler_t::strict) const
14738     {
14739         string_t result;
14740         serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
14741 
14742         if (indent >= 0)
14743         {
14744             s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
14745         }
14746         else
14747         {
14748             s.dump(*this, false, ensure_ascii, 0);
14749         }
14750 
14751         return result;
14752     }
14753 
14754     /*!
14755     @brief return the type of the JSON value (explicit)
14756 
14757     Return the type of the JSON value as a value from the @ref value_t
14758     enumeration.
14759 
14760     @return the type of the JSON value
14761             Value type                | return value
14762             ------------------------- | -------------------------
14763             null                      | value_t::null
14764             boolean                   | value_t::boolean
14765             string                    | value_t::string
14766             number (integer)          | value_t::number_integer
14767             number (unsigned integer) | value_t::number_unsigned
14768             number (floating-point)   | value_t::number_float
14769             object                    | value_t::object
14770             array                     | value_t::array
14771             discarded                 | value_t::discarded
14772 
14773     @complexity Constant.
14774 
14775     @exceptionsafety No-throw guarantee: this member function never throws
14776     exceptions.
14777 
14778     @liveexample{The following code exemplifies `type()` for all JSON
14779     types.,type}
14780 
14781     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
14782     @sa @ref type_name() -- return the type as string
14783 
14784     @since version 1.0.0
14785     */
type() const14786     constexpr value_t type() const noexcept
14787     {
14788         return m_type;
14789     }
14790 
14791     /*!
14792     @brief return whether type is primitive
14793 
14794     This function returns true if and only if the JSON type is primitive
14795     (string, number, boolean, or null).
14796 
14797     @return `true` if type is primitive (string, number, boolean, or null),
14798     `false` otherwise.
14799 
14800     @complexity Constant.
14801 
14802     @exceptionsafety No-throw guarantee: this member function never throws
14803     exceptions.
14804 
14805     @liveexample{The following code exemplifies `is_primitive()` for all JSON
14806     types.,is_primitive}
14807 
14808     @sa @ref is_structured() -- returns whether JSON value is structured
14809     @sa @ref is_null() -- returns whether JSON value is `null`
14810     @sa @ref is_string() -- returns whether JSON value is a string
14811     @sa @ref is_boolean() -- returns whether JSON value is a boolean
14812     @sa @ref is_number() -- returns whether JSON value is a number
14813 
14814     @since version 1.0.0
14815     */
is_primitive() const14816     constexpr bool is_primitive() const noexcept
14817     {
14818         return is_null() or is_string() or is_boolean() or is_number();
14819     }
14820 
14821     /*!
14822     @brief return whether type is structured
14823 
14824     This function returns true if and only if the JSON type is structured
14825     (array or object).
14826 
14827     @return `true` if type is structured (array or object), `false` otherwise.
14828 
14829     @complexity Constant.
14830 
14831     @exceptionsafety No-throw guarantee: this member function never throws
14832     exceptions.
14833 
14834     @liveexample{The following code exemplifies `is_structured()` for all JSON
14835     types.,is_structured}
14836 
14837     @sa @ref is_primitive() -- returns whether value is primitive
14838     @sa @ref is_array() -- returns whether value is an array
14839     @sa @ref is_object() -- returns whether value is an object
14840 
14841     @since version 1.0.0
14842     */
is_structured() const14843     constexpr bool is_structured() const noexcept
14844     {
14845         return is_array() or is_object();
14846     }
14847 
14848     /*!
14849     @brief return whether value is null
14850 
14851     This function returns true if and only if the JSON value is null.
14852 
14853     @return `true` if type is null, `false` otherwise.
14854 
14855     @complexity Constant.
14856 
14857     @exceptionsafety No-throw guarantee: this member function never throws
14858     exceptions.
14859 
14860     @liveexample{The following code exemplifies `is_null()` for all JSON
14861     types.,is_null}
14862 
14863     @since version 1.0.0
14864     */
is_null() const14865     constexpr bool is_null() const noexcept
14866     {
14867         return m_type == value_t::null;
14868     }
14869 
14870     /*!
14871     @brief return whether value is a boolean
14872 
14873     This function returns true if and only if the JSON value is a boolean.
14874 
14875     @return `true` if type is boolean, `false` otherwise.
14876 
14877     @complexity Constant.
14878 
14879     @exceptionsafety No-throw guarantee: this member function never throws
14880     exceptions.
14881 
14882     @liveexample{The following code exemplifies `is_boolean()` for all JSON
14883     types.,is_boolean}
14884 
14885     @since version 1.0.0
14886     */
is_boolean() const14887     constexpr bool is_boolean() const noexcept
14888     {
14889         return m_type == value_t::boolean;
14890     }
14891 
14892     /*!
14893     @brief return whether value is a number
14894 
14895     This function returns true if and only if the JSON value is a number. This
14896     includes both integer (signed and unsigned) and floating-point values.
14897 
14898     @return `true` if type is number (regardless whether integer, unsigned
14899     integer or floating-type), `false` otherwise.
14900 
14901     @complexity Constant.
14902 
14903     @exceptionsafety No-throw guarantee: this member function never throws
14904     exceptions.
14905 
14906     @liveexample{The following code exemplifies `is_number()` for all JSON
14907     types.,is_number}
14908 
14909     @sa @ref is_number_integer() -- check if value is an integer or unsigned
14910     integer number
14911     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
14912     number
14913     @sa @ref is_number_float() -- check if value is a floating-point number
14914 
14915     @since version 1.0.0
14916     */
is_number() const14917     constexpr bool is_number() const noexcept
14918     {
14919         return is_number_integer() or is_number_float();
14920     }
14921 
14922     /*!
14923     @brief return whether value is an integer number
14924 
14925     This function returns true if and only if the JSON value is a signed or
14926     unsigned integer number. This excludes floating-point values.
14927 
14928     @return `true` if type is an integer or unsigned integer number, `false`
14929     otherwise.
14930 
14931     @complexity Constant.
14932 
14933     @exceptionsafety No-throw guarantee: this member function never throws
14934     exceptions.
14935 
14936     @liveexample{The following code exemplifies `is_number_integer()` for all
14937     JSON types.,is_number_integer}
14938 
14939     @sa @ref is_number() -- check if value is a number
14940     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
14941     number
14942     @sa @ref is_number_float() -- check if value is a floating-point number
14943 
14944     @since version 1.0.0
14945     */
is_number_integer() const14946     constexpr bool is_number_integer() const noexcept
14947     {
14948         return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
14949     }
14950 
14951     /*!
14952     @brief return whether value is an unsigned integer number
14953 
14954     This function returns true if and only if the JSON value is an unsigned
14955     integer number. This excludes floating-point and signed integer values.
14956 
14957     @return `true` if type is an unsigned integer number, `false` otherwise.
14958 
14959     @complexity Constant.
14960 
14961     @exceptionsafety No-throw guarantee: this member function never throws
14962     exceptions.
14963 
14964     @liveexample{The following code exemplifies `is_number_unsigned()` for all
14965     JSON types.,is_number_unsigned}
14966 
14967     @sa @ref is_number() -- check if value is a number
14968     @sa @ref is_number_integer() -- check if value is an integer or unsigned
14969     integer number
14970     @sa @ref is_number_float() -- check if value is a floating-point number
14971 
14972     @since version 2.0.0
14973     */
is_number_unsigned() const14974     constexpr bool is_number_unsigned() const noexcept
14975     {
14976         return m_type == value_t::number_unsigned;
14977     }
14978 
14979     /*!
14980     @brief return whether value is a floating-point number
14981 
14982     This function returns true if and only if the JSON value is a
14983     floating-point number. This excludes signed and unsigned integer values.
14984 
14985     @return `true` if type is a floating-point number, `false` otherwise.
14986 
14987     @complexity Constant.
14988 
14989     @exceptionsafety No-throw guarantee: this member function never throws
14990     exceptions.
14991 
14992     @liveexample{The following code exemplifies `is_number_float()` for all
14993     JSON types.,is_number_float}
14994 
14995     @sa @ref is_number() -- check if value is number
14996     @sa @ref is_number_integer() -- check if value is an integer number
14997     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
14998     number
14999 
15000     @since version 1.0.0
15001     */
is_number_float() const15002     constexpr bool is_number_float() const noexcept
15003     {
15004         return m_type == value_t::number_float;
15005     }
15006 
15007     /*!
15008     @brief return whether value is an object
15009 
15010     This function returns true if and only if the JSON value is an object.
15011 
15012     @return `true` if type is object, `false` otherwise.
15013 
15014     @complexity Constant.
15015 
15016     @exceptionsafety No-throw guarantee: this member function never throws
15017     exceptions.
15018 
15019     @liveexample{The following code exemplifies `is_object()` for all JSON
15020     types.,is_object}
15021 
15022     @since version 1.0.0
15023     */
is_object() const15024     constexpr bool is_object() const noexcept
15025     {
15026         return m_type == value_t::object;
15027     }
15028 
15029     /*!
15030     @brief return whether value is an array
15031 
15032     This function returns true if and only if the JSON value is an array.
15033 
15034     @return `true` if type is array, `false` otherwise.
15035 
15036     @complexity Constant.
15037 
15038     @exceptionsafety No-throw guarantee: this member function never throws
15039     exceptions.
15040 
15041     @liveexample{The following code exemplifies `is_array()` for all JSON
15042     types.,is_array}
15043 
15044     @since version 1.0.0
15045     */
is_array() const15046     constexpr bool is_array() const noexcept
15047     {
15048         return m_type == value_t::array;
15049     }
15050 
15051     /*!
15052     @brief return whether value is a string
15053 
15054     This function returns true if and only if the JSON value is a string.
15055 
15056     @return `true` if type is string, `false` otherwise.
15057 
15058     @complexity Constant.
15059 
15060     @exceptionsafety No-throw guarantee: this member function never throws
15061     exceptions.
15062 
15063     @liveexample{The following code exemplifies `is_string()` for all JSON
15064     types.,is_string}
15065 
15066     @since version 1.0.0
15067     */
is_string() const15068     constexpr bool is_string() const noexcept
15069     {
15070         return m_type == value_t::string;
15071     }
15072 
15073     /*!
15074     @brief return whether value is discarded
15075 
15076     This function returns true if and only if the JSON value was discarded
15077     during parsing with a callback function (see @ref parser_callback_t).
15078 
15079     @note This function will always be `false` for JSON values after parsing.
15080     That is, discarded values can only occur during parsing, but will be
15081     removed when inside a structured value or replaced by null in other cases.
15082 
15083     @return `true` if type is discarded, `false` otherwise.
15084 
15085     @complexity Constant.
15086 
15087     @exceptionsafety No-throw guarantee: this member function never throws
15088     exceptions.
15089 
15090     @liveexample{The following code exemplifies `is_discarded()` for all JSON
15091     types.,is_discarded}
15092 
15093     @since version 1.0.0
15094     */
is_discarded() const15095     constexpr bool is_discarded() const noexcept
15096     {
15097         return m_type == value_t::discarded;
15098     }
15099 
15100     /*!
15101     @brief return the type of the JSON value (implicit)
15102 
15103     Implicitly return the type of the JSON value as a value from the @ref
15104     value_t enumeration.
15105 
15106     @return the type of the JSON value
15107 
15108     @complexity Constant.
15109 
15110     @exceptionsafety No-throw guarantee: this member function never throws
15111     exceptions.
15112 
15113     @liveexample{The following code exemplifies the @ref value_t operator for
15114     all JSON types.,operator__value_t}
15115 
15116     @sa @ref type() -- return the type of the JSON value (explicit)
15117     @sa @ref type_name() -- return the type as string
15118 
15119     @since version 1.0.0
15120     */
operator value_t() const15121     constexpr operator value_t() const noexcept
15122     {
15123         return m_type;
15124     }
15125 
15126     /// @}
15127 
15128   private:
15129     //////////////////
15130     // value access //
15131     //////////////////
15132 
15133     /// get a boolean (explicit)
get_impl(boolean_t *) const15134     boolean_t get_impl(boolean_t* /*unused*/) const
15135     {
15136         if (JSON_LIKELY(is_boolean()))
15137         {
15138             return m_value.boolean;
15139         }
15140 
15141         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
15142     }
15143 
15144     /// get a pointer to the value (object)
get_impl_ptr(object_t *)15145     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
15146     {
15147         return is_object() ? m_value.object : nullptr;
15148     }
15149 
15150     /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const15151     constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
15152     {
15153         return is_object() ? m_value.object : nullptr;
15154     }
15155 
15156     /// get a pointer to the value (array)
get_impl_ptr(array_t *)15157     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
15158     {
15159         return is_array() ? m_value.array : nullptr;
15160     }
15161 
15162     /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const15163     constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
15164     {
15165         return is_array() ? m_value.array : nullptr;
15166     }
15167 
15168     /// get a pointer to the value (string)
get_impl_ptr(string_t *)15169     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
15170     {
15171         return is_string() ? m_value.string : nullptr;
15172     }
15173 
15174     /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const15175     constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
15176     {
15177         return is_string() ? m_value.string : nullptr;
15178     }
15179 
15180     /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)15181     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
15182     {
15183         return is_boolean() ? &m_value.boolean : nullptr;
15184     }
15185 
15186     /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const15187     constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
15188     {
15189         return is_boolean() ? &m_value.boolean : nullptr;
15190     }
15191 
15192     /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)15193     number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
15194     {
15195         return is_number_integer() ? &m_value.number_integer : nullptr;
15196     }
15197 
15198     /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const15199     constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
15200     {
15201         return is_number_integer() ? &m_value.number_integer : nullptr;
15202     }
15203 
15204     /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)15205     number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
15206     {
15207         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
15208     }
15209 
15210     /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const15211     constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
15212     {
15213         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
15214     }
15215 
15216     /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)15217     number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
15218     {
15219         return is_number_float() ? &m_value.number_float : nullptr;
15220     }
15221 
15222     /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const15223     constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
15224     {
15225         return is_number_float() ? &m_value.number_float : nullptr;
15226     }
15227 
15228     /*!
15229     @brief helper function to implement get_ref()
15230 
15231     This function helps to implement get_ref() without code duplication for
15232     const and non-const overloads
15233 
15234     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
15235 
15236     @throw type_error.303 if ReferenceType does not match underlying value
15237     type of the current JSON
15238     */
15239     template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)15240     static ReferenceType get_ref_impl(ThisType& obj)
15241     {
15242         // delegate the call to get_ptr<>()
15243         auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
15244 
15245         if (JSON_LIKELY(ptr != nullptr))
15246         {
15247             return *ptr;
15248         }
15249 
15250         JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
15251     }
15252 
15253   public:
15254     /// @name value access
15255     /// Direct access to the stored value of a JSON value.
15256     /// @{
15257 
15258     /*!
15259     @brief get special-case overload
15260 
15261     This overloads avoids a lot of template boilerplate, it can be seen as the
15262     identity method
15263 
15264     @tparam BasicJsonType == @ref basic_json
15265 
15266     @return a copy of *this
15267 
15268     @complexity Constant.
15269 
15270     @since version 2.1.0
15271     */
15272     template<typename BasicJsonType, detail::enable_if_t<
15273                  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
15274                  int> = 0>
get() const15275     basic_json get() const
15276     {
15277         return *this;
15278     }
15279 
15280     /*!
15281     @brief get special-case overload
15282 
15283     This overloads converts the current @ref basic_json in a different
15284     @ref basic_json type
15285 
15286     @tparam BasicJsonType == @ref basic_json
15287 
15288     @return a copy of *this, converted into @tparam BasicJsonType
15289 
15290     @complexity Depending on the implementation of the called `from_json()`
15291                 method.
15292 
15293     @since version 3.2.0
15294     */
15295     template<typename BasicJsonType, detail::enable_if_t<
15296                  not std::is_same<BasicJsonType, basic_json>::value and
15297                  detail::is_basic_json<BasicJsonType>::value, int> = 0>
15298     BasicJsonType get() const
15299     {
15300         return *this;
15301     }
15302 
15303     /*!
15304     @brief get a value (explicit)
15305 
15306     Explicit type conversion between the JSON value and a compatible value
15307     which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
15308     and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
15309     The value is converted by calling the @ref json_serializer<ValueType>
15310     `from_json()` method.
15311 
15312     The function is equivalent to executing
15313     @code {.cpp}
15314     ValueType ret;
15315     JSONSerializer<ValueType>::from_json(*this, ret);
15316     return ret;
15317     @endcode
15318 
15319     This overloads is chosen if:
15320     - @a ValueType is not @ref basic_json,
15321     - @ref json_serializer<ValueType> has a `from_json()` method of the form
15322       `void from_json(const basic_json&, ValueType&)`, and
15323     - @ref json_serializer<ValueType> does not have a `from_json()` method of
15324       the form `ValueType from_json(const basic_json&)`
15325 
15326     @tparam ValueTypeCV the provided value type
15327     @tparam ValueType the returned value type
15328 
15329     @return copy of the JSON value, converted to @a ValueType
15330 
15331     @throw what @ref json_serializer<ValueType> `from_json()` method throws
15332 
15333     @liveexample{The example below shows several conversions from JSON values
15334     to other types. There a few things to note: (1) Floating-point numbers can
15335     be converted to integers\, (2) A JSON array can be converted to a standard
15336     `std::vector<short>`\, (3) A JSON object can be converted to C++
15337     associative containers such as `std::unordered_map<std::string\,
15338     json>`.,get__ValueType_const}
15339 
15340     @since version 2.1.0
15341     */
15342     template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
15343              detail::enable_if_t <
15344                  not detail::is_basic_json<ValueType>::value and
15345                  detail::has_from_json<basic_json_t, ValueType>::value and
15346                  not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15347                  int> = 0>
15348     ValueType get() const noexcept(noexcept(
15349                                        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
15350     {
15351         // we cannot static_assert on ValueTypeCV being non-const, because
15352         // there is support for get<const basic_json_t>(), which is why we
15353         // still need the uncvref
15354         static_assert(not std::is_reference<ValueTypeCV>::value,
15355                       "get() cannot be used with reference types, you might want to use get_ref()");
15356         static_assert(std::is_default_constructible<ValueType>::value,
15357                       "types must be DefaultConstructible when used with get()");
15358 
15359         ValueType ret;
15360         JSONSerializer<ValueType>::from_json(*this, ret);
15361         return ret;
15362     }
15363 
15364     /*!
15365     @brief get a value (explicit); special case
15366 
15367     Explicit type conversion between the JSON value and a compatible value
15368     which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
15369     and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
15370     The value is converted by calling the @ref json_serializer<ValueType>
15371     `from_json()` method.
15372 
15373     The function is equivalent to executing
15374     @code {.cpp}
15375     return JSONSerializer<ValueTypeCV>::from_json(*this);
15376     @endcode
15377 
15378     This overloads is chosen if:
15379     - @a ValueType is not @ref basic_json and
15380     - @ref json_serializer<ValueType> has a `from_json()` method of the form
15381       `ValueType from_json(const basic_json&)`
15382 
15383     @note If @ref json_serializer<ValueType> has both overloads of
15384     `from_json()`, this one is chosen.
15385 
15386     @tparam ValueTypeCV the provided value type
15387     @tparam ValueType the returned value type
15388 
15389     @return copy of the JSON value, converted to @a ValueType
15390 
15391     @throw what @ref json_serializer<ValueType> `from_json()` method throws
15392 
15393     @since version 2.1.0
15394     */
15395     template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
15396              detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
15397                                  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15398                                  int> = 0>
15399     ValueType get() const noexcept(noexcept(
15400                                        JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
15401     {
15402         static_assert(not std::is_reference<ValueTypeCV>::value,
15403                       "get() cannot be used with reference types, you might want to use get_ref()");
15404         return JSONSerializer<ValueTypeCV>::from_json(*this);
15405     }
15406 
15407     /*!
15408     @brief get a value (explicit)
15409 
15410     Explicit type conversion between the JSON value and a compatible value.
15411     The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
15412     `from_json()` method.
15413 
15414     The function is equivalent to executing
15415     @code {.cpp}
15416     ValueType v;
15417     JSONSerializer<ValueType>::from_json(*this, v);
15418     @endcode
15419 
15420     This overloads is chosen if:
15421     - @a ValueType is not @ref basic_json,
15422     - @ref json_serializer<ValueType> has a `from_json()` method of the form
15423       `void from_json(const basic_json&, ValueType&)`, and
15424 
15425     @tparam ValueType the input parameter type.
15426 
15427     @return the input parameter, allowing chaining calls.
15428 
15429     @throw what @ref json_serializer<ValueType> `from_json()` method throws
15430 
15431     @liveexample{The example below shows several conversions from JSON values
15432     to other types. There a few things to note: (1) Floating-point numbers can
15433     be converted to integers\, (2) A JSON array can be converted to a standard
15434     `std::vector<short>`\, (3) A JSON object can be converted to C++
15435     associative containers such as `std::unordered_map<std::string\,
15436     json>`.,get_to}
15437 
15438     @since version 3.3.0
15439     */
15440     template<typename ValueType,
15441              detail::enable_if_t <
15442                  not detail::is_basic_json<ValueType>::value and
15443                  detail::has_from_json<basic_json_t, ValueType>::value,
15444                  int> = 0>
15445     ValueType & get_to(ValueType& v) const noexcept(noexcept(
15446                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
15447     {
15448         JSONSerializer<ValueType>::from_json(*this, v);
15449         return v;
15450     }
15451 
15452 
15453     /*!
15454     @brief get a pointer value (implicit)
15455 
15456     Implicit pointer access to the internally stored JSON value. No copies are
15457     made.
15458 
15459     @warning Writing data to the pointee of the result yields an undefined
15460     state.
15461 
15462     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
15463     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
15464     @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
15465     assertion.
15466 
15467     @return pointer to the internally stored JSON value if the requested
15468     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
15469 
15470     @complexity Constant.
15471 
15472     @liveexample{The example below shows how pointers to internal values of a
15473     JSON value can be requested. Note that no type conversions are made and a
15474     `nullptr` is returned if the value and the requested pointer type does not
15475     match.,get_ptr}
15476 
15477     @since version 1.0.0
15478     */
15479     template<typename PointerType, typename std::enable_if<
15480                  std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()15481     auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15482     {
15483         // delegate the call to get_impl_ptr<>()
15484         return get_impl_ptr(static_cast<PointerType>(nullptr));
15485     }
15486 
15487     /*!
15488     @brief get a pointer value (implicit)
15489     @copydoc get_ptr()
15490     */
15491     template<typename PointerType, typename std::enable_if<
15492                  std::is_pointer<PointerType>::value and
15493                  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const15494     constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15495     {
15496         // delegate the call to get_impl_ptr<>() const
15497         return get_impl_ptr(static_cast<PointerType>(nullptr));
15498     }
15499 
15500     /*!
15501     @brief get a pointer value (explicit)
15502 
15503     Explicit pointer access to the internally stored JSON value. No copies are
15504     made.
15505 
15506     @warning The pointer becomes invalid if the underlying JSON object
15507     changes.
15508 
15509     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
15510     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
15511     @ref number_unsigned_t, or @ref number_float_t.
15512 
15513     @return pointer to the internally stored JSON value if the requested
15514     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
15515 
15516     @complexity Constant.
15517 
15518     @liveexample{The example below shows how pointers to internal values of a
15519     JSON value can be requested. Note that no type conversions are made and a
15520     `nullptr` is returned if the value and the requested pointer type does not
15521     match.,get__PointerType}
15522 
15523     @sa @ref get_ptr() for explicit pointer-member access
15524 
15525     @since version 1.0.0
15526     */
15527     template<typename PointerType, typename std::enable_if<
15528                  std::is_pointer<PointerType>::value, int>::type = 0>
get()15529     auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
15530     {
15531         // delegate the call to get_ptr
15532         return get_ptr<PointerType>();
15533     }
15534 
15535     /*!
15536     @brief get a pointer value (explicit)
15537     @copydoc get()
15538     */
15539     template<typename PointerType, typename std::enable_if<
15540                  std::is_pointer<PointerType>::value, int>::type = 0>
get() const15541     constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
15542     {
15543         // delegate the call to get_ptr
15544         return get_ptr<PointerType>();
15545     }
15546 
15547     /*!
15548     @brief get a reference value (implicit)
15549 
15550     Implicit reference access to the internally stored JSON value. No copies
15551     are made.
15552 
15553     @warning Writing data to the referee of the result yields an undefined
15554     state.
15555 
15556     @tparam ReferenceType reference type; must be a reference to @ref array_t,
15557     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
15558     @ref number_float_t. Enforced by static assertion.
15559 
15560     @return reference to the internally stored JSON value if the requested
15561     reference type @a ReferenceType fits to the JSON value; throws
15562     type_error.303 otherwise
15563 
15564     @throw type_error.303 in case passed type @a ReferenceType is incompatible
15565     with the stored JSON value; see example below
15566 
15567     @complexity Constant.
15568 
15569     @liveexample{The example shows several calls to `get_ref()`.,get_ref}
15570 
15571     @since version 1.1.0
15572     */
15573     template<typename ReferenceType, typename std::enable_if<
15574                  std::is_reference<ReferenceType>::value, int>::type = 0>
15575     ReferenceType get_ref()
15576     {
15577         // delegate call to get_ref_impl
15578         return get_ref_impl<ReferenceType>(*this);
15579     }
15580 
15581     /*!
15582     @brief get a reference value (implicit)
15583     @copydoc get_ref()
15584     */
15585     template<typename ReferenceType, typename std::enable_if<
15586                  std::is_reference<ReferenceType>::value and
15587                  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
15588     ReferenceType get_ref() const
15589     {
15590         // delegate call to get_ref_impl
15591         return get_ref_impl<ReferenceType>(*this);
15592     }
15593 
15594     /*!
15595     @brief get a value (implicit)
15596 
15597     Implicit type conversion between the JSON value and a compatible value.
15598     The call is realized by calling @ref get() const.
15599 
15600     @tparam ValueType non-pointer type compatible to the JSON value, for
15601     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
15602     `std::vector` types for JSON arrays. The character type of @ref string_t
15603     as well as an initializer list of this type is excluded to avoid
15604     ambiguities as these types implicitly convert to `std::string`.
15605 
15606     @return copy of the JSON value, converted to type @a ValueType
15607 
15608     @throw type_error.302 in case passed type @a ValueType is incompatible
15609     to the JSON value type (e.g., the JSON value is of type boolean, but a
15610     string is requested); see example below
15611 
15612     @complexity Linear in the size of the JSON value.
15613 
15614     @liveexample{The example below shows several conversions from JSON values
15615     to other types. There a few things to note: (1) Floating-point numbers can
15616     be converted to integers\, (2) A JSON array can be converted to a standard
15617     `std::vector<short>`\, (3) A JSON object can be converted to C++
15618     associative containers such as `std::unordered_map<std::string\,
15619     json>`.,operator__ValueType}
15620 
15621     @since version 1.0.0
15622     */
15623     template < typename ValueType, typename std::enable_if <
15624                    not std::is_pointer<ValueType>::value and
15625                    not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
15626                    not std::is_same<ValueType, typename string_t::value_type>::value and
15627                    not detail::is_basic_json<ValueType>::value
15628 
15629 #ifndef _MSC_VER  // fix for issue #167 operator<< ambiguity under VS2015
15630                    and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
15631 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
15632                    and not std::is_same<ValueType, typename std::string_view>::value
15633 #endif
15634 #endif
15635                    and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
15636                    , int >::type = 0 >
operator ValueType() const15637     operator ValueType() const
15638     {
15639         // delegate the call to get<>() const
15640         return get<ValueType>();
15641     }
15642 
15643     /// @}
15644 
15645 
15646     ////////////////////
15647     // element access //
15648     ////////////////////
15649 
15650     /// @name element access
15651     /// Access to the JSON value.
15652     /// @{
15653 
15654     /*!
15655     @brief access specified array element with bounds checking
15656 
15657     Returns a reference to the element at specified location @a idx, with
15658     bounds checking.
15659 
15660     @param[in] idx  index of the element to access
15661 
15662     @return reference to the element at index @a idx
15663 
15664     @throw type_error.304 if the JSON value is not an array; in this case,
15665     calling `at` with an index makes no sense. See example below.
15666     @throw out_of_range.401 if the index @a idx is out of range of the array;
15667     that is, `idx >= size()`. See example below.
15668 
15669     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15670     changes in the JSON value.
15671 
15672     @complexity Constant.
15673 
15674     @since version 1.0.0
15675 
15676     @liveexample{The example below shows how array elements can be read and
15677     written using `at()`. It also demonstrates the different exceptions that
15678     can be thrown.,at__size_type}
15679     */
at(size_type idx)15680     reference at(size_type idx)
15681     {
15682         // at only works for arrays
15683         if (JSON_LIKELY(is_array()))
15684         {
15685             JSON_TRY
15686             {
15687                 return m_value.array->at(idx);
15688             }
15689             JSON_CATCH (std::out_of_range&)
15690             {
15691                 // create better exception explanation
15692                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
15693             }
15694         }
15695         else
15696         {
15697             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15698         }
15699     }
15700 
15701     /*!
15702     @brief access specified array element with bounds checking
15703 
15704     Returns a const reference to the element at specified location @a idx,
15705     with bounds checking.
15706 
15707     @param[in] idx  index of the element to access
15708 
15709     @return const reference to the element at index @a idx
15710 
15711     @throw type_error.304 if the JSON value is not an array; in this case,
15712     calling `at` with an index makes no sense. See example below.
15713     @throw out_of_range.401 if the index @a idx is out of range of the array;
15714     that is, `idx >= size()`. See example below.
15715 
15716     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15717     changes in the JSON value.
15718 
15719     @complexity Constant.
15720 
15721     @since version 1.0.0
15722 
15723     @liveexample{The example below shows how array elements can be read using
15724     `at()`. It also demonstrates the different exceptions that can be thrown.,
15725     at__size_type_const}
15726     */
at(size_type idx) const15727     const_reference at(size_type idx) const
15728     {
15729         // at only works for arrays
15730         if (JSON_LIKELY(is_array()))
15731         {
15732             JSON_TRY
15733             {
15734                 return m_value.array->at(idx);
15735             }
15736             JSON_CATCH (std::out_of_range&)
15737             {
15738                 // create better exception explanation
15739                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
15740             }
15741         }
15742         else
15743         {
15744             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15745         }
15746     }
15747 
15748     /*!
15749     @brief access specified object element with bounds checking
15750 
15751     Returns a reference to the element at with specified key @a key, with
15752     bounds checking.
15753 
15754     @param[in] key  key of the element to access
15755 
15756     @return reference to the element at key @a key
15757 
15758     @throw type_error.304 if the JSON value is not an object; in this case,
15759     calling `at` with a key makes no sense. See example below.
15760     @throw out_of_range.403 if the key @a key is is not stored in the object;
15761     that is, `find(key) == end()`. See example below.
15762 
15763     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15764     changes in the JSON value.
15765 
15766     @complexity Logarithmic in the size of the container.
15767 
15768     @sa @ref operator[](const typename object_t::key_type&) for unchecked
15769     access by reference
15770     @sa @ref value() for access by value with a default value
15771 
15772     @since version 1.0.0
15773 
15774     @liveexample{The example below shows how object elements can be read and
15775     written using `at()`. It also demonstrates the different exceptions that
15776     can be thrown.,at__object_t_key_type}
15777     */
at(const typename object_t::key_type & key)15778     reference at(const typename object_t::key_type& key)
15779     {
15780         // at only works for objects
15781         if (JSON_LIKELY(is_object()))
15782         {
15783             JSON_TRY
15784             {
15785                 return m_value.object->at(key);
15786             }
15787             JSON_CATCH (std::out_of_range&)
15788             {
15789                 // create better exception explanation
15790                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
15791             }
15792         }
15793         else
15794         {
15795             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15796         }
15797     }
15798 
15799     /*!
15800     @brief access specified object element with bounds checking
15801 
15802     Returns a const reference to the element at with specified key @a key,
15803     with bounds checking.
15804 
15805     @param[in] key  key of the element to access
15806 
15807     @return const reference to the element at key @a key
15808 
15809     @throw type_error.304 if the JSON value is not an object; in this case,
15810     calling `at` with a key makes no sense. See example below.
15811     @throw out_of_range.403 if the key @a key is is not stored in the object;
15812     that is, `find(key) == end()`. See example below.
15813 
15814     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15815     changes in the JSON value.
15816 
15817     @complexity Logarithmic in the size of the container.
15818 
15819     @sa @ref operator[](const typename object_t::key_type&) for unchecked
15820     access by reference
15821     @sa @ref value() for access by value with a default value
15822 
15823     @since version 1.0.0
15824 
15825     @liveexample{The example below shows how object elements can be read using
15826     `at()`. It also demonstrates the different exceptions that can be thrown.,
15827     at__object_t_key_type_const}
15828     */
at(const typename object_t::key_type & key) const15829     const_reference at(const typename object_t::key_type& key) const
15830     {
15831         // at only works for objects
15832         if (JSON_LIKELY(is_object()))
15833         {
15834             JSON_TRY
15835             {
15836                 return m_value.object->at(key);
15837             }
15838             JSON_CATCH (std::out_of_range&)
15839             {
15840                 // create better exception explanation
15841                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
15842             }
15843         }
15844         else
15845         {
15846             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15847         }
15848     }
15849 
15850     /*!
15851     @brief access specified array element
15852 
15853     Returns a reference to the element at specified location @a idx.
15854 
15855     @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
15856     then the array is silently filled up with `null` values to make `idx` a
15857     valid reference to the last stored element.
15858 
15859     @param[in] idx  index of the element to access
15860 
15861     @return reference to the element at index @a idx
15862 
15863     @throw type_error.305 if the JSON value is not an array or null; in that
15864     cases, using the [] operator with an index makes no sense.
15865 
15866     @complexity Constant if @a idx is in the range of the array. Otherwise
15867     linear in `idx - size()`.
15868 
15869     @liveexample{The example below shows how array elements can be read and
15870     written using `[]` operator. Note the addition of `null`
15871     values.,operatorarray__size_type}
15872 
15873     @since version 1.0.0
15874     */
operator [](size_type idx)15875     reference operator[](size_type idx)
15876     {
15877         // implicitly convert null value to an empty array
15878         if (is_null())
15879         {
15880             m_type = value_t::array;
15881             m_value.array = create<array_t>();
15882             assert_invariant();
15883         }
15884 
15885         // operator[] only works for arrays
15886         if (JSON_LIKELY(is_array()))
15887         {
15888             // fill up array with null values if given idx is outside range
15889             if (idx >= m_value.array->size())
15890             {
15891                 m_value.array->insert(m_value.array->end(),
15892                                       idx - m_value.array->size() + 1,
15893                                       basic_json());
15894             }
15895 
15896             return m_value.array->operator[](idx);
15897         }
15898 
15899         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15900     }
15901 
15902     /*!
15903     @brief access specified array element
15904 
15905     Returns a const reference to the element at specified location @a idx.
15906 
15907     @param[in] idx  index of the element to access
15908 
15909     @return const reference to the element at index @a idx
15910 
15911     @throw type_error.305 if the JSON value is not an array; in that case,
15912     using the [] operator with an index makes no sense.
15913 
15914     @complexity Constant.
15915 
15916     @liveexample{The example below shows how array elements can be read using
15917     the `[]` operator.,operatorarray__size_type_const}
15918 
15919     @since version 1.0.0
15920     */
operator [](size_type idx) const15921     const_reference operator[](size_type idx) const
15922     {
15923         // const operator[] only works for arrays
15924         if (JSON_LIKELY(is_array()))
15925         {
15926             return m_value.array->operator[](idx);
15927         }
15928 
15929         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15930     }
15931 
15932     /*!
15933     @brief access specified object element
15934 
15935     Returns a reference to the element at with specified key @a key.
15936 
15937     @note If @a key is not found in the object, then it is silently added to
15938     the object and filled with a `null` value to make `key` a valid reference.
15939     In case the value was `null` before, it is converted to an object.
15940 
15941     @param[in] key  key of the element to access
15942 
15943     @return reference to the element at key @a key
15944 
15945     @throw type_error.305 if the JSON value is not an object or null; in that
15946     cases, using the [] operator with a key makes no sense.
15947 
15948     @complexity Logarithmic in the size of the container.
15949 
15950     @liveexample{The example below shows how object elements can be read and
15951     written using the `[]` operator.,operatorarray__key_type}
15952 
15953     @sa @ref at(const typename object_t::key_type&) for access by reference
15954     with range checking
15955     @sa @ref value() for access by value with a default value
15956 
15957     @since version 1.0.0
15958     */
operator [](const typename object_t::key_type & key)15959     reference operator[](const typename object_t::key_type& key)
15960     {
15961         // implicitly convert null value to an empty object
15962         if (is_null())
15963         {
15964             m_type = value_t::object;
15965             m_value.object = create<object_t>();
15966             assert_invariant();
15967         }
15968 
15969         // operator[] only works for objects
15970         if (JSON_LIKELY(is_object()))
15971         {
15972             return m_value.object->operator[](key);
15973         }
15974 
15975         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
15976     }
15977 
15978     /*!
15979     @brief read-only access specified object element
15980 
15981     Returns a const reference to the element at with specified key @a key. No
15982     bounds checking is performed.
15983 
15984     @warning If the element with key @a key does not exist, the behavior is
15985     undefined.
15986 
15987     @param[in] key  key of the element to access
15988 
15989     @return const reference to the element at key @a key
15990 
15991     @pre The element with key @a key must exist. **This precondition is
15992          enforced with an assertion.**
15993 
15994     @throw type_error.305 if the JSON value is not an object; in that case,
15995     using the [] operator with a key makes no sense.
15996 
15997     @complexity Logarithmic in the size of the container.
15998 
15999     @liveexample{The example below shows how object elements can be read using
16000     the `[]` operator.,operatorarray__key_type_const}
16001 
16002     @sa @ref at(const typename object_t::key_type&) for access by reference
16003     with range checking
16004     @sa @ref value() for access by value with a default value
16005 
16006     @since version 1.0.0
16007     */
operator [](const typename object_t::key_type & key) const16008     const_reference operator[](const typename object_t::key_type& key) const
16009     {
16010         // const operator[] only works for objects
16011         if (JSON_LIKELY(is_object()))
16012         {
16013             assert(m_value.object->find(key) != m_value.object->end());
16014             return m_value.object->find(key)->second;
16015         }
16016 
16017         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16018     }
16019 
16020     /*!
16021     @brief access specified object element
16022 
16023     Returns a reference to the element at with specified key @a key.
16024 
16025     @note If @a key is not found in the object, then it is silently added to
16026     the object and filled with a `null` value to make `key` a valid reference.
16027     In case the value was `null` before, it is converted to an object.
16028 
16029     @param[in] key  key of the element to access
16030 
16031     @return reference to the element at key @a key
16032 
16033     @throw type_error.305 if the JSON value is not an object or null; in that
16034     cases, using the [] operator with a key makes no sense.
16035 
16036     @complexity Logarithmic in the size of the container.
16037 
16038     @liveexample{The example below shows how object elements can be read and
16039     written using the `[]` operator.,operatorarray__key_type}
16040 
16041     @sa @ref at(const typename object_t::key_type&) for access by reference
16042     with range checking
16043     @sa @ref value() for access by value with a default value
16044 
16045     @since version 1.1.0
16046     */
16047     template<typename T>
operator [](T * key)16048     reference operator[](T* key)
16049     {
16050         // implicitly convert null to object
16051         if (is_null())
16052         {
16053             m_type = value_t::object;
16054             m_value = value_t::object;
16055             assert_invariant();
16056         }
16057 
16058         // at only works for objects
16059         if (JSON_LIKELY(is_object()))
16060         {
16061             return m_value.object->operator[](key);
16062         }
16063 
16064         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16065     }
16066 
16067     /*!
16068     @brief read-only access specified object element
16069 
16070     Returns a const reference to the element at with specified key @a key. No
16071     bounds checking is performed.
16072 
16073     @warning If the element with key @a key does not exist, the behavior is
16074     undefined.
16075 
16076     @param[in] key  key of the element to access
16077 
16078     @return const reference to the element at key @a key
16079 
16080     @pre The element with key @a key must exist. **This precondition is
16081          enforced with an assertion.**
16082 
16083     @throw type_error.305 if the JSON value is not an object; in that case,
16084     using the [] operator with a key makes no sense.
16085 
16086     @complexity Logarithmic in the size of the container.
16087 
16088     @liveexample{The example below shows how object elements can be read using
16089     the `[]` operator.,operatorarray__key_type_const}
16090 
16091     @sa @ref at(const typename object_t::key_type&) for access by reference
16092     with range checking
16093     @sa @ref value() for access by value with a default value
16094 
16095     @since version 1.1.0
16096     */
16097     template<typename T>
operator [](T * key) const16098     const_reference operator[](T* key) const
16099     {
16100         // at only works for objects
16101         if (JSON_LIKELY(is_object()))
16102         {
16103             assert(m_value.object->find(key) != m_value.object->end());
16104             return m_value.object->find(key)->second;
16105         }
16106 
16107         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16108     }
16109 
16110     /*!
16111     @brief access specified object element with default value
16112 
16113     Returns either a copy of an object's element at the specified key @a key
16114     or a given default value if no element with key @a key exists.
16115 
16116     The function is basically equivalent to executing
16117     @code {.cpp}
16118     try {
16119         return at(key);
16120     } catch(out_of_range) {
16121         return default_value;
16122     }
16123     @endcode
16124 
16125     @note Unlike @ref at(const typename object_t::key_type&), this function
16126     does not throw if the given key @a key was not found.
16127 
16128     @note Unlike @ref operator[](const typename object_t::key_type& key), this
16129     function does not implicitly add an element to the position defined by @a
16130     key. This function is furthermore also applicable to const objects.
16131 
16132     @param[in] key  key of the element to access
16133     @param[in] default_value  the value to return if @a key is not found
16134 
16135     @tparam ValueType type compatible to JSON values, for instance `int` for
16136     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
16137     JSON arrays. Note the type of the expected value at @a key and the default
16138     value @a default_value must be compatible.
16139 
16140     @return copy of the element at key @a key or @a default_value if @a key
16141     is not found
16142 
16143     @throw type_error.306 if the JSON value is not an object; in that case,
16144     using `value()` with a key makes no sense.
16145 
16146     @complexity Logarithmic in the size of the container.
16147 
16148     @liveexample{The example below shows how object elements can be queried
16149     with a default value.,basic_json__value}
16150 
16151     @sa @ref at(const typename object_t::key_type&) for access by reference
16152     with range checking
16153     @sa @ref operator[](const typename object_t::key_type&) for unchecked
16154     access by reference
16155 
16156     @since version 1.0.0
16157     */
16158     template<class ValueType, typename std::enable_if<
16159                  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
16160     ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
16161     {
16162         // at only works for objects
16163         if (JSON_LIKELY(is_object()))
16164         {
16165             // if key is found, return value and given default value otherwise
16166             const auto it = find(key);
16167             if (it != end())
16168             {
16169                 return *it;
16170             }
16171 
16172             return default_value;
16173         }
16174 
16175         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
16176     }
16177 
16178     /*!
16179     @brief overload for a default value of type const char*
16180     @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
16181     */
value(const typename object_t::key_type & key,const char * default_value) const16182     string_t value(const typename object_t::key_type& key, const char* default_value) const
16183     {
16184         return value(key, string_t(default_value));
16185     }
16186 
16187     /*!
16188     @brief access specified object element via JSON Pointer with default value
16189 
16190     Returns either a copy of an object's element at the specified key @a key
16191     or a given default value if no element with key @a key exists.
16192 
16193     The function is basically equivalent to executing
16194     @code {.cpp}
16195     try {
16196         return at(ptr);
16197     } catch(out_of_range) {
16198         return default_value;
16199     }
16200     @endcode
16201 
16202     @note Unlike @ref at(const json_pointer&), this function does not throw
16203     if the given key @a key was not found.
16204 
16205     @param[in] ptr  a JSON pointer to the element to access
16206     @param[in] default_value  the value to return if @a ptr found no value
16207 
16208     @tparam ValueType type compatible to JSON values, for instance `int` for
16209     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
16210     JSON arrays. Note the type of the expected value at @a key and the default
16211     value @a default_value must be compatible.
16212 
16213     @return copy of the element at key @a key or @a default_value if @a key
16214     is not found
16215 
16216     @throw type_error.306 if the JSON value is not an object; in that case,
16217     using `value()` with a key makes no sense.
16218 
16219     @complexity Logarithmic in the size of the container.
16220 
16221     @liveexample{The example below shows how object elements can be queried
16222     with a default value.,basic_json__value_ptr}
16223 
16224     @sa @ref operator[](const json_pointer&) for unchecked access by reference
16225 
16226     @since version 2.0.2
16227     */
16228     template<class ValueType, typename std::enable_if<
16229                  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
16230     ValueType value(const json_pointer& ptr, const ValueType& default_value) const
16231     {
16232         // at only works for objects
16233         if (JSON_LIKELY(is_object()))
16234         {
16235             // if pointer resolves a value, return it or use default value
16236             JSON_TRY
16237             {
16238                 return ptr.get_checked(this);
16239             }
16240             JSON_INTERNAL_CATCH (out_of_range&)
16241             {
16242                 return default_value;
16243             }
16244         }
16245 
16246         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
16247     }
16248 
16249     /*!
16250     @brief overload for a default value of type const char*
16251     @copydoc basic_json::value(const json_pointer&, ValueType) const
16252     */
value(const json_pointer & ptr,const char * default_value) const16253     string_t value(const json_pointer& ptr, const char* default_value) const
16254     {
16255         return value(ptr, string_t(default_value));
16256     }
16257 
16258     /*!
16259     @brief access the first element
16260 
16261     Returns a reference to the first element in the container. For a JSON
16262     container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
16263 
16264     @return In case of a structured type (array or object), a reference to the
16265     first element is returned. In case of number, string, or boolean values, a
16266     reference to the value is returned.
16267 
16268     @complexity Constant.
16269 
16270     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
16271     or an empty array or object (undefined behavior, **guarded by
16272     assertions**).
16273     @post The JSON value remains unchanged.
16274 
16275     @throw invalid_iterator.214 when called on `null` value
16276 
16277     @liveexample{The following code shows an example for `front()`.,front}
16278 
16279     @sa @ref back() -- access the last element
16280 
16281     @since version 1.0.0
16282     */
front()16283     reference front()
16284     {
16285         return *begin();
16286     }
16287 
16288     /*!
16289     @copydoc basic_json::front()
16290     */
front() const16291     const_reference front() const
16292     {
16293         return *cbegin();
16294     }
16295 
16296     /*!
16297     @brief access the last element
16298 
16299     Returns a reference to the last element in the container. For a JSON
16300     container `c`, the expression `c.back()` is equivalent to
16301     @code {.cpp}
16302     auto tmp = c.end();
16303     --tmp;
16304     return *tmp;
16305     @endcode
16306 
16307     @return In case of a structured type (array or object), a reference to the
16308     last element is returned. In case of number, string, or boolean values, a
16309     reference to the value is returned.
16310 
16311     @complexity Constant.
16312 
16313     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
16314     or an empty array or object (undefined behavior, **guarded by
16315     assertions**).
16316     @post The JSON value remains unchanged.
16317 
16318     @throw invalid_iterator.214 when called on a `null` value. See example
16319     below.
16320 
16321     @liveexample{The following code shows an example for `back()`.,back}
16322 
16323     @sa @ref front() -- access the first element
16324 
16325     @since version 1.0.0
16326     */
back()16327     reference back()
16328     {
16329         auto tmp = end();
16330         --tmp;
16331         return *tmp;
16332     }
16333 
16334     /*!
16335     @copydoc basic_json::back()
16336     */
back() const16337     const_reference back() const
16338     {
16339         auto tmp = cend();
16340         --tmp;
16341         return *tmp;
16342     }
16343 
16344     /*!
16345     @brief remove element given an iterator
16346 
16347     Removes the element specified by iterator @a pos. The iterator @a pos must
16348     be valid and dereferenceable. Thus the `end()` iterator (which is valid,
16349     but is not dereferenceable) cannot be used as a value for @a pos.
16350 
16351     If called on a primitive type other than `null`, the resulting JSON value
16352     will be `null`.
16353 
16354     @param[in] pos iterator to the element to remove
16355     @return Iterator following the last removed element. If the iterator @a
16356     pos refers to the last element, the `end()` iterator is returned.
16357 
16358     @tparam IteratorType an @ref iterator or @ref const_iterator
16359 
16360     @post Invalidates iterators and references at or after the point of the
16361     erase, including the `end()` iterator.
16362 
16363     @throw type_error.307 if called on a `null` value; example: `"cannot use
16364     erase() with null"`
16365     @throw invalid_iterator.202 if called on an iterator which does not belong
16366     to the current JSON value; example: `"iterator does not fit current
16367     value"`
16368     @throw invalid_iterator.205 if called on a primitive type with invalid
16369     iterator (i.e., any iterator which is not `begin()`); example: `"iterator
16370     out of range"`
16371 
16372     @complexity The complexity depends on the type:
16373     - objects: amortized constant
16374     - arrays: linear in distance between @a pos and the end of the container
16375     - strings: linear in the length of the string
16376     - other types: constant
16377 
16378     @liveexample{The example shows the result of `erase()` for different JSON
16379     types.,erase__IteratorType}
16380 
16381     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16382     the given range
16383     @sa @ref erase(const typename object_t::key_type&) -- removes the element
16384     from an object at the given key
16385     @sa @ref erase(const size_type) -- removes the element from an array at
16386     the given index
16387 
16388     @since version 1.0.0
16389     */
16390     template<class IteratorType, typename std::enable_if<
16391                  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16392                  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
16393              = 0>
16394     IteratorType erase(IteratorType pos)
16395     {
16396         // make sure iterator fits the current value
16397         if (JSON_UNLIKELY(this != pos.m_object))
16398         {
16399             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16400         }
16401 
16402         IteratorType result = end();
16403 
16404         switch (m_type)
16405         {
16406             case value_t::boolean:
16407             case value_t::number_float:
16408             case value_t::number_integer:
16409             case value_t::number_unsigned:
16410             case value_t::string:
16411             {
16412                 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
16413                 {
16414                     JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
16415                 }
16416 
16417                 if (is_string())
16418                 {
16419                     AllocatorType<string_t> alloc;
16420                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16421                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16422                     m_value.string = nullptr;
16423                 }
16424 
16425                 m_type = value_t::null;
16426                 assert_invariant();
16427                 break;
16428             }
16429 
16430             case value_t::object:
16431             {
16432                 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
16433                 break;
16434             }
16435 
16436             case value_t::array:
16437             {
16438                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
16439                 break;
16440             }
16441 
16442             default:
16443                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16444         }
16445 
16446         return result;
16447     }
16448 
16449     /*!
16450     @brief remove elements given an iterator range
16451 
16452     Removes the element specified by the range `[first; last)`. The iterator
16453     @a first does not need to be dereferenceable if `first == last`: erasing
16454     an empty range is a no-op.
16455 
16456     If called on a primitive type other than `null`, the resulting JSON value
16457     will be `null`.
16458 
16459     @param[in] first iterator to the beginning of the range to remove
16460     @param[in] last iterator past the end of the range to remove
16461     @return Iterator following the last removed element. If the iterator @a
16462     second refers to the last element, the `end()` iterator is returned.
16463 
16464     @tparam IteratorType an @ref iterator or @ref const_iterator
16465 
16466     @post Invalidates iterators and references at or after the point of the
16467     erase, including the `end()` iterator.
16468 
16469     @throw type_error.307 if called on a `null` value; example: `"cannot use
16470     erase() with null"`
16471     @throw invalid_iterator.203 if called on iterators which does not belong
16472     to the current JSON value; example: `"iterators do not fit current value"`
16473     @throw invalid_iterator.204 if called on a primitive type with invalid
16474     iterators (i.e., if `first != begin()` and `last != end()`); example:
16475     `"iterators out of range"`
16476 
16477     @complexity The complexity depends on the type:
16478     - objects: `log(size()) + std::distance(first, last)`
16479     - arrays: linear in the distance between @a first and @a last, plus linear
16480       in the distance between @a last and end of the container
16481     - strings: linear in the length of the string
16482     - other types: constant
16483 
16484     @liveexample{The example shows the result of `erase()` for different JSON
16485     types.,erase__IteratorType_IteratorType}
16486 
16487     @sa @ref erase(IteratorType) -- removes the element at a given position
16488     @sa @ref erase(const typename object_t::key_type&) -- removes the element
16489     from an object at the given key
16490     @sa @ref erase(const size_type) -- removes the element from an array at
16491     the given index
16492 
16493     @since version 1.0.0
16494     */
16495     template<class IteratorType, typename std::enable_if<
16496                  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16497                  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
16498              = 0>
16499     IteratorType erase(IteratorType first, IteratorType last)
16500     {
16501         // make sure iterator fits the current value
16502         if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
16503         {
16504             JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
16505         }
16506 
16507         IteratorType result = end();
16508 
16509         switch (m_type)
16510         {
16511             case value_t::boolean:
16512             case value_t::number_float:
16513             case value_t::number_integer:
16514             case value_t::number_unsigned:
16515             case value_t::string:
16516             {
16517                 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
16518                                 or not last.m_it.primitive_iterator.is_end()))
16519                 {
16520                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
16521                 }
16522 
16523                 if (is_string())
16524                 {
16525                     AllocatorType<string_t> alloc;
16526                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16527                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16528                     m_value.string = nullptr;
16529                 }
16530 
16531                 m_type = value_t::null;
16532                 assert_invariant();
16533                 break;
16534             }
16535 
16536             case value_t::object:
16537             {
16538                 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
16539                                               last.m_it.object_iterator);
16540                 break;
16541             }
16542 
16543             case value_t::array:
16544             {
16545                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
16546                                              last.m_it.array_iterator);
16547                 break;
16548             }
16549 
16550             default:
16551                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16552         }
16553 
16554         return result;
16555     }
16556 
16557     /*!
16558     @brief remove element from a JSON object given a key
16559 
16560     Removes elements from a JSON object with the key value @a key.
16561 
16562     @param[in] key value of the elements to remove
16563 
16564     @return Number of elements removed. If @a ObjectType is the default
16565     `std::map` type, the return value will always be `0` (@a key was not
16566     found) or `1` (@a key was found).
16567 
16568     @post References and iterators to the erased elements are invalidated.
16569     Other references and iterators are not affected.
16570 
16571     @throw type_error.307 when called on a type other than JSON object;
16572     example: `"cannot use erase() with null"`
16573 
16574     @complexity `log(size()) + count(key)`
16575 
16576     @liveexample{The example shows the effect of `erase()`.,erase__key_type}
16577 
16578     @sa @ref erase(IteratorType) -- removes the element at a given position
16579     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16580     the given range
16581     @sa @ref erase(const size_type) -- removes the element from an array at
16582     the given index
16583 
16584     @since version 1.0.0
16585     */
erase(const typename object_t::key_type & key)16586     size_type erase(const typename object_t::key_type& key)
16587     {
16588         // this erase only works for objects
16589         if (JSON_LIKELY(is_object()))
16590         {
16591             return m_value.object->erase(key);
16592         }
16593 
16594         JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16595     }
16596 
16597     /*!
16598     @brief remove element from a JSON array given an index
16599 
16600     Removes element from a JSON array at the index @a idx.
16601 
16602     @param[in] idx index of the element to remove
16603 
16604     @throw type_error.307 when called on a type other than JSON object;
16605     example: `"cannot use erase() with null"`
16606     @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
16607     is out of range"`
16608 
16609     @complexity Linear in distance between @a idx and the end of the container.
16610 
16611     @liveexample{The example shows the effect of `erase()`.,erase__size_type}
16612 
16613     @sa @ref erase(IteratorType) -- removes the element at a given position
16614     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16615     the given range
16616     @sa @ref erase(const typename object_t::key_type&) -- removes the element
16617     from an object at the given key
16618 
16619     @since version 1.0.0
16620     */
erase(const size_type idx)16621     void erase(const size_type idx)
16622     {
16623         // this erase only works for arrays
16624         if (JSON_LIKELY(is_array()))
16625         {
16626             if (JSON_UNLIKELY(idx >= size()))
16627             {
16628                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
16629             }
16630 
16631             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
16632         }
16633         else
16634         {
16635             JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16636         }
16637     }
16638 
16639     /// @}
16640 
16641 
16642     ////////////
16643     // lookup //
16644     ////////////
16645 
16646     /// @name lookup
16647     /// @{
16648 
16649     /*!
16650     @brief find an element in a JSON object
16651 
16652     Finds an element in a JSON object with key equivalent to @a key. If the
16653     element is not found or the JSON value is not an object, end() is
16654     returned.
16655 
16656     @note This method always returns @ref end() when executed on a JSON type
16657           that is not an object.
16658 
16659     @param[in] key key value of the element to search for.
16660 
16661     @return Iterator to an element with key equivalent to @a key. If no such
16662     element is found or the JSON value is not an object, past-the-end (see
16663     @ref end()) iterator is returned.
16664 
16665     @complexity Logarithmic in the size of the JSON object.
16666 
16667     @liveexample{The example shows how `find()` is used.,find__key_type}
16668 
16669     @sa @ref contains(KeyT&&) const -- checks whether a key exists
16670 
16671     @since version 1.0.0
16672     */
16673     template<typename KeyT>
find(KeyT && key)16674     iterator find(KeyT&& key)
16675     {
16676         auto result = end();
16677 
16678         if (is_object())
16679         {
16680             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16681         }
16682 
16683         return result;
16684     }
16685 
16686     /*!
16687     @brief find an element in a JSON object
16688     @copydoc find(KeyT&&)
16689     */
16690     template<typename KeyT>
find(KeyT && key) const16691     const_iterator find(KeyT&& key) const
16692     {
16693         auto result = cend();
16694 
16695         if (is_object())
16696         {
16697             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16698         }
16699 
16700         return result;
16701     }
16702 
16703     /*!
16704     @brief returns the number of occurrences of a key in a JSON object
16705 
16706     Returns the number of elements with key @a key. If ObjectType is the
16707     default `std::map` type, the return value will always be `0` (@a key was
16708     not found) or `1` (@a key was found).
16709 
16710     @note This method always returns `0` when executed on a JSON type that is
16711           not an object.
16712 
16713     @param[in] key key value of the element to count
16714 
16715     @return Number of elements with key @a key. If the JSON value is not an
16716     object, the return value will be `0`.
16717 
16718     @complexity Logarithmic in the size of the JSON object.
16719 
16720     @liveexample{The example shows how `count()` is used.,count}
16721 
16722     @since version 1.0.0
16723     */
16724     template<typename KeyT>
count(KeyT && key) const16725     size_type count(KeyT&& key) const
16726     {
16727         // return 0 for all nonobject types
16728         return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
16729     }
16730 
16731     /*!
16732     @brief check the existence of an element in a JSON object
16733 
16734     Check whether an element exists in a JSON object with key equivalent to
16735     @a key. If the element is not found or the JSON value is not an object,
16736     false is returned.
16737 
16738     @note This method always returns false when executed on a JSON type
16739           that is not an object.
16740 
16741     @param[in] key key value to check its existence.
16742 
16743     @return true if an element with specified @a key exists. If no such
16744     element with such key is found or the JSON value is not an object,
16745     false is returned.
16746 
16747     @complexity Logarithmic in the size of the JSON object.
16748 
16749     @liveexample{The following code shows an example for `contains()`.,contains}
16750 
16751     @sa @ref find(KeyT&&) -- returns an iterator to an object element
16752 
16753     @since version 3.6.0
16754     */
16755     template<typename KeyT>
contains(KeyT && key) const16756     bool contains(KeyT&& key) const
16757     {
16758         return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
16759     }
16760 
16761     /// @}
16762 
16763 
16764     ///////////////
16765     // iterators //
16766     ///////////////
16767 
16768     /// @name iterators
16769     /// @{
16770 
16771     /*!
16772     @brief returns an iterator to the first element
16773 
16774     Returns an iterator to the first element.
16775 
16776     @image html range-begin-end.svg "Illustration from cppreference.com"
16777 
16778     @return iterator to the first element
16779 
16780     @complexity Constant.
16781 
16782     @requirement This function helps `basic_json` satisfying the
16783     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16784     requirements:
16785     - The complexity is constant.
16786 
16787     @liveexample{The following code shows an example for `begin()`.,begin}
16788 
16789     @sa @ref cbegin() -- returns a const iterator to the beginning
16790     @sa @ref end() -- returns an iterator to the end
16791     @sa @ref cend() -- returns a const iterator to the end
16792 
16793     @since version 1.0.0
16794     */
begin()16795     iterator begin() noexcept
16796     {
16797         iterator result(this);
16798         result.set_begin();
16799         return result;
16800     }
16801 
16802     /*!
16803     @copydoc basic_json::cbegin()
16804     */
begin() const16805     const_iterator begin() const noexcept
16806     {
16807         return cbegin();
16808     }
16809 
16810     /*!
16811     @brief returns a const iterator to the first element
16812 
16813     Returns a const iterator to the first element.
16814 
16815     @image html range-begin-end.svg "Illustration from cppreference.com"
16816 
16817     @return const iterator to the first element
16818 
16819     @complexity Constant.
16820 
16821     @requirement This function helps `basic_json` satisfying the
16822     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16823     requirements:
16824     - The complexity is constant.
16825     - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
16826 
16827     @liveexample{The following code shows an example for `cbegin()`.,cbegin}
16828 
16829     @sa @ref begin() -- returns an iterator to the beginning
16830     @sa @ref end() -- returns an iterator to the end
16831     @sa @ref cend() -- returns a const iterator to the end
16832 
16833     @since version 1.0.0
16834     */
cbegin() const16835     const_iterator cbegin() const noexcept
16836     {
16837         const_iterator result(this);
16838         result.set_begin();
16839         return result;
16840     }
16841 
16842     /*!
16843     @brief returns an iterator to one past the last element
16844 
16845     Returns an iterator to one past the last element.
16846 
16847     @image html range-begin-end.svg "Illustration from cppreference.com"
16848 
16849     @return iterator one past the last element
16850 
16851     @complexity Constant.
16852 
16853     @requirement This function helps `basic_json` satisfying the
16854     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16855     requirements:
16856     - The complexity is constant.
16857 
16858     @liveexample{The following code shows an example for `end()`.,end}
16859 
16860     @sa @ref cend() -- returns a const iterator to the end
16861     @sa @ref begin() -- returns an iterator to the beginning
16862     @sa @ref cbegin() -- returns a const iterator to the beginning
16863 
16864     @since version 1.0.0
16865     */
end()16866     iterator end() noexcept
16867     {
16868         iterator result(this);
16869         result.set_end();
16870         return result;
16871     }
16872 
16873     /*!
16874     @copydoc basic_json::cend()
16875     */
end() const16876     const_iterator end() const noexcept
16877     {
16878         return cend();
16879     }
16880 
16881     /*!
16882     @brief returns a const iterator to one past the last element
16883 
16884     Returns a const iterator to one past the last element.
16885 
16886     @image html range-begin-end.svg "Illustration from cppreference.com"
16887 
16888     @return const iterator one past the last element
16889 
16890     @complexity Constant.
16891 
16892     @requirement This function helps `basic_json` satisfying the
16893     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16894     requirements:
16895     - The complexity is constant.
16896     - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
16897 
16898     @liveexample{The following code shows an example for `cend()`.,cend}
16899 
16900     @sa @ref end() -- returns an iterator to the end
16901     @sa @ref begin() -- returns an iterator to the beginning
16902     @sa @ref cbegin() -- returns a const iterator to the beginning
16903 
16904     @since version 1.0.0
16905     */
cend() const16906     const_iterator cend() const noexcept
16907     {
16908         const_iterator result(this);
16909         result.set_end();
16910         return result;
16911     }
16912 
16913     /*!
16914     @brief returns an iterator to the reverse-beginning
16915 
16916     Returns an iterator to the reverse-beginning; that is, the last element.
16917 
16918     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
16919 
16920     @complexity Constant.
16921 
16922     @requirement This function helps `basic_json` satisfying the
16923     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
16924     requirements:
16925     - The complexity is constant.
16926     - Has the semantics of `reverse_iterator(end())`.
16927 
16928     @liveexample{The following code shows an example for `rbegin()`.,rbegin}
16929 
16930     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
16931     @sa @ref rend() -- returns a reverse iterator to the end
16932     @sa @ref crend() -- returns a const reverse iterator to the end
16933 
16934     @since version 1.0.0
16935     */
rbegin()16936     reverse_iterator rbegin() noexcept
16937     {
16938         return reverse_iterator(end());
16939     }
16940 
16941     /*!
16942     @copydoc basic_json::crbegin()
16943     */
rbegin() const16944     const_reverse_iterator rbegin() const noexcept
16945     {
16946         return crbegin();
16947     }
16948 
16949     /*!
16950     @brief returns an iterator to the reverse-end
16951 
16952     Returns an iterator to the reverse-end; that is, one before the first
16953     element.
16954 
16955     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
16956 
16957     @complexity Constant.
16958 
16959     @requirement This function helps `basic_json` satisfying the
16960     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
16961     requirements:
16962     - The complexity is constant.
16963     - Has the semantics of `reverse_iterator(begin())`.
16964 
16965     @liveexample{The following code shows an example for `rend()`.,rend}
16966 
16967     @sa @ref crend() -- returns a const reverse iterator to the end
16968     @sa @ref rbegin() -- returns a reverse iterator to the beginning
16969     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
16970 
16971     @since version 1.0.0
16972     */
rend()16973     reverse_iterator rend() noexcept
16974     {
16975         return reverse_iterator(begin());
16976     }
16977 
16978     /*!
16979     @copydoc basic_json::crend()
16980     */
rend() const16981     const_reverse_iterator rend() const noexcept
16982     {
16983         return crend();
16984     }
16985 
16986     /*!
16987     @brief returns a const reverse iterator to the last element
16988 
16989     Returns a const iterator to the reverse-beginning; that is, the last
16990     element.
16991 
16992     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
16993 
16994     @complexity Constant.
16995 
16996     @requirement This function helps `basic_json` satisfying the
16997     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
16998     requirements:
16999     - The complexity is constant.
17000     - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
17001 
17002     @liveexample{The following code shows an example for `crbegin()`.,crbegin}
17003 
17004     @sa @ref rbegin() -- returns a reverse iterator to the beginning
17005     @sa @ref rend() -- returns a reverse iterator to the end
17006     @sa @ref crend() -- returns a const reverse iterator to the end
17007 
17008     @since version 1.0.0
17009     */
crbegin() const17010     const_reverse_iterator crbegin() const noexcept
17011     {
17012         return const_reverse_iterator(cend());
17013     }
17014 
17015     /*!
17016     @brief returns a const reverse iterator to one before the first
17017 
17018     Returns a const reverse iterator to the reverse-end; that is, one before
17019     the first element.
17020 
17021     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
17022 
17023     @complexity Constant.
17024 
17025     @requirement This function helps `basic_json` satisfying the
17026     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
17027     requirements:
17028     - The complexity is constant.
17029     - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
17030 
17031     @liveexample{The following code shows an example for `crend()`.,crend}
17032 
17033     @sa @ref rend() -- returns a reverse iterator to the end
17034     @sa @ref rbegin() -- returns a reverse iterator to the beginning
17035     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
17036 
17037     @since version 1.0.0
17038     */
crend() const17039     const_reverse_iterator crend() const noexcept
17040     {
17041         return const_reverse_iterator(cbegin());
17042     }
17043 
17044   public:
17045     /*!
17046     @brief wrapper to access iterator member functions in range-based for
17047 
17048     This function allows to access @ref iterator::key() and @ref
17049     iterator::value() during range-based for loops. In these loops, a
17050     reference to the JSON values is returned, so there is no access to the
17051     underlying iterator.
17052 
17053     For loop without iterator_wrapper:
17054 
17055     @code{cpp}
17056     for (auto it = j_object.begin(); it != j_object.end(); ++it)
17057     {
17058         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17059     }
17060     @endcode
17061 
17062     Range-based for loop without iterator proxy:
17063 
17064     @code{cpp}
17065     for (auto it : j_object)
17066     {
17067         // "it" is of type json::reference and has no key() member
17068         std::cout << "value: " << it << '\n';
17069     }
17070     @endcode
17071 
17072     Range-based for loop with iterator proxy:
17073 
17074     @code{cpp}
17075     for (auto it : json::iterator_wrapper(j_object))
17076     {
17077         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17078     }
17079     @endcode
17080 
17081     @note When iterating over an array, `key()` will return the index of the
17082           element as string (see example).
17083 
17084     @param[in] ref  reference to a JSON value
17085     @return iteration proxy object wrapping @a ref with an interface to use in
17086             range-based for loops
17087 
17088     @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
17089 
17090     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17091     changes in the JSON value.
17092 
17093     @complexity Constant.
17094 
17095     @note The name of this function is not yet final and may change in the
17096     future.
17097 
17098     @deprecated This stream operator is deprecated and will be removed in
17099                 future 4.0.0 of the library. Please use @ref items() instead;
17100                 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
17101     */
17102     JSON_DEPRECATED
iterator_wrapper(reference ref)17103     static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
17104     {
17105         return ref.items();
17106     }
17107 
17108     /*!
17109     @copydoc iterator_wrapper(reference)
17110     */
17111     JSON_DEPRECATED
iterator_wrapper(const_reference ref)17112     static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
17113     {
17114         return ref.items();
17115     }
17116 
17117     /*!
17118     @brief helper to access iterator member functions in range-based for
17119 
17120     This function allows to access @ref iterator::key() and @ref
17121     iterator::value() during range-based for loops. In these loops, a
17122     reference to the JSON values is returned, so there is no access to the
17123     underlying iterator.
17124 
17125     For loop without `items()` function:
17126 
17127     @code{cpp}
17128     for (auto it = j_object.begin(); it != j_object.end(); ++it)
17129     {
17130         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17131     }
17132     @endcode
17133 
17134     Range-based for loop without `items()` function:
17135 
17136     @code{cpp}
17137     for (auto it : j_object)
17138     {
17139         // "it" is of type json::reference and has no key() member
17140         std::cout << "value: " << it << '\n';
17141     }
17142     @endcode
17143 
17144     Range-based for loop with `items()` function:
17145 
17146     @code{cpp}
17147     for (auto& el : j_object.items())
17148     {
17149         std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
17150     }
17151     @endcode
17152 
17153     The `items()` function also allows to use
17154     [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
17155     (C++17):
17156 
17157     @code{cpp}
17158     for (auto& [key, val] : j_object.items())
17159     {
17160         std::cout << "key: " << key << ", value:" << val << '\n';
17161     }
17162     @endcode
17163 
17164     @note When iterating over an array, `key()` will return the index of the
17165           element as string (see example). For primitive types (e.g., numbers),
17166           `key()` returns an empty string.
17167 
17168     @return iteration proxy object wrapping @a ref with an interface to use in
17169             range-based for loops
17170 
17171     @liveexample{The following code shows how the function is used.,items}
17172 
17173     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17174     changes in the JSON value.
17175 
17176     @complexity Constant.
17177 
17178     @since version 3.1.0, structured bindings support since 3.5.0.
17179     */
items()17180     iteration_proxy<iterator> items() noexcept
17181     {
17182         return iteration_proxy<iterator>(*this);
17183     }
17184 
17185     /*!
17186     @copydoc items()
17187     */
items() const17188     iteration_proxy<const_iterator> items() const noexcept
17189     {
17190         return iteration_proxy<const_iterator>(*this);
17191     }
17192 
17193     /// @}
17194 
17195 
17196     //////////////
17197     // capacity //
17198     //////////////
17199 
17200     /// @name capacity
17201     /// @{
17202 
17203     /*!
17204     @brief checks whether the container is empty.
17205 
17206     Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
17207 
17208     @return The return value depends on the different types and is
17209             defined as follows:
17210             Value type  | return value
17211             ----------- | -------------
17212             null        | `true`
17213             boolean     | `false`
17214             string      | `false`
17215             number      | `false`
17216             object      | result of function `object_t::empty()`
17217             array       | result of function `array_t::empty()`
17218 
17219     @liveexample{The following code uses `empty()` to check if a JSON
17220     object contains any elements.,empty}
17221 
17222     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17223     the Container concept; that is, their `empty()` functions have constant
17224     complexity.
17225 
17226     @iterators No changes.
17227 
17228     @exceptionsafety No-throw guarantee: this function never throws exceptions.
17229 
17230     @note This function does not return whether a string stored as JSON value
17231     is empty - it returns whether the JSON container itself is empty which is
17232     false in the case of a string.
17233 
17234     @requirement This function helps `basic_json` satisfying the
17235     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17236     requirements:
17237     - The complexity is constant.
17238     - Has the semantics of `begin() == end()`.
17239 
17240     @sa @ref size() -- returns the number of elements
17241 
17242     @since version 1.0.0
17243     */
empty() const17244     bool empty() const noexcept
17245     {
17246         switch (m_type)
17247         {
17248             case value_t::null:
17249             {
17250                 // null values are empty
17251                 return true;
17252             }
17253 
17254             case value_t::array:
17255             {
17256                 // delegate call to array_t::empty()
17257                 return m_value.array->empty();
17258             }
17259 
17260             case value_t::object:
17261             {
17262                 // delegate call to object_t::empty()
17263                 return m_value.object->empty();
17264             }
17265 
17266             default:
17267             {
17268                 // all other types are nonempty
17269                 return false;
17270             }
17271         }
17272     }
17273 
17274     /*!
17275     @brief returns the number of elements
17276 
17277     Returns the number of elements in a JSON value.
17278 
17279     @return The return value depends on the different types and is
17280             defined as follows:
17281             Value type  | return value
17282             ----------- | -------------
17283             null        | `0`
17284             boolean     | `1`
17285             string      | `1`
17286             number      | `1`
17287             object      | result of function object_t::size()
17288             array       | result of function array_t::size()
17289 
17290     @liveexample{The following code calls `size()` on the different value
17291     types.,size}
17292 
17293     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17294     the Container concept; that is, their size() functions have constant
17295     complexity.
17296 
17297     @iterators No changes.
17298 
17299     @exceptionsafety No-throw guarantee: this function never throws exceptions.
17300 
17301     @note This function does not return the length of a string stored as JSON
17302     value - it returns the number of elements in the JSON value which is 1 in
17303     the case of a string.
17304 
17305     @requirement This function helps `basic_json` satisfying the
17306     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17307     requirements:
17308     - The complexity is constant.
17309     - Has the semantics of `std::distance(begin(), end())`.
17310 
17311     @sa @ref empty() -- checks whether the container is empty
17312     @sa @ref max_size() -- returns the maximal number of elements
17313 
17314     @since version 1.0.0
17315     */
size() const17316     size_type size() const noexcept
17317     {
17318         switch (m_type)
17319         {
17320             case value_t::null:
17321             {
17322                 // null values are empty
17323                 return 0;
17324             }
17325 
17326             case value_t::array:
17327             {
17328                 // delegate call to array_t::size()
17329                 return m_value.array->size();
17330             }
17331 
17332             case value_t::object:
17333             {
17334                 // delegate call to object_t::size()
17335                 return m_value.object->size();
17336             }
17337 
17338             default:
17339             {
17340                 // all other types have size 1
17341                 return 1;
17342             }
17343         }
17344     }
17345 
17346     /*!
17347     @brief returns the maximum possible number of elements
17348 
17349     Returns the maximum number of elements a JSON value is able to hold due to
17350     system or library implementation limitations, i.e. `std::distance(begin(),
17351     end())` for the JSON value.
17352 
17353     @return The return value depends on the different types and is
17354             defined as follows:
17355             Value type  | return value
17356             ----------- | -------------
17357             null        | `0` (same as `size()`)
17358             boolean     | `1` (same as `size()`)
17359             string      | `1` (same as `size()`)
17360             number      | `1` (same as `size()`)
17361             object      | result of function `object_t::max_size()`
17362             array       | result of function `array_t::max_size()`
17363 
17364     @liveexample{The following code calls `max_size()` on the different value
17365     types. Note the output is implementation specific.,max_size}
17366 
17367     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17368     the Container concept; that is, their `max_size()` functions have constant
17369     complexity.
17370 
17371     @iterators No changes.
17372 
17373     @exceptionsafety No-throw guarantee: this function never throws exceptions.
17374 
17375     @requirement This function helps `basic_json` satisfying the
17376     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17377     requirements:
17378     - The complexity is constant.
17379     - Has the semantics of returning `b.size()` where `b` is the largest
17380       possible JSON value.
17381 
17382     @sa @ref size() -- returns the number of elements
17383 
17384     @since version 1.0.0
17385     */
max_size() const17386     size_type max_size() const noexcept
17387     {
17388         switch (m_type)
17389         {
17390             case value_t::array:
17391             {
17392                 // delegate call to array_t::max_size()
17393                 return m_value.array->max_size();
17394             }
17395 
17396             case value_t::object:
17397             {
17398                 // delegate call to object_t::max_size()
17399                 return m_value.object->max_size();
17400             }
17401 
17402             default:
17403             {
17404                 // all other types have max_size() == size()
17405                 return size();
17406             }
17407         }
17408     }
17409 
17410     /// @}
17411 
17412 
17413     ///////////////
17414     // modifiers //
17415     ///////////////
17416 
17417     /// @name modifiers
17418     /// @{
17419 
17420     /*!
17421     @brief clears the contents
17422 
17423     Clears the content of a JSON value and resets it to the default value as
17424     if @ref basic_json(value_t) would have been called with the current value
17425     type from @ref type():
17426 
17427     Value type  | initial value
17428     ----------- | -------------
17429     null        | `null`
17430     boolean     | `false`
17431     string      | `""`
17432     number      | `0`
17433     object      | `{}`
17434     array       | `[]`
17435 
17436     @post Has the same effect as calling
17437     @code {.cpp}
17438     *this = basic_json(type());
17439     @endcode
17440 
17441     @liveexample{The example below shows the effect of `clear()` to different
17442     JSON types.,clear}
17443 
17444     @complexity Linear in the size of the JSON value.
17445 
17446     @iterators All iterators, pointers and references related to this container
17447                are invalidated.
17448 
17449     @exceptionsafety No-throw guarantee: this function never throws exceptions.
17450 
17451     @sa @ref basic_json(value_t) -- constructor that creates an object with the
17452         same value than calling `clear()`
17453 
17454     @since version 1.0.0
17455     */
clear()17456     void clear() noexcept
17457     {
17458         switch (m_type)
17459         {
17460             case value_t::number_integer:
17461             {
17462                 m_value.number_integer = 0;
17463                 break;
17464             }
17465 
17466             case value_t::number_unsigned:
17467             {
17468                 m_value.number_unsigned = 0;
17469                 break;
17470             }
17471 
17472             case value_t::number_float:
17473             {
17474                 m_value.number_float = 0.0;
17475                 break;
17476             }
17477 
17478             case value_t::boolean:
17479             {
17480                 m_value.boolean = false;
17481                 break;
17482             }
17483 
17484             case value_t::string:
17485             {
17486                 m_value.string->clear();
17487                 break;
17488             }
17489 
17490             case value_t::array:
17491             {
17492                 m_value.array->clear();
17493                 break;
17494             }
17495 
17496             case value_t::object:
17497             {
17498                 m_value.object->clear();
17499                 break;
17500             }
17501 
17502             default:
17503                 break;
17504         }
17505     }
17506 
17507     /*!
17508     @brief add an object to an array
17509 
17510     Appends the given element @a val to the end of the JSON value. If the
17511     function is called on a JSON null value, an empty array is created before
17512     appending @a val.
17513 
17514     @param[in] val the value to add to the JSON array
17515 
17516     @throw type_error.308 when called on a type other than JSON array or
17517     null; example: `"cannot use push_back() with number"`
17518 
17519     @complexity Amortized constant.
17520 
17521     @liveexample{The example shows how `push_back()` and `+=` can be used to
17522     add elements to a JSON array. Note how the `null` value was silently
17523     converted to a JSON array.,push_back}
17524 
17525     @since version 1.0.0
17526     */
push_back(basic_json && val)17527     void push_back(basic_json&& val)
17528     {
17529         // push_back only works for null objects or arrays
17530         if (JSON_UNLIKELY(not(is_null() or is_array())))
17531         {
17532             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17533         }
17534 
17535         // transform null object into an array
17536         if (is_null())
17537         {
17538             m_type = value_t::array;
17539             m_value = value_t::array;
17540             assert_invariant();
17541         }
17542 
17543         // add element to array (move semantics)
17544         m_value.array->push_back(std::move(val));
17545         // invalidate object: mark it null so we do not call the destructor
17546         // cppcheck-suppress accessMoved
17547         val.m_type = value_t::null;
17548     }
17549 
17550     /*!
17551     @brief add an object to an array
17552     @copydoc push_back(basic_json&&)
17553     */
operator +=(basic_json && val)17554     reference operator+=(basic_json&& val)
17555     {
17556         push_back(std::move(val));
17557         return *this;
17558     }
17559 
17560     /*!
17561     @brief add an object to an array
17562     @copydoc push_back(basic_json&&)
17563     */
push_back(const basic_json & val)17564     void push_back(const basic_json& val)
17565     {
17566         // push_back only works for null objects or arrays
17567         if (JSON_UNLIKELY(not(is_null() or is_array())))
17568         {
17569             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17570         }
17571 
17572         // transform null object into an array
17573         if (is_null())
17574         {
17575             m_type = value_t::array;
17576             m_value = value_t::array;
17577             assert_invariant();
17578         }
17579 
17580         // add element to array
17581         m_value.array->push_back(val);
17582     }
17583 
17584     /*!
17585     @brief add an object to an array
17586     @copydoc push_back(basic_json&&)
17587     */
operator +=(const basic_json & val)17588     reference operator+=(const basic_json& val)
17589     {
17590         push_back(val);
17591         return *this;
17592     }
17593 
17594     /*!
17595     @brief add an object to an object
17596 
17597     Inserts the given element @a val to the JSON object. If the function is
17598     called on a JSON null value, an empty object is created before inserting
17599     @a val.
17600 
17601     @param[in] val the value to add to the JSON object
17602 
17603     @throw type_error.308 when called on a type other than JSON object or
17604     null; example: `"cannot use push_back() with number"`
17605 
17606     @complexity Logarithmic in the size of the container, O(log(`size()`)).
17607 
17608     @liveexample{The example shows how `push_back()` and `+=` can be used to
17609     add elements to a JSON object. Note how the `null` value was silently
17610     converted to a JSON object.,push_back__object_t__value}
17611 
17612     @since version 1.0.0
17613     */
push_back(const typename object_t::value_type & val)17614     void push_back(const typename object_t::value_type& val)
17615     {
17616         // push_back only works for null objects or objects
17617         if (JSON_UNLIKELY(not(is_null() or is_object())))
17618         {
17619             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17620         }
17621 
17622         // transform null object into an object
17623         if (is_null())
17624         {
17625             m_type = value_t::object;
17626             m_value = value_t::object;
17627             assert_invariant();
17628         }
17629 
17630         // add element to array
17631         m_value.object->insert(val);
17632     }
17633 
17634     /*!
17635     @brief add an object to an object
17636     @copydoc push_back(const typename object_t::value_type&)
17637     */
operator +=(const typename object_t::value_type & val)17638     reference operator+=(const typename object_t::value_type& val)
17639     {
17640         push_back(val);
17641         return *this;
17642     }
17643 
17644     /*!
17645     @brief add an object to an object
17646 
17647     This function allows to use `push_back` with an initializer list. In case
17648 
17649     1. the current value is an object,
17650     2. the initializer list @a init contains only two elements, and
17651     3. the first element of @a init is a string,
17652 
17653     @a init is converted into an object element and added using
17654     @ref push_back(const typename object_t::value_type&). Otherwise, @a init
17655     is converted to a JSON value and added using @ref push_back(basic_json&&).
17656 
17657     @param[in] init  an initializer list
17658 
17659     @complexity Linear in the size of the initializer list @a init.
17660 
17661     @note This function is required to resolve an ambiguous overload error,
17662           because pairs like `{"key", "value"}` can be both interpreted as
17663           `object_t::value_type` or `std::initializer_list<basic_json>`, see
17664           https://github.com/nlohmann/json/issues/235 for more information.
17665 
17666     @liveexample{The example shows how initializer lists are treated as
17667     objects when possible.,push_back__initializer_list}
17668     */
push_back(initializer_list_t init)17669     void push_back(initializer_list_t init)
17670     {
17671         if (is_object() and init.size() == 2 and (*init.begin())->is_string())
17672         {
17673             basic_json&& key = init.begin()->moved_or_copied();
17674             push_back(typename object_t::value_type(
17675                           std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
17676         }
17677         else
17678         {
17679             push_back(basic_json(init));
17680         }
17681     }
17682 
17683     /*!
17684     @brief add an object to an object
17685     @copydoc push_back(initializer_list_t)
17686     */
operator +=(initializer_list_t init)17687     reference operator+=(initializer_list_t init)
17688     {
17689         push_back(init);
17690         return *this;
17691     }
17692 
17693     /*!
17694     @brief add an object to an array
17695 
17696     Creates a JSON value from the passed parameters @a args to the end of the
17697     JSON value. If the function is called on a JSON null value, an empty array
17698     is created before appending the value created from @a args.
17699 
17700     @param[in] args arguments to forward to a constructor of @ref basic_json
17701     @tparam Args compatible types to create a @ref basic_json object
17702 
17703     @throw type_error.311 when called on a type other than JSON array or
17704     null; example: `"cannot use emplace_back() with number"`
17705 
17706     @complexity Amortized constant.
17707 
17708     @liveexample{The example shows how `push_back()` can be used to add
17709     elements to a JSON array. Note how the `null` value was silently converted
17710     to a JSON array.,emplace_back}
17711 
17712     @since version 2.0.8
17713     */
17714     template<class... Args>
emplace_back(Args &&...args)17715     void emplace_back(Args&& ... args)
17716     {
17717         // emplace_back only works for null objects or arrays
17718         if (JSON_UNLIKELY(not(is_null() or is_array())))
17719         {
17720             JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
17721         }
17722 
17723         // transform null object into an array
17724         if (is_null())
17725         {
17726             m_type = value_t::array;
17727             m_value = value_t::array;
17728             assert_invariant();
17729         }
17730 
17731         // add element to array (perfect forwarding)
17732         m_value.array->emplace_back(std::forward<Args>(args)...);
17733     }
17734 
17735     /*!
17736     @brief add an object to an object if key does not exist
17737 
17738     Inserts a new element into a JSON object constructed in-place with the
17739     given @a args if there is no element with the key in the container. If the
17740     function is called on a JSON null value, an empty object is created before
17741     appending the value created from @a args.
17742 
17743     @param[in] args arguments to forward to a constructor of @ref basic_json
17744     @tparam Args compatible types to create a @ref basic_json object
17745 
17746     @return a pair consisting of an iterator to the inserted element, or the
17747             already-existing element if no insertion happened, and a bool
17748             denoting whether the insertion took place.
17749 
17750     @throw type_error.311 when called on a type other than JSON object or
17751     null; example: `"cannot use emplace() with number"`
17752 
17753     @complexity Logarithmic in the size of the container, O(log(`size()`)).
17754 
17755     @liveexample{The example shows how `emplace()` can be used to add elements
17756     to a JSON object. Note how the `null` value was silently converted to a
17757     JSON object. Further note how no value is added if there was already one
17758     value stored with the same key.,emplace}
17759 
17760     @since version 2.0.8
17761     */
17762     template<class... Args>
emplace(Args &&...args)17763     std::pair<iterator, bool> emplace(Args&& ... args)
17764     {
17765         // emplace only works for null objects or arrays
17766         if (JSON_UNLIKELY(not(is_null() or is_object())))
17767         {
17768             JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
17769         }
17770 
17771         // transform null object into an object
17772         if (is_null())
17773         {
17774             m_type = value_t::object;
17775             m_value = value_t::object;
17776             assert_invariant();
17777         }
17778 
17779         // add element to array (perfect forwarding)
17780         auto res = m_value.object->emplace(std::forward<Args>(args)...);
17781         // create result iterator and set iterator to the result of emplace
17782         auto it = begin();
17783         it.m_it.object_iterator = res.first;
17784 
17785         // return pair of iterator and boolean
17786         return {it, res.second};
17787     }
17788 
17789     /// Helper for insertion of an iterator
17790     /// @note: This uses std::distance to support GCC 4.8,
17791     ///        see https://github.com/nlohmann/json/pull/1257
17792     template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)17793     iterator insert_iterator(const_iterator pos, Args&& ... args)
17794     {
17795         iterator result(this);
17796         assert(m_value.array != nullptr);
17797 
17798         auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
17799         m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
17800         result.m_it.array_iterator = m_value.array->begin() + insert_pos;
17801 
17802         // This could have been written as:
17803         // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
17804         // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
17805 
17806         return result;
17807     }
17808 
17809     /*!
17810     @brief inserts element
17811 
17812     Inserts element @a val before iterator @a pos.
17813 
17814     @param[in] pos iterator before which the content will be inserted; may be
17815     the end() iterator
17816     @param[in] val element to insert
17817     @return iterator pointing to the inserted @a val.
17818 
17819     @throw type_error.309 if called on JSON values other than arrays;
17820     example: `"cannot use insert() with string"`
17821     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17822     example: `"iterator does not fit current value"`
17823 
17824     @complexity Constant plus linear in the distance between @a pos and end of
17825     the container.
17826 
17827     @liveexample{The example shows how `insert()` is used.,insert}
17828 
17829     @since version 1.0.0
17830     */
insert(const_iterator pos,const basic_json & val)17831     iterator insert(const_iterator pos, const basic_json& val)
17832     {
17833         // insert only works for arrays
17834         if (JSON_LIKELY(is_array()))
17835         {
17836             // check if iterator pos fits to this JSON value
17837             if (JSON_UNLIKELY(pos.m_object != this))
17838             {
17839                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17840             }
17841 
17842             // insert to array and return iterator
17843             return insert_iterator(pos, val);
17844         }
17845 
17846         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17847     }
17848 
17849     /*!
17850     @brief inserts element
17851     @copydoc insert(const_iterator, const basic_json&)
17852     */
insert(const_iterator pos,basic_json && val)17853     iterator insert(const_iterator pos, basic_json&& val)
17854     {
17855         return insert(pos, val);
17856     }
17857 
17858     /*!
17859     @brief inserts elements
17860 
17861     Inserts @a cnt copies of @a val before iterator @a pos.
17862 
17863     @param[in] pos iterator before which the content will be inserted; may be
17864     the end() iterator
17865     @param[in] cnt number of copies of @a val to insert
17866     @param[in] val element to insert
17867     @return iterator pointing to the first element inserted, or @a pos if
17868     `cnt==0`
17869 
17870     @throw type_error.309 if called on JSON values other than arrays; example:
17871     `"cannot use insert() with string"`
17872     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17873     example: `"iterator does not fit current value"`
17874 
17875     @complexity Linear in @a cnt plus linear in the distance between @a pos
17876     and end of the container.
17877 
17878     @liveexample{The example shows how `insert()` is used.,insert__count}
17879 
17880     @since version 1.0.0
17881     */
insert(const_iterator pos,size_type cnt,const basic_json & val)17882     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
17883     {
17884         // insert only works for arrays
17885         if (JSON_LIKELY(is_array()))
17886         {
17887             // check if iterator pos fits to this JSON value
17888             if (JSON_UNLIKELY(pos.m_object != this))
17889             {
17890                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17891             }
17892 
17893             // insert to array and return iterator
17894             return insert_iterator(pos, cnt, val);
17895         }
17896 
17897         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17898     }
17899 
17900     /*!
17901     @brief inserts elements
17902 
17903     Inserts elements from range `[first, last)` before iterator @a pos.
17904 
17905     @param[in] pos iterator before which the content will be inserted; may be
17906     the end() iterator
17907     @param[in] first begin of the range of elements to insert
17908     @param[in] last end of the range of elements to insert
17909 
17910     @throw type_error.309 if called on JSON values other than arrays; example:
17911     `"cannot use insert() with string"`
17912     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17913     example: `"iterator does not fit current value"`
17914     @throw invalid_iterator.210 if @a first and @a last do not belong to the
17915     same JSON value; example: `"iterators do not fit"`
17916     @throw invalid_iterator.211 if @a first or @a last are iterators into
17917     container for which insert is called; example: `"passed iterators may not
17918     belong to container"`
17919 
17920     @return iterator pointing to the first element inserted, or @a pos if
17921     `first==last`
17922 
17923     @complexity Linear in `std::distance(first, last)` plus linear in the
17924     distance between @a pos and end of the container.
17925 
17926     @liveexample{The example shows how `insert()` is used.,insert__range}
17927 
17928     @since version 1.0.0
17929     */
insert(const_iterator pos,const_iterator first,const_iterator last)17930     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
17931     {
17932         // insert only works for arrays
17933         if (JSON_UNLIKELY(not is_array()))
17934         {
17935             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17936         }
17937 
17938         // check if iterator pos fits to this JSON value
17939         if (JSON_UNLIKELY(pos.m_object != this))
17940         {
17941             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17942         }
17943 
17944         // check if range iterators belong to the same JSON object
17945         if (JSON_UNLIKELY(first.m_object != last.m_object))
17946         {
17947             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
17948         }
17949 
17950         if (JSON_UNLIKELY(first.m_object == this))
17951         {
17952             JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
17953         }
17954 
17955         // insert to array and return iterator
17956         return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
17957     }
17958 
17959     /*!
17960     @brief inserts elements
17961 
17962     Inserts elements from initializer list @a ilist before iterator @a pos.
17963 
17964     @param[in] pos iterator before which the content will be inserted; may be
17965     the end() iterator
17966     @param[in] ilist initializer list to insert the values from
17967 
17968     @throw type_error.309 if called on JSON values other than arrays; example:
17969     `"cannot use insert() with string"`
17970     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17971     example: `"iterator does not fit current value"`
17972 
17973     @return iterator pointing to the first element inserted, or @a pos if
17974     `ilist` is empty
17975 
17976     @complexity Linear in `ilist.size()` plus linear in the distance between
17977     @a pos and end of the container.
17978 
17979     @liveexample{The example shows how `insert()` is used.,insert__ilist}
17980 
17981     @since version 1.0.0
17982     */
insert(const_iterator pos,initializer_list_t ilist)17983     iterator insert(const_iterator pos, initializer_list_t ilist)
17984     {
17985         // insert only works for arrays
17986         if (JSON_UNLIKELY(not is_array()))
17987         {
17988             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17989         }
17990 
17991         // check if iterator pos fits to this JSON value
17992         if (JSON_UNLIKELY(pos.m_object != this))
17993         {
17994             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17995         }
17996 
17997         // insert to array and return iterator
17998         return insert_iterator(pos, ilist.begin(), ilist.end());
17999     }
18000 
18001     /*!
18002     @brief inserts elements
18003 
18004     Inserts elements from range `[first, last)`.
18005 
18006     @param[in] first begin of the range of elements to insert
18007     @param[in] last end of the range of elements to insert
18008 
18009     @throw type_error.309 if called on JSON values other than objects; example:
18010     `"cannot use insert() with string"`
18011     @throw invalid_iterator.202 if iterator @a first or @a last does does not
18012     point to an object; example: `"iterators first and last must point to
18013     objects"`
18014     @throw invalid_iterator.210 if @a first and @a last do not belong to the
18015     same JSON value; example: `"iterators do not fit"`
18016 
18017     @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
18018     of elements to insert.
18019 
18020     @liveexample{The example shows how `insert()` is used.,insert__range_object}
18021 
18022     @since version 3.0.0
18023     */
insert(const_iterator first,const_iterator last)18024     void insert(const_iterator first, const_iterator last)
18025     {
18026         // insert only works for objects
18027         if (JSON_UNLIKELY(not is_object()))
18028         {
18029             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
18030         }
18031 
18032         // check if range iterators belong to the same JSON object
18033         if (JSON_UNLIKELY(first.m_object != last.m_object))
18034         {
18035             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
18036         }
18037 
18038         // passed iterators must belong to objects
18039         if (JSON_UNLIKELY(not first.m_object->is_object()))
18040         {
18041             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
18042         }
18043 
18044         m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
18045     }
18046 
18047     /*!
18048     @brief updates a JSON object from another object, overwriting existing keys
18049 
18050     Inserts all values from JSON object @a j and overwrites existing keys.
18051 
18052     @param[in] j  JSON object to read values from
18053 
18054     @throw type_error.312 if called on JSON values other than objects; example:
18055     `"cannot use update() with string"`
18056 
18057     @complexity O(N*log(size() + N)), where N is the number of elements to
18058                 insert.
18059 
18060     @liveexample{The example shows how `update()` is used.,update}
18061 
18062     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
18063 
18064     @since version 3.0.0
18065     */
update(const_reference j)18066     void update(const_reference j)
18067     {
18068         // implicitly convert null value to an empty object
18069         if (is_null())
18070         {
18071             m_type = value_t::object;
18072             m_value.object = create<object_t>();
18073             assert_invariant();
18074         }
18075 
18076         if (JSON_UNLIKELY(not is_object()))
18077         {
18078             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
18079         }
18080         if (JSON_UNLIKELY(not j.is_object()))
18081         {
18082             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
18083         }
18084 
18085         for (auto it = j.cbegin(); it != j.cend(); ++it)
18086         {
18087             m_value.object->operator[](it.key()) = it.value();
18088         }
18089     }
18090 
18091     /*!
18092     @brief updates a JSON object from another object, overwriting existing keys
18093 
18094     Inserts all values from from range `[first, last)` and overwrites existing
18095     keys.
18096 
18097     @param[in] first begin of the range of elements to insert
18098     @param[in] last end of the range of elements to insert
18099 
18100     @throw type_error.312 if called on JSON values other than objects; example:
18101     `"cannot use update() with string"`
18102     @throw invalid_iterator.202 if iterator @a first or @a last does does not
18103     point to an object; example: `"iterators first and last must point to
18104     objects"`
18105     @throw invalid_iterator.210 if @a first and @a last do not belong to the
18106     same JSON value; example: `"iterators do not fit"`
18107 
18108     @complexity O(N*log(size() + N)), where N is the number of elements to
18109                 insert.
18110 
18111     @liveexample{The example shows how `update()` is used__range.,update}
18112 
18113     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
18114 
18115     @since version 3.0.0
18116     */
update(const_iterator first,const_iterator last)18117     void update(const_iterator first, const_iterator last)
18118     {
18119         // implicitly convert null value to an empty object
18120         if (is_null())
18121         {
18122             m_type = value_t::object;
18123             m_value.object = create<object_t>();
18124             assert_invariant();
18125         }
18126 
18127         if (JSON_UNLIKELY(not is_object()))
18128         {
18129             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
18130         }
18131 
18132         // check if range iterators belong to the same JSON object
18133         if (JSON_UNLIKELY(first.m_object != last.m_object))
18134         {
18135             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
18136         }
18137 
18138         // passed iterators must belong to objects
18139         if (JSON_UNLIKELY(not first.m_object->is_object()
18140                           or not last.m_object->is_object()))
18141         {
18142             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
18143         }
18144 
18145         for (auto it = first; it != last; ++it)
18146         {
18147             m_value.object->operator[](it.key()) = it.value();
18148         }
18149     }
18150 
18151     /*!
18152     @brief exchanges the values
18153 
18154     Exchanges the contents of the JSON value with those of @a other. Does not
18155     invoke any move, copy, or swap operations on individual elements. All
18156     iterators and references remain valid. The past-the-end iterator is
18157     invalidated.
18158 
18159     @param[in,out] other JSON value to exchange the contents with
18160 
18161     @complexity Constant.
18162 
18163     @liveexample{The example below shows how JSON values can be swapped with
18164     `swap()`.,swap__reference}
18165 
18166     @since version 1.0.0
18167     */
swap(reference other)18168     void swap(reference other) noexcept (
18169         std::is_nothrow_move_constructible<value_t>::value and
18170         std::is_nothrow_move_assignable<value_t>::value and
18171         std::is_nothrow_move_constructible<json_value>::value and
18172         std::is_nothrow_move_assignable<json_value>::value
18173     )
18174     {
18175         std::swap(m_type, other.m_type);
18176         std::swap(m_value, other.m_value);
18177         assert_invariant();
18178     }
18179 
18180     /*!
18181     @brief exchanges the values
18182 
18183     Exchanges the contents of a JSON array with those of @a other. Does not
18184     invoke any move, copy, or swap operations on individual elements. All
18185     iterators and references remain valid. The past-the-end iterator is
18186     invalidated.
18187 
18188     @param[in,out] other array to exchange the contents with
18189 
18190     @throw type_error.310 when JSON value is not an array; example: `"cannot
18191     use swap() with string"`
18192 
18193     @complexity Constant.
18194 
18195     @liveexample{The example below shows how arrays can be swapped with
18196     `swap()`.,swap__array_t}
18197 
18198     @since version 1.0.0
18199     */
swap(array_t & other)18200     void swap(array_t& other)
18201     {
18202         // swap only works for arrays
18203         if (JSON_LIKELY(is_array()))
18204         {
18205             std::swap(*(m_value.array), other);
18206         }
18207         else
18208         {
18209             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18210         }
18211     }
18212 
18213     /*!
18214     @brief exchanges the values
18215 
18216     Exchanges the contents of a JSON object with those of @a other. Does not
18217     invoke any move, copy, or swap operations on individual elements. All
18218     iterators and references remain valid. The past-the-end iterator is
18219     invalidated.
18220 
18221     @param[in,out] other object to exchange the contents with
18222 
18223     @throw type_error.310 when JSON value is not an object; example:
18224     `"cannot use swap() with string"`
18225 
18226     @complexity Constant.
18227 
18228     @liveexample{The example below shows how objects can be swapped with
18229     `swap()`.,swap__object_t}
18230 
18231     @since version 1.0.0
18232     */
swap(object_t & other)18233     void swap(object_t& other)
18234     {
18235         // swap only works for objects
18236         if (JSON_LIKELY(is_object()))
18237         {
18238             std::swap(*(m_value.object), other);
18239         }
18240         else
18241         {
18242             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18243         }
18244     }
18245 
18246     /*!
18247     @brief exchanges the values
18248 
18249     Exchanges the contents of a JSON string with those of @a other. Does not
18250     invoke any move, copy, or swap operations on individual elements. All
18251     iterators and references remain valid. The past-the-end iterator is
18252     invalidated.
18253 
18254     @param[in,out] other string to exchange the contents with
18255 
18256     @throw type_error.310 when JSON value is not a string; example: `"cannot
18257     use swap() with boolean"`
18258 
18259     @complexity Constant.
18260 
18261     @liveexample{The example below shows how strings can be swapped with
18262     `swap()`.,swap__string_t}
18263 
18264     @since version 1.0.0
18265     */
swap(string_t & other)18266     void swap(string_t& other)
18267     {
18268         // swap only works for strings
18269         if (JSON_LIKELY(is_string()))
18270         {
18271             std::swap(*(m_value.string), other);
18272         }
18273         else
18274         {
18275             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18276         }
18277     }
18278 
18279     /// @}
18280 
18281   public:
18282     //////////////////////////////////////////
18283     // lexicographical comparison operators //
18284     //////////////////////////////////////////
18285 
18286     /// @name lexicographical comparison operators
18287     /// @{
18288 
18289     /*!
18290     @brief comparison: equal
18291 
18292     Compares two JSON values for equality according to the following rules:
18293     - Two JSON values are equal if (1) they are from the same type and (2)
18294       their stored values are the same according to their respective
18295       `operator==`.
18296     - Integer and floating-point numbers are automatically converted before
18297       comparison. Note than two NaN values are always treated as unequal.
18298     - Two JSON null values are equal.
18299 
18300     @note Floating-point inside JSON values numbers are compared with
18301     `json::number_float_t::operator==` which is `double::operator==` by
18302     default. To compare floating-point while respecting an epsilon, an alternative
18303     [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
18304     could be used, for instance
18305     @code {.cpp}
18306     template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
18307     inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
18308     {
18309         return std::abs(a - b) <= epsilon;
18310     }
18311     @endcode
18312 
18313     @note NaN values never compare equal to themselves or to other NaN values.
18314 
18315     @param[in] lhs  first JSON value to consider
18316     @param[in] rhs  second JSON value to consider
18317     @return whether the values @a lhs and @a rhs are equal
18318 
18319     @exceptionsafety No-throw guarantee: this function never throws exceptions.
18320 
18321     @complexity Linear.
18322 
18323     @liveexample{The example demonstrates comparing several JSON
18324     types.,operator__equal}
18325 
18326     @since version 1.0.0
18327     */
operator ==(const_reference lhs,const_reference rhs)18328     friend bool operator==(const_reference lhs, const_reference rhs) noexcept
18329     {
18330         const auto lhs_type = lhs.type();
18331         const auto rhs_type = rhs.type();
18332 
18333         if (lhs_type == rhs_type)
18334         {
18335             switch (lhs_type)
18336             {
18337                 case value_t::array:
18338                     return *lhs.m_value.array == *rhs.m_value.array;
18339 
18340                 case value_t::object:
18341                     return *lhs.m_value.object == *rhs.m_value.object;
18342 
18343                 case value_t::null:
18344                     return true;
18345 
18346                 case value_t::string:
18347                     return *lhs.m_value.string == *rhs.m_value.string;
18348 
18349                 case value_t::boolean:
18350                     return lhs.m_value.boolean == rhs.m_value.boolean;
18351 
18352                 case value_t::number_integer:
18353                     return lhs.m_value.number_integer == rhs.m_value.number_integer;
18354 
18355                 case value_t::number_unsigned:
18356                     return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
18357 
18358                 case value_t::number_float:
18359                     return lhs.m_value.number_float == rhs.m_value.number_float;
18360 
18361                 default:
18362                     return false;
18363             }
18364         }
18365         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
18366         {
18367             return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
18368         }
18369         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
18370         {
18371             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
18372         }
18373         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
18374         {
18375             return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
18376         }
18377         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
18378         {
18379             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
18380         }
18381         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
18382         {
18383             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
18384         }
18385         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
18386         {
18387             return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18388         }
18389 
18390         return false;
18391     }
18392 
18393     /*!
18394     @brief comparison: equal
18395     @copydoc operator==(const_reference, const_reference)
18396     */
18397     template<typename ScalarType, typename std::enable_if<
18398                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)18399     friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
18400     {
18401         return lhs == basic_json(rhs);
18402     }
18403 
18404     /*!
18405     @brief comparison: equal
18406     @copydoc operator==(const_reference, const_reference)
18407     */
18408     template<typename ScalarType, typename std::enable_if<
18409                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)18410     friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
18411     {
18412         return basic_json(lhs) == rhs;
18413     }
18414 
18415     /*!
18416     @brief comparison: not equal
18417 
18418     Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
18419 
18420     @param[in] lhs  first JSON value to consider
18421     @param[in] rhs  second JSON value to consider
18422     @return whether the values @a lhs and @a rhs are not equal
18423 
18424     @complexity Linear.
18425 
18426     @exceptionsafety No-throw guarantee: this function never throws exceptions.
18427 
18428     @liveexample{The example demonstrates comparing several JSON
18429     types.,operator__notequal}
18430 
18431     @since version 1.0.0
18432     */
operator !=(const_reference lhs,const_reference rhs)18433     friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
18434     {
18435         return not (lhs == rhs);
18436     }
18437 
18438     /*!
18439     @brief comparison: not equal
18440     @copydoc operator!=(const_reference, const_reference)
18441     */
18442     template<typename ScalarType, typename std::enable_if<
18443                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)18444     friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
18445     {
18446         return lhs != basic_json(rhs);
18447     }
18448 
18449     /*!
18450     @brief comparison: not equal
18451     @copydoc operator!=(const_reference, const_reference)
18452     */
18453     template<typename ScalarType, typename std::enable_if<
18454                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)18455     friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
18456     {
18457         return basic_json(lhs) != rhs;
18458     }
18459 
18460     /*!
18461     @brief comparison: less than
18462 
18463     Compares whether one JSON value @a lhs is less than another JSON value @a
18464     rhs according to the following rules:
18465     - If @a lhs and @a rhs have the same type, the values are compared using
18466       the default `<` operator.
18467     - Integer and floating-point numbers are automatically converted before
18468       comparison
18469     - In case @a lhs and @a rhs have different types, the values are ignored
18470       and the order of the types is considered, see
18471       @ref operator<(const value_t, const value_t).
18472 
18473     @param[in] lhs  first JSON value to consider
18474     @param[in] rhs  second JSON value to consider
18475     @return whether @a lhs is less than @a rhs
18476 
18477     @complexity Linear.
18478 
18479     @exceptionsafety No-throw guarantee: this function never throws exceptions.
18480 
18481     @liveexample{The example demonstrates comparing several JSON
18482     types.,operator__less}
18483 
18484     @since version 1.0.0
18485     */
operator <(const_reference lhs,const_reference rhs)18486     friend bool operator<(const_reference lhs, const_reference rhs) noexcept
18487     {
18488         const auto lhs_type = lhs.type();
18489         const auto rhs_type = rhs.type();
18490 
18491         if (lhs_type == rhs_type)
18492         {
18493             switch (lhs_type)
18494             {
18495                 case value_t::array:
18496                     // note parentheses are necessary, see
18497                     // https://github.com/nlohmann/json/issues/1530
18498                     return (*lhs.m_value.array) < (*rhs.m_value.array);
18499 
18500                 case value_t::object:
18501                     return *lhs.m_value.object < *rhs.m_value.object;
18502 
18503                 case value_t::null:
18504                     return false;
18505 
18506                 case value_t::string:
18507                     return *lhs.m_value.string < *rhs.m_value.string;
18508 
18509                 case value_t::boolean:
18510                     return lhs.m_value.boolean < rhs.m_value.boolean;
18511 
18512                 case value_t::number_integer:
18513                     return lhs.m_value.number_integer < rhs.m_value.number_integer;
18514 
18515                 case value_t::number_unsigned:
18516                     return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
18517 
18518                 case value_t::number_float:
18519                     return lhs.m_value.number_float < rhs.m_value.number_float;
18520 
18521                 default:
18522                     return false;
18523             }
18524         }
18525         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
18526         {
18527             return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
18528         }
18529         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
18530         {
18531             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
18532         }
18533         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
18534         {
18535             return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
18536         }
18537         else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
18538         {
18539             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
18540         }
18541         else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
18542         {
18543             return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18544         }
18545         else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
18546         {
18547             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
18548         }
18549 
18550         // We only reach this line if we cannot compare values. In that case,
18551         // we compare types. Note we have to call the operator explicitly,
18552         // because MSVC has problems otherwise.
18553         return operator<(lhs_type, rhs_type);
18554     }
18555 
18556     /*!
18557     @brief comparison: less than
18558     @copydoc operator<(const_reference, const_reference)
18559     */
18560     template<typename ScalarType, typename std::enable_if<
18561                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)18562     friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
18563     {
18564         return lhs < basic_json(rhs);
18565     }
18566 
18567     /*!
18568     @brief comparison: less than
18569     @copydoc operator<(const_reference, const_reference)
18570     */
18571     template<typename ScalarType, typename std::enable_if<
18572                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)18573     friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
18574     {
18575         return basic_json(lhs) < rhs;
18576     }
18577 
18578     /*!
18579     @brief comparison: less than or equal
18580 
18581     Compares whether one JSON value @a lhs is less than or equal to another
18582     JSON value by calculating `not (rhs < lhs)`.
18583 
18584     @param[in] lhs  first JSON value to consider
18585     @param[in] rhs  second JSON value to consider
18586     @return whether @a lhs is less than or equal to @a rhs
18587 
18588     @complexity Linear.
18589 
18590     @exceptionsafety No-throw guarantee: this function never throws exceptions.
18591 
18592     @liveexample{The example demonstrates comparing several JSON
18593     types.,operator__greater}
18594 
18595     @since version 1.0.0
18596     */
operator <=(const_reference lhs,const_reference rhs)18597     friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
18598     {
18599         return not (rhs < lhs);
18600     }
18601 
18602     /*!
18603     @brief comparison: less than or equal
18604     @copydoc operator<=(const_reference, const_reference)
18605     */
18606     template<typename ScalarType, typename std::enable_if<
18607                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)18608     friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
18609     {
18610         return lhs <= basic_json(rhs);
18611     }
18612 
18613     /*!
18614     @brief comparison: less than or equal
18615     @copydoc operator<=(const_reference, const_reference)
18616     */
18617     template<typename ScalarType, typename std::enable_if<
18618                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)18619     friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
18620     {
18621         return basic_json(lhs) <= rhs;
18622     }
18623 
18624     /*!
18625     @brief comparison: greater than
18626 
18627     Compares whether one JSON value @a lhs is greater than another
18628     JSON value by calculating `not (lhs <= rhs)`.
18629 
18630     @param[in] lhs  first JSON value to consider
18631     @param[in] rhs  second JSON value to consider
18632     @return whether @a lhs is greater than to @a rhs
18633 
18634     @complexity Linear.
18635 
18636     @exceptionsafety No-throw guarantee: this function never throws exceptions.
18637 
18638     @liveexample{The example demonstrates comparing several JSON
18639     types.,operator__lessequal}
18640 
18641     @since version 1.0.0
18642     */
operator >(const_reference lhs,const_reference rhs)18643     friend bool operator>(const_reference lhs, const_reference rhs) noexcept
18644     {
18645         return not (lhs <= rhs);
18646     }
18647 
18648     /*!
18649     @brief comparison: greater than
18650     @copydoc operator>(const_reference, const_reference)
18651     */
18652     template<typename ScalarType, typename std::enable_if<
18653                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)18654     friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
18655     {
18656         return lhs > basic_json(rhs);
18657     }
18658 
18659     /*!
18660     @brief comparison: greater than
18661     @copydoc operator>(const_reference, const_reference)
18662     */
18663     template<typename ScalarType, typename std::enable_if<
18664                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)18665     friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
18666     {
18667         return basic_json(lhs) > rhs;
18668     }
18669 
18670     /*!
18671     @brief comparison: greater than or equal
18672 
18673     Compares whether one JSON value @a lhs is greater than or equal to another
18674     JSON value by calculating `not (lhs < rhs)`.
18675 
18676     @param[in] lhs  first JSON value to consider
18677     @param[in] rhs  second JSON value to consider
18678     @return whether @a lhs is greater than or equal to @a rhs
18679 
18680     @complexity Linear.
18681 
18682     @exceptionsafety No-throw guarantee: this function never throws exceptions.
18683 
18684     @liveexample{The example demonstrates comparing several JSON
18685     types.,operator__greaterequal}
18686 
18687     @since version 1.0.0
18688     */
operator >=(const_reference lhs,const_reference rhs)18689     friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
18690     {
18691         return not (lhs < rhs);
18692     }
18693 
18694     /*!
18695     @brief comparison: greater than or equal
18696     @copydoc operator>=(const_reference, const_reference)
18697     */
18698     template<typename ScalarType, typename std::enable_if<
18699                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)18700     friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
18701     {
18702         return lhs >= basic_json(rhs);
18703     }
18704 
18705     /*!
18706     @brief comparison: greater than or equal
18707     @copydoc operator>=(const_reference, const_reference)
18708     */
18709     template<typename ScalarType, typename std::enable_if<
18710                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)18711     friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
18712     {
18713         return basic_json(lhs) >= rhs;
18714     }
18715 
18716     /// @}
18717 
18718     ///////////////////
18719     // serialization //
18720     ///////////////////
18721 
18722     /// @name serialization
18723     /// @{
18724 
18725     /*!
18726     @brief serialize to stream
18727 
18728     Serialize the given JSON value @a j to the output stream @a o. The JSON
18729     value will be serialized using the @ref dump member function.
18730 
18731     - The indentation of the output can be controlled with the member variable
18732       `width` of the output stream @a o. For instance, using the manipulator
18733       `std::setw(4)` on @a o sets the indentation level to `4` and the
18734       serialization result is the same as calling `dump(4)`.
18735 
18736     - The indentation character can be controlled with the member variable
18737       `fill` of the output stream @a o. For instance, the manipulator
18738       `std::setfill('\\t')` sets indentation to use a tab character rather than
18739       the default space character.
18740 
18741     @param[in,out] o  stream to serialize to
18742     @param[in] j  JSON value to serialize
18743 
18744     @return the stream @a o
18745 
18746     @throw type_error.316 if a string stored inside the JSON value is not
18747                           UTF-8 encoded
18748 
18749     @complexity Linear.
18750 
18751     @liveexample{The example below shows the serialization with different
18752     parameters to `width` to adjust the indentation level.,operator_serialize}
18753 
18754     @since version 1.0.0; indentation character added in version 3.0.0
18755     */
operator <<(std::ostream & o,const basic_json & j)18756     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
18757     {
18758         // read width member and use it as indentation parameter if nonzero
18759         const bool pretty_print = o.width() > 0;
18760         const auto indentation = pretty_print ? o.width() : 0;
18761 
18762         // reset width to 0 for subsequent calls to this stream
18763         o.width(0);
18764 
18765         // do the actual serialization
18766         serializer s(detail::output_adapter<char>(o), o.fill());
18767         s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
18768         return o;
18769     }
18770 
18771     /*!
18772     @brief serialize to stream
18773     @deprecated This stream operator is deprecated and will be removed in
18774                 future 4.0.0 of the library. Please use
18775                 @ref operator<<(std::ostream&, const basic_json&)
18776                 instead; that is, replace calls like `j >> o;` with `o << j;`.
18777     @since version 1.0.0; deprecated since version 3.0.0
18778     */
18779     JSON_DEPRECATED
operator >>(const basic_json & j,std::ostream & o)18780     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
18781     {
18782         return o << j;
18783     }
18784 
18785     /// @}
18786 
18787 
18788     /////////////////////
18789     // deserialization //
18790     /////////////////////
18791 
18792     /// @name deserialization
18793     /// @{
18794 
18795     /*!
18796     @brief deserialize from a compatible input
18797 
18798     This function reads from a compatible input. Examples are:
18799     - an array of 1-byte values
18800     - strings with character/literal type with size of 1 byte
18801     - input streams
18802     - container with contiguous storage of 1-byte values. Compatible container
18803       types include `std::vector`, `std::string`, `std::array`,
18804       `std::valarray`, and `std::initializer_list`. Furthermore, C-style
18805       arrays can be used with `std::begin()`/`std::end()`. User-defined
18806       containers can be used as long as they implement random-access iterators
18807       and a contiguous storage.
18808 
18809     @pre Each element of the container has a size of 1 byte. Violating this
18810     precondition yields undefined behavior. **This precondition is enforced
18811     with a static assertion.**
18812 
18813     @pre The container storage is contiguous. Violating this precondition
18814     yields undefined behavior. **This precondition is enforced with an
18815     assertion.**
18816 
18817     @warning There is no way to enforce all preconditions at compile-time. If
18818              the function is called with a noncompliant container and with
18819              assertions switched off, the behavior is undefined and will most
18820              likely yield segmentation violation.
18821 
18822     @param[in] i  input to read from
18823     @param[in] cb  a parser callback function of type @ref parser_callback_t
18824     which is used to control the deserialization by filtering unwanted values
18825     (optional)
18826     @param[in] allow_exceptions  whether to throw exceptions in case of a
18827     parse error (optional, true by default)
18828 
18829     @return deserialized JSON value; in case of a parse error and
18830             @a allow_exceptions set to `false`, the return value will be
18831             value_t::discarded.
18832 
18833     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
18834     of input; expected string literal""`
18835     @throw parse_error.102 if to_unicode fails or surrogate error
18836     @throw parse_error.103 if to_unicode fails
18837 
18838     @complexity Linear in the length of the input. The parser is a predictive
18839     LL(1) parser. The complexity can be higher if the parser callback function
18840     @a cb has a super-linear complexity.
18841 
18842     @note A UTF-8 byte order mark is silently ignored.
18843 
18844     @liveexample{The example below demonstrates the `parse()` function reading
18845     from an array.,parse__array__parser_callback_t}
18846 
18847     @liveexample{The example below demonstrates the `parse()` function with
18848     and without callback function.,parse__string__parser_callback_t}
18849 
18850     @liveexample{The example below demonstrates the `parse()` function with
18851     and without callback function.,parse__istream__parser_callback_t}
18852 
18853     @liveexample{The example below demonstrates the `parse()` function reading
18854     from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
18855 
18856     @since version 2.0.3 (contiguous containers)
18857     */
18858     JSON_NODISCARD
parse(detail::input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)18859     static basic_json parse(detail::input_adapter&& i,
18860                             const parser_callback_t cb = nullptr,
18861                             const bool allow_exceptions = true)
18862     {
18863         basic_json result;
18864         parser(i, cb, allow_exceptions).parse(true, result);
18865         return result;
18866     }
18867 
accept(detail::input_adapter && i)18868     static bool accept(detail::input_adapter&& i)
18869     {
18870         return parser(i).accept(true);
18871     }
18872 
18873     /*!
18874     @brief generate SAX events
18875 
18876     The SAX event lister must follow the interface of @ref json_sax.
18877 
18878     This function reads from a compatible input. Examples are:
18879     - an array of 1-byte values
18880     - strings with character/literal type with size of 1 byte
18881     - input streams
18882     - container with contiguous storage of 1-byte values. Compatible container
18883       types include `std::vector`, `std::string`, `std::array`,
18884       `std::valarray`, and `std::initializer_list`. Furthermore, C-style
18885       arrays can be used with `std::begin()`/`std::end()`. User-defined
18886       containers can be used as long as they implement random-access iterators
18887       and a contiguous storage.
18888 
18889     @pre Each element of the container has a size of 1 byte. Violating this
18890     precondition yields undefined behavior. **This precondition is enforced
18891     with a static assertion.**
18892 
18893     @pre The container storage is contiguous. Violating this precondition
18894     yields undefined behavior. **This precondition is enforced with an
18895     assertion.**
18896 
18897     @warning There is no way to enforce all preconditions at compile-time. If
18898              the function is called with a noncompliant container and with
18899              assertions switched off, the behavior is undefined and will most
18900              likely yield segmentation violation.
18901 
18902     @param[in] i  input to read from
18903     @param[in,out] sax  SAX event listener
18904     @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
18905     @param[in] strict  whether the input has to be consumed completely
18906 
18907     @return return value of the last processed SAX event
18908 
18909     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
18910     of input; expected string literal""`
18911     @throw parse_error.102 if to_unicode fails or surrogate error
18912     @throw parse_error.103 if to_unicode fails
18913 
18914     @complexity Linear in the length of the input. The parser is a predictive
18915     LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
18916     a super-linear complexity.
18917 
18918     @note A UTF-8 byte order mark is silently ignored.
18919 
18920     @liveexample{The example below demonstrates the `sax_parse()` function
18921     reading from string and processing the events with a user-defined SAX
18922     event consumer.,sax_parse}
18923 
18924     @since version 3.2.0
18925     */
18926     template <typename SAX>
sax_parse(detail::input_adapter && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true)18927     static bool sax_parse(detail::input_adapter&& i, SAX* sax,
18928                           input_format_t format = input_format_t::json,
18929                           const bool strict = true)
18930     {
18931         assert(sax);
18932         return format == input_format_t::json
18933                ? parser(std::move(i)).sax_parse(sax, strict)
18934                : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
18935     }
18936 
18937     /*!
18938     @brief deserialize from an iterator range with contiguous storage
18939 
18940     This function reads from an iterator range of a container with contiguous
18941     storage of 1-byte values. Compatible container types include
18942     `std::vector`, `std::string`, `std::array`, `std::valarray`, and
18943     `std::initializer_list`. Furthermore, C-style arrays can be used with
18944     `std::begin()`/`std::end()`. User-defined containers can be used as long
18945     as they implement random-access iterators and a contiguous storage.
18946 
18947     @pre The iterator range is contiguous. Violating this precondition yields
18948     undefined behavior. **This precondition is enforced with an assertion.**
18949     @pre Each element in the range has a size of 1 byte. Violating this
18950     precondition yields undefined behavior. **This precondition is enforced
18951     with a static assertion.**
18952 
18953     @warning There is no way to enforce all preconditions at compile-time. If
18954              the function is called with noncompliant iterators and with
18955              assertions switched off, the behavior is undefined and will most
18956              likely yield segmentation violation.
18957 
18958     @tparam IteratorType iterator of container with contiguous storage
18959     @param[in] first  begin of the range to parse (included)
18960     @param[in] last  end of the range to parse (excluded)
18961     @param[in] cb  a parser callback function of type @ref parser_callback_t
18962     which is used to control the deserialization by filtering unwanted values
18963     (optional)
18964     @param[in] allow_exceptions  whether to throw exceptions in case of a
18965     parse error (optional, true by default)
18966 
18967     @return deserialized JSON value; in case of a parse error and
18968             @a allow_exceptions set to `false`, the return value will be
18969             value_t::discarded.
18970 
18971     @throw parse_error.101 in case of an unexpected token
18972     @throw parse_error.102 if to_unicode fails or surrogate error
18973     @throw parse_error.103 if to_unicode fails
18974 
18975     @complexity Linear in the length of the input. The parser is a predictive
18976     LL(1) parser. The complexity can be higher if the parser callback function
18977     @a cb has a super-linear complexity.
18978 
18979     @note A UTF-8 byte order mark is silently ignored.
18980 
18981     @liveexample{The example below demonstrates the `parse()` function reading
18982     from an iterator range.,parse__iteratortype__parser_callback_t}
18983 
18984     @since version 2.0.3
18985     */
18986     template<class IteratorType, typename std::enable_if<
18987                  std::is_base_of<
18988                      std::random_access_iterator_tag,
18989                      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)18990     static basic_json parse(IteratorType first, IteratorType last,
18991                             const parser_callback_t cb = nullptr,
18992                             const bool allow_exceptions = true)
18993     {
18994         basic_json result;
18995         parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
18996         return result;
18997     }
18998 
18999     template<class IteratorType, typename std::enable_if<
19000                  std::is_base_of<
19001                      std::random_access_iterator_tag,
19002                      typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
accept(IteratorType first,IteratorType last)19003     static bool accept(IteratorType first, IteratorType last)
19004     {
19005         return parser(detail::input_adapter(first, last)).accept(true);
19006     }
19007 
19008     template<class IteratorType, class SAX, typename std::enable_if<
19009                  std::is_base_of<
19010                      std::random_access_iterator_tag,
19011                      typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
sax_parse(IteratorType first,IteratorType last,SAX * sax)19012     static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
19013     {
19014         return parser(detail::input_adapter(first, last)).sax_parse(sax);
19015     }
19016 
19017     /*!
19018     @brief deserialize from stream
19019     @deprecated This stream operator is deprecated and will be removed in
19020                 version 4.0.0 of the library. Please use
19021                 @ref operator>>(std::istream&, basic_json&)
19022                 instead; that is, replace calls like `j << i;` with `i >> j;`.
19023     @since version 1.0.0; deprecated since version 3.0.0
19024     */
19025     JSON_DEPRECATED
operator <<(basic_json & j,std::istream & i)19026     friend std::istream& operator<<(basic_json& j, std::istream& i)
19027     {
19028         return operator>>(i, j);
19029     }
19030 
19031     /*!
19032     @brief deserialize from stream
19033 
19034     Deserializes an input stream to a JSON value.
19035 
19036     @param[in,out] i  input stream to read a serialized JSON value from
19037     @param[in,out] j  JSON value to write the deserialized input to
19038 
19039     @throw parse_error.101 in case of an unexpected token
19040     @throw parse_error.102 if to_unicode fails or surrogate error
19041     @throw parse_error.103 if to_unicode fails
19042 
19043     @complexity Linear in the length of the input. The parser is a predictive
19044     LL(1) parser.
19045 
19046     @note A UTF-8 byte order mark is silently ignored.
19047 
19048     @liveexample{The example below shows how a JSON value is constructed by
19049     reading a serialization from a stream.,operator_deserialize}
19050 
19051     @sa parse(std::istream&, const parser_callback_t) for a variant with a
19052     parser callback function to filter values while parsing
19053 
19054     @since version 1.0.0
19055     */
operator >>(std::istream & i,basic_json & j)19056     friend std::istream& operator>>(std::istream& i, basic_json& j)
19057     {
19058         parser(detail::input_adapter(i)).parse(false, j);
19059         return i;
19060     }
19061 
19062     /// @}
19063 
19064     ///////////////////////////
19065     // convenience functions //
19066     ///////////////////////////
19067 
19068     /*!
19069     @brief return the type as string
19070 
19071     Returns the type name as string to be used in error messages - usually to
19072     indicate that a function was called on a wrong JSON type.
19073 
19074     @return a string representation of a the @a m_type member:
19075             Value type  | return value
19076             ----------- | -------------
19077             null        | `"null"`
19078             boolean     | `"boolean"`
19079             string      | `"string"`
19080             number      | `"number"` (for all number types)
19081             object      | `"object"`
19082             array       | `"array"`
19083             discarded   | `"discarded"`
19084 
19085     @exceptionsafety No-throw guarantee: this function never throws exceptions.
19086 
19087     @complexity Constant.
19088 
19089     @liveexample{The following code exemplifies `type_name()` for all JSON
19090     types.,type_name}
19091 
19092     @sa @ref type() -- return the type of the JSON value
19093     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
19094 
19095     @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
19096     since 3.0.0
19097     */
type_name() const19098     const char* type_name() const noexcept
19099     {
19100         {
19101             switch (m_type)
19102             {
19103                 case value_t::null:
19104                     return "null";
19105                 case value_t::object:
19106                     return "object";
19107                 case value_t::array:
19108                     return "array";
19109                 case value_t::string:
19110                     return "string";
19111                 case value_t::boolean:
19112                     return "boolean";
19113                 case value_t::discarded:
19114                     return "discarded";
19115                 default:
19116                     return "number";
19117             }
19118         }
19119     }
19120 
19121 
19122   private:
19123     //////////////////////
19124     // member variables //
19125     //////////////////////
19126 
19127     /// the type of the current element
19128     value_t m_type = value_t::null;
19129 
19130     /// the value of the current element
19131     json_value m_value = {};
19132 
19133     //////////////////////////////////////////
19134     // binary serialization/deserialization //
19135     //////////////////////////////////////////
19136 
19137     /// @name binary serialization/deserialization support
19138     /// @{
19139 
19140   public:
19141     /*!
19142     @brief create a CBOR serialization of a given JSON value
19143 
19144     Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
19145     Binary Object Representation) serialization format. CBOR is a binary
19146     serialization format which aims to be more compact than JSON itself, yet
19147     more efficient to parse.
19148 
19149     The library uses the following mapping from JSON values types to
19150     CBOR types according to the CBOR specification (RFC 7049):
19151 
19152     JSON value type | value/range                                | CBOR type                          | first byte
19153     --------------- | ------------------------------------------ | ---------------------------------- | ---------------
19154     null            | `null`                                     | Null                               | 0xF6
19155     boolean         | `true`                                     | True                               | 0xF5
19156     boolean         | `false`                                    | False                              | 0xF4
19157     number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
19158     number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
19159     number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
19160     number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
19161     number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
19162     number_integer  | 0..23                                      | Integer                            | 0x00..0x17
19163     number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
19164     number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
19165     number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
19166     number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
19167     number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
19168     number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
19169     number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
19170     number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
19171     number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
19172     number_float    | *any value*                                | Double-Precision Float             | 0xFB
19173     string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
19174     string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
19175     string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
19176     string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
19177     string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
19178     array           | *size*: 0..23                              | array                              | 0x80..0x97
19179     array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
19180     array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
19181     array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
19182     array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
19183     object          | *size*: 0..23                              | map                                | 0xA0..0xB7
19184     object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
19185     object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
19186     object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
19187     object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
19188 
19189     @note The mapping is **complete** in the sense that any JSON value type
19190           can be converted to a CBOR value.
19191 
19192     @note If NaN or Infinity are stored inside a JSON number, they are
19193           serialized properly. This behavior differs from the @ref dump()
19194           function which serializes NaN or Infinity to `null`.
19195 
19196     @note The following CBOR types are not used in the conversion:
19197           - byte strings (0x40..0x5F)
19198           - UTF-8 strings terminated by "break" (0x7F)
19199           - arrays terminated by "break" (0x9F)
19200           - maps terminated by "break" (0xBF)
19201           - date/time (0xC0..0xC1)
19202           - bignum (0xC2..0xC3)
19203           - decimal fraction (0xC4)
19204           - bigfloat (0xC5)
19205           - tagged items (0xC6..0xD4, 0xD8..0xDB)
19206           - expected conversions (0xD5..0xD7)
19207           - simple values (0xE0..0xF3, 0xF8)
19208           - undefined (0xF7)
19209           - half and single-precision floats (0xF9-0xFA)
19210           - break (0xFF)
19211 
19212     @param[in] j  JSON value to serialize
19213     @return MessagePack serialization as byte vector
19214 
19215     @complexity Linear in the size of the JSON value @a j.
19216 
19217     @liveexample{The example shows the serialization of a JSON value to a byte
19218     vector in CBOR format.,to_cbor}
19219 
19220     @sa http://cbor.io
19221     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19222         analogous deserialization
19223     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19224     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19225              related UBJSON format
19226 
19227     @since version 2.0.9
19228     */
to_cbor(const basic_json & j)19229     static std::vector<uint8_t> to_cbor(const basic_json& j)
19230     {
19231         std::vector<uint8_t> result;
19232         to_cbor(j, result);
19233         return result;
19234     }
19235 
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)19236     static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
19237     {
19238         binary_writer<uint8_t>(o).write_cbor(j);
19239     }
19240 
to_cbor(const basic_json & j,detail::output_adapter<char> o)19241     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
19242     {
19243         binary_writer<char>(o).write_cbor(j);
19244     }
19245 
19246     /*!
19247     @brief create a MessagePack serialization of a given JSON value
19248 
19249     Serializes a given JSON value @a j to a byte vector using the MessagePack
19250     serialization format. MessagePack is a binary serialization format which
19251     aims to be more compact than JSON itself, yet more efficient to parse.
19252 
19253     The library uses the following mapping from JSON values types to
19254     MessagePack types according to the MessagePack specification:
19255 
19256     JSON value type | value/range                       | MessagePack type | first byte
19257     --------------- | --------------------------------- | ---------------- | ----------
19258     null            | `null`                            | nil              | 0xC0
19259     boolean         | `true`                            | true             | 0xC3
19260     boolean         | `false`                           | false            | 0xC2
19261     number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
19262     number_integer  | -2147483648..-32769               | int32            | 0xD2
19263     number_integer  | -32768..-129                      | int16            | 0xD1
19264     number_integer  | -128..-33                         | int8             | 0xD0
19265     number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
19266     number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
19267     number_integer  | 128..255                          | uint 8           | 0xCC
19268     number_integer  | 256..65535                        | uint 16          | 0xCD
19269     number_integer  | 65536..4294967295                 | uint 32          | 0xCE
19270     number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
19271     number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
19272     number_unsigned | 128..255                          | uint 8           | 0xCC
19273     number_unsigned | 256..65535                        | uint 16          | 0xCD
19274     number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
19275     number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
19276     number_float    | *any value*                       | float 64         | 0xCB
19277     string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
19278     string          | *length*: 32..255                 | str 8            | 0xD9
19279     string          | *length*: 256..65535              | str 16           | 0xDA
19280     string          | *length*: 65536..4294967295       | str 32           | 0xDB
19281     array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
19282     array           | *size*: 16..65535                 | array 16         | 0xDC
19283     array           | *size*: 65536..4294967295         | array 32         | 0xDD
19284     object          | *size*: 0..15                     | fix map          | 0x80..0x8F
19285     object          | *size*: 16..65535                 | map 16           | 0xDE
19286     object          | *size*: 65536..4294967295         | map 32           | 0xDF
19287 
19288     @note The mapping is **complete** in the sense that any JSON value type
19289           can be converted to a MessagePack value.
19290 
19291     @note The following values can **not** be converted to a MessagePack value:
19292           - strings with more than 4294967295 bytes
19293           - arrays with more than 4294967295 elements
19294           - objects with more than 4294967295 elements
19295 
19296     @note The following MessagePack types are not used in the conversion:
19297           - bin 8 - bin 32 (0xC4..0xC6)
19298           - ext 8 - ext 32 (0xC7..0xC9)
19299           - float 32 (0xCA)
19300           - fixext 1 - fixext 16 (0xD4..0xD8)
19301 
19302     @note Any MessagePack output created @ref to_msgpack can be successfully
19303           parsed by @ref from_msgpack.
19304 
19305     @note If NaN or Infinity are stored inside a JSON number, they are
19306           serialized properly. This behavior differs from the @ref dump()
19307           function which serializes NaN or Infinity to `null`.
19308 
19309     @param[in] j  JSON value to serialize
19310     @return MessagePack serialization as byte vector
19311 
19312     @complexity Linear in the size of the JSON value @a j.
19313 
19314     @liveexample{The example shows the serialization of a JSON value to a byte
19315     vector in MessagePack format.,to_msgpack}
19316 
19317     @sa http://msgpack.org
19318     @sa @ref from_msgpack for the analogous deserialization
19319     @sa @ref to_cbor(const basic_json& for the related CBOR format
19320     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19321              related UBJSON format
19322 
19323     @since version 2.0.9
19324     */
to_msgpack(const basic_json & j)19325     static std::vector<uint8_t> to_msgpack(const basic_json& j)
19326     {
19327         std::vector<uint8_t> result;
19328         to_msgpack(j, result);
19329         return result;
19330     }
19331 
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)19332     static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
19333     {
19334         binary_writer<uint8_t>(o).write_msgpack(j);
19335     }
19336 
to_msgpack(const basic_json & j,detail::output_adapter<char> o)19337     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
19338     {
19339         binary_writer<char>(o).write_msgpack(j);
19340     }
19341 
19342     /*!
19343     @brief create a UBJSON serialization of a given JSON value
19344 
19345     Serializes a given JSON value @a j to a byte vector using the UBJSON
19346     (Universal Binary JSON) serialization format. UBJSON aims to be more compact
19347     than JSON itself, yet more efficient to parse.
19348 
19349     The library uses the following mapping from JSON values types to
19350     UBJSON types according to the UBJSON specification:
19351 
19352     JSON value type | value/range                       | UBJSON type | marker
19353     --------------- | --------------------------------- | ----------- | ------
19354     null            | `null`                            | null        | `Z`
19355     boolean         | `true`                            | true        | `T`
19356     boolean         | `false`                           | false       | `F`
19357     number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
19358     number_integer  | -2147483648..-32769               | int32       | `l`
19359     number_integer  | -32768..-129                      | int16       | `I`
19360     number_integer  | -128..127                         | int8        | `i`
19361     number_integer  | 128..255                          | uint8       | `U`
19362     number_integer  | 256..32767                        | int16       | `I`
19363     number_integer  | 32768..2147483647                 | int32       | `l`
19364     number_integer  | 2147483648..9223372036854775807   | int64       | `L`
19365     number_unsigned | 0..127                            | int8        | `i`
19366     number_unsigned | 128..255                          | uint8       | `U`
19367     number_unsigned | 256..32767                        | int16       | `I`
19368     number_unsigned | 32768..2147483647                 | int32       | `l`
19369     number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
19370     number_float    | *any value*                       | float64     | `D`
19371     string          | *with shortest length indicator*  | string      | `S`
19372     array           | *see notes on optimized format*   | array       | `[`
19373     object          | *see notes on optimized format*   | map         | `{`
19374 
19375     @note The mapping is **complete** in the sense that any JSON value type
19376           can be converted to a UBJSON value.
19377 
19378     @note The following values can **not** be converted to a UBJSON value:
19379           - strings with more than 9223372036854775807 bytes (theoretical)
19380           - unsigned integer numbers above 9223372036854775807
19381 
19382     @note The following markers are not used in the conversion:
19383           - `Z`: no-op values are not created.
19384           - `C`: single-byte strings are serialized with `S` markers.
19385 
19386     @note Any UBJSON output created @ref to_ubjson can be successfully parsed
19387           by @ref from_ubjson.
19388 
19389     @note If NaN or Infinity are stored inside a JSON number, they are
19390           serialized properly. This behavior differs from the @ref dump()
19391           function which serializes NaN or Infinity to `null`.
19392 
19393     @note The optimized formats for containers are supported: Parameter
19394           @a use_size adds size information to the beginning of a container and
19395           removes the closing marker. Parameter @a use_type further checks
19396           whether all elements of a container have the same type and adds the
19397           type marker to the beginning of the container. The @a use_type
19398           parameter must only be used together with @a use_size = true. Note
19399           that @a use_size = true alone may result in larger representations -
19400           the benefit of this parameter is that the receiving side is
19401           immediately informed on the number of elements of the container.
19402 
19403     @param[in] j  JSON value to serialize
19404     @param[in] use_size  whether to add size annotations to container types
19405     @param[in] use_type  whether to add type annotations to container types
19406                          (must be combined with @a use_size = true)
19407     @return UBJSON serialization as byte vector
19408 
19409     @complexity Linear in the size of the JSON value @a j.
19410 
19411     @liveexample{The example shows the serialization of a JSON value to a byte
19412     vector in UBJSON format.,to_ubjson}
19413 
19414     @sa http://ubjson.org
19415     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19416         analogous deserialization
19417     @sa @ref to_cbor(const basic_json& for the related CBOR format
19418     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19419 
19420     @since version 3.1.0
19421     */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)19422     static std::vector<uint8_t> to_ubjson(const basic_json& j,
19423                                           const bool use_size = false,
19424                                           const bool use_type = false)
19425     {
19426         std::vector<uint8_t> result;
19427         to_ubjson(j, result, use_size, use_type);
19428         return result;
19429     }
19430 
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)19431     static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
19432                           const bool use_size = false, const bool use_type = false)
19433     {
19434         binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
19435     }
19436 
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)19437     static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
19438                           const bool use_size = false, const bool use_type = false)
19439     {
19440         binary_writer<char>(o).write_ubjson(j, use_size, use_type);
19441     }
19442 
19443 
19444     /*!
19445     @brief Serializes the given JSON object `j` to BSON and returns a vector
19446            containing the corresponding BSON-representation.
19447 
19448     BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
19449     stored as a single entity (a so-called document).
19450 
19451     The library uses the following mapping from JSON values types to BSON types:
19452 
19453     JSON value type | value/range                       | BSON type   | marker
19454     --------------- | --------------------------------- | ----------- | ------
19455     null            | `null`                            | null        | 0x0A
19456     boolean         | `true`, `false`                   | boolean     | 0x08
19457     number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
19458     number_integer  | -2147483648..2147483647           | int32       | 0x10
19459     number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
19460     number_unsigned | 0..2147483647                     | int32       | 0x10
19461     number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
19462     number_unsigned | 9223372036854775808..18446744073709551615| --   | --
19463     number_float    | *any value*                       | double      | 0x01
19464     string          | *any value*                       | string      | 0x02
19465     array           | *any value*                       | document    | 0x04
19466     object          | *any value*                       | document    | 0x03
19467 
19468     @warning The mapping is **incomplete**, since only JSON-objects (and things
19469     contained therein) can be serialized to BSON.
19470     Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
19471     and the keys may not contain U+0000, since they are serialized a
19472     zero-terminated c-strings.
19473 
19474     @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
19475     @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
19476     @throw type_error.317    if `!j.is_object()`
19477 
19478     @pre The input `j` is required to be an object: `j.is_object() == true`.
19479 
19480     @note Any BSON output created via @ref to_bson can be successfully parsed
19481           by @ref from_bson.
19482 
19483     @param[in] j  JSON value to serialize
19484     @return BSON serialization as byte vector
19485 
19486     @complexity Linear in the size of the JSON value @a j.
19487 
19488     @liveexample{The example shows the serialization of a JSON value to a byte
19489     vector in BSON format.,to_bson}
19490 
19491     @sa http://bsonspec.org/spec.html
19492     @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
19493         analogous deserialization
19494     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19495              related UBJSON format
19496     @sa @ref to_cbor(const basic_json&) for the related CBOR format
19497     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19498     */
to_bson(const basic_json & j)19499     static std::vector<uint8_t> to_bson(const basic_json& j)
19500     {
19501         std::vector<uint8_t> result;
19502         to_bson(j, result);
19503         return result;
19504     }
19505 
19506     /*!
19507     @brief Serializes the given JSON object `j` to BSON and forwards the
19508            corresponding BSON-representation to the given output_adapter `o`.
19509     @param j The JSON object to convert to BSON.
19510     @param o The output adapter that receives the binary BSON representation.
19511     @pre The input `j` shall be an object: `j.is_object() == true`
19512     @sa @ref to_bson(const basic_json&)
19513     */
to_bson(const basic_json & j,detail::output_adapter<uint8_t> o)19514     static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
19515     {
19516         binary_writer<uint8_t>(o).write_bson(j);
19517     }
19518 
19519     /*!
19520     @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
19521     */
to_bson(const basic_json & j,detail::output_adapter<char> o)19522     static void to_bson(const basic_json& j, detail::output_adapter<char> o)
19523     {
19524         binary_writer<char>(o).write_bson(j);
19525     }
19526 
19527 
19528     /*!
19529     @brief create a JSON value from an input in CBOR format
19530 
19531     Deserializes a given input @a i to a JSON value using the CBOR (Concise
19532     Binary Object Representation) serialization format.
19533 
19534     The library maps CBOR types to JSON value types as follows:
19535 
19536     CBOR type              | JSON value type | first byte
19537     ---------------------- | --------------- | ----------
19538     Integer                | number_unsigned | 0x00..0x17
19539     Unsigned integer       | number_unsigned | 0x18
19540     Unsigned integer       | number_unsigned | 0x19
19541     Unsigned integer       | number_unsigned | 0x1A
19542     Unsigned integer       | number_unsigned | 0x1B
19543     Negative integer       | number_integer  | 0x20..0x37
19544     Negative integer       | number_integer  | 0x38
19545     Negative integer       | number_integer  | 0x39
19546     Negative integer       | number_integer  | 0x3A
19547     Negative integer       | number_integer  | 0x3B
19548     Negative integer       | number_integer  | 0x40..0x57
19549     UTF-8 string           | string          | 0x60..0x77
19550     UTF-8 string           | string          | 0x78
19551     UTF-8 string           | string          | 0x79
19552     UTF-8 string           | string          | 0x7A
19553     UTF-8 string           | string          | 0x7B
19554     UTF-8 string           | string          | 0x7F
19555     array                  | array           | 0x80..0x97
19556     array                  | array           | 0x98
19557     array                  | array           | 0x99
19558     array                  | array           | 0x9A
19559     array                  | array           | 0x9B
19560     array                  | array           | 0x9F
19561     map                    | object          | 0xA0..0xB7
19562     map                    | object          | 0xB8
19563     map                    | object          | 0xB9
19564     map                    | object          | 0xBA
19565     map                    | object          | 0xBB
19566     map                    | object          | 0xBF
19567     False                  | `false`         | 0xF4
19568     True                   | `true`          | 0xF5
19569     Null                   | `null`          | 0xF6
19570     Half-Precision Float   | number_float    | 0xF9
19571     Single-Precision Float | number_float    | 0xFA
19572     Double-Precision Float | number_float    | 0xFB
19573 
19574     @warning The mapping is **incomplete** in the sense that not all CBOR
19575              types can be converted to a JSON value. The following CBOR types
19576              are not supported and will yield parse errors (parse_error.112):
19577              - byte strings (0x40..0x5F)
19578              - date/time (0xC0..0xC1)
19579              - bignum (0xC2..0xC3)
19580              - decimal fraction (0xC4)
19581              - bigfloat (0xC5)
19582              - tagged items (0xC6..0xD4, 0xD8..0xDB)
19583              - expected conversions (0xD5..0xD7)
19584              - simple values (0xE0..0xF3, 0xF8)
19585              - undefined (0xF7)
19586 
19587     @warning CBOR allows map keys of any type, whereas JSON only allows
19588              strings as keys in object values. Therefore, CBOR maps with keys
19589              other than UTF-8 strings are rejected (parse_error.113).
19590 
19591     @note Any CBOR output created @ref to_cbor can be successfully parsed by
19592           @ref from_cbor.
19593 
19594     @param[in] i  an input in CBOR format convertible to an input adapter
19595     @param[in] strict  whether to expect the input to be consumed until EOF
19596                        (true by default)
19597     @param[in] allow_exceptions  whether to throw exceptions in case of a
19598     parse error (optional, true by default)
19599 
19600     @return deserialized JSON value; in case of a parse error and
19601             @a allow_exceptions set to `false`, the return value will be
19602             value_t::discarded.
19603 
19604     @throw parse_error.110 if the given input ends prematurely or the end of
19605     file was not reached when @a strict was set to true
19606     @throw parse_error.112 if unsupported features from CBOR were
19607     used in the given input @a v or if the input is not valid CBOR
19608     @throw parse_error.113 if a string was expected as map key, but not found
19609 
19610     @complexity Linear in the size of the input @a i.
19611 
19612     @liveexample{The example shows the deserialization of a byte vector in CBOR
19613     format to a JSON value.,from_cbor}
19614 
19615     @sa http://cbor.io
19616     @sa @ref to_cbor(const basic_json&) for the analogous serialization
19617     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
19618         related MessagePack format
19619     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19620         related UBJSON format
19621 
19622     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
19623            consume input adapters, removed start_index parameter, and added
19624            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
19625            since 3.2.0
19626     */
19627     JSON_NODISCARD
from_cbor(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19628     static basic_json from_cbor(detail::input_adapter&& i,
19629                                 const bool strict = true,
19630                                 const bool allow_exceptions = true)
19631     {
19632         basic_json result;
19633         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19634         const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
19635         return res ? result : basic_json(value_t::discarded);
19636     }
19637 
19638     /*!
19639     @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
19640     */
19641     template<typename A1, typename A2,
19642              detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19643     JSON_NODISCARD
from_cbor(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19644     static basic_json from_cbor(A1 && a1, A2 && a2,
19645                                 const bool strict = true,
19646                                 const bool allow_exceptions = true)
19647     {
19648         basic_json result;
19649         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19650         const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
19651         return res ? result : basic_json(value_t::discarded);
19652     }
19653 
19654     /*!
19655     @brief create a JSON value from an input in MessagePack format
19656 
19657     Deserializes a given input @a i to a JSON value using the MessagePack
19658     serialization format.
19659 
19660     The library maps MessagePack types to JSON value types as follows:
19661 
19662     MessagePack type | JSON value type | first byte
19663     ---------------- | --------------- | ----------
19664     positive fixint  | number_unsigned | 0x00..0x7F
19665     fixmap           | object          | 0x80..0x8F
19666     fixarray         | array           | 0x90..0x9F
19667     fixstr           | string          | 0xA0..0xBF
19668     nil              | `null`          | 0xC0
19669     false            | `false`         | 0xC2
19670     true             | `true`          | 0xC3
19671     float 32         | number_float    | 0xCA
19672     float 64         | number_float    | 0xCB
19673     uint 8           | number_unsigned | 0xCC
19674     uint 16          | number_unsigned | 0xCD
19675     uint 32          | number_unsigned | 0xCE
19676     uint 64          | number_unsigned | 0xCF
19677     int 8            | number_integer  | 0xD0
19678     int 16           | number_integer  | 0xD1
19679     int 32           | number_integer  | 0xD2
19680     int 64           | number_integer  | 0xD3
19681     str 8            | string          | 0xD9
19682     str 16           | string          | 0xDA
19683     str 32           | string          | 0xDB
19684     array 16         | array           | 0xDC
19685     array 32         | array           | 0xDD
19686     map 16           | object          | 0xDE
19687     map 32           | object          | 0xDF
19688     negative fixint  | number_integer  | 0xE0-0xFF
19689 
19690     @warning The mapping is **incomplete** in the sense that not all
19691              MessagePack types can be converted to a JSON value. The following
19692              MessagePack types are not supported and will yield parse errors:
19693               - bin 8 - bin 32 (0xC4..0xC6)
19694               - ext 8 - ext 32 (0xC7..0xC9)
19695               - fixext 1 - fixext 16 (0xD4..0xD8)
19696 
19697     @note Any MessagePack output created @ref to_msgpack can be successfully
19698           parsed by @ref from_msgpack.
19699 
19700     @param[in] i  an input in MessagePack format convertible to an input
19701                   adapter
19702     @param[in] strict  whether to expect the input to be consumed until EOF
19703                        (true by default)
19704     @param[in] allow_exceptions  whether to throw exceptions in case of a
19705     parse error (optional, true by default)
19706 
19707     @return deserialized JSON value; in case of a parse error and
19708             @a allow_exceptions set to `false`, the return value will be
19709             value_t::discarded.
19710 
19711     @throw parse_error.110 if the given input ends prematurely or the end of
19712     file was not reached when @a strict was set to true
19713     @throw parse_error.112 if unsupported features from MessagePack were
19714     used in the given input @a i or if the input is not valid MessagePack
19715     @throw parse_error.113 if a string was expected as map key, but not found
19716 
19717     @complexity Linear in the size of the input @a i.
19718 
19719     @liveexample{The example shows the deserialization of a byte vector in
19720     MessagePack format to a JSON value.,from_msgpack}
19721 
19722     @sa http://msgpack.org
19723     @sa @ref to_msgpack(const basic_json&) for the analogous serialization
19724     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19725         related CBOR format
19726     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
19727         the related UBJSON format
19728     @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
19729         the related BSON format
19730 
19731     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
19732            consume input adapters, removed start_index parameter, and added
19733            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
19734            since 3.2.0
19735     */
19736     JSON_NODISCARD
from_msgpack(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19737     static basic_json from_msgpack(detail::input_adapter&& i,
19738                                    const bool strict = true,
19739                                    const bool allow_exceptions = true)
19740     {
19741         basic_json result;
19742         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19743         const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
19744         return res ? result : basic_json(value_t::discarded);
19745     }
19746 
19747     /*!
19748     @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
19749     */
19750     template<typename A1, typename A2,
19751              detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19752     JSON_NODISCARD
from_msgpack(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19753     static basic_json from_msgpack(A1 && a1, A2 && a2,
19754                                    const bool strict = true,
19755                                    const bool allow_exceptions = true)
19756     {
19757         basic_json result;
19758         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19759         const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
19760         return res ? result : basic_json(value_t::discarded);
19761     }
19762 
19763     /*!
19764     @brief create a JSON value from an input in UBJSON format
19765 
19766     Deserializes a given input @a i to a JSON value using the UBJSON (Universal
19767     Binary JSON) serialization format.
19768 
19769     The library maps UBJSON types to JSON value types as follows:
19770 
19771     UBJSON type | JSON value type                         | marker
19772     ----------- | --------------------------------------- | ------
19773     no-op       | *no value, next value is read*          | `N`
19774     null        | `null`                                  | `Z`
19775     false       | `false`                                 | `F`
19776     true        | `true`                                  | `T`
19777     float32     | number_float                            | `d`
19778     float64     | number_float                            | `D`
19779     uint8       | number_unsigned                         | `U`
19780     int8        | number_integer                          | `i`
19781     int16       | number_integer                          | `I`
19782     int32       | number_integer                          | `l`
19783     int64       | number_integer                          | `L`
19784     string      | string                                  | `S`
19785     char        | string                                  | `C`
19786     array       | array (optimized values are supported)  | `[`
19787     object      | object (optimized values are supported) | `{`
19788 
19789     @note The mapping is **complete** in the sense that any UBJSON value can
19790           be converted to a JSON value.
19791 
19792     @param[in] i  an input in UBJSON format convertible to an input adapter
19793     @param[in] strict  whether to expect the input to be consumed until EOF
19794                        (true by default)
19795     @param[in] allow_exceptions  whether to throw exceptions in case of a
19796     parse error (optional, true by default)
19797 
19798     @return deserialized JSON value; in case of a parse error and
19799             @a allow_exceptions set to `false`, the return value will be
19800             value_t::discarded.
19801 
19802     @throw parse_error.110 if the given input ends prematurely or the end of
19803     file was not reached when @a strict was set to true
19804     @throw parse_error.112 if a parse error occurs
19805     @throw parse_error.113 if a string could not be parsed successfully
19806 
19807     @complexity Linear in the size of the input @a i.
19808 
19809     @liveexample{The example shows the deserialization of a byte vector in
19810     UBJSON format to a JSON value.,from_ubjson}
19811 
19812     @sa http://ubjson.org
19813     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19814              analogous serialization
19815     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19816         related CBOR format
19817     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
19818         the related MessagePack format
19819     @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
19820         the related BSON format
19821 
19822     @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
19823     */
19824     JSON_NODISCARD
from_ubjson(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19825     static basic_json from_ubjson(detail::input_adapter&& i,
19826                                   const bool strict = true,
19827                                   const bool allow_exceptions = true)
19828     {
19829         basic_json result;
19830         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19831         const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
19832         return res ? result : basic_json(value_t::discarded);
19833     }
19834 
19835     /*!
19836     @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
19837     */
19838     template<typename A1, typename A2,
19839              detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19840     JSON_NODISCARD
from_ubjson(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19841     static basic_json from_ubjson(A1 && a1, A2 && a2,
19842                                   const bool strict = true,
19843                                   const bool allow_exceptions = true)
19844     {
19845         basic_json result;
19846         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19847         const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
19848         return res ? result : basic_json(value_t::discarded);
19849     }
19850 
19851     /*!
19852     @brief Create a JSON value from an input in BSON format
19853 
19854     Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
19855     serialization format.
19856 
19857     The library maps BSON record types to JSON value types as follows:
19858 
19859     BSON type       | BSON marker byte | JSON value type
19860     --------------- | ---------------- | ---------------------------
19861     double          | 0x01             | number_float
19862     string          | 0x02             | string
19863     document        | 0x03             | object
19864     array           | 0x04             | array
19865     binary          | 0x05             | still unsupported
19866     undefined       | 0x06             | still unsupported
19867     ObjectId        | 0x07             | still unsupported
19868     boolean         | 0x08             | boolean
19869     UTC Date-Time   | 0x09             | still unsupported
19870     null            | 0x0A             | null
19871     Regular Expr.   | 0x0B             | still unsupported
19872     DB Pointer      | 0x0C             | still unsupported
19873     JavaScript Code | 0x0D             | still unsupported
19874     Symbol          | 0x0E             | still unsupported
19875     JavaScript Code | 0x0F             | still unsupported
19876     int32           | 0x10             | number_integer
19877     Timestamp       | 0x11             | still unsupported
19878     128-bit decimal float | 0x13       | still unsupported
19879     Max Key         | 0x7F             | still unsupported
19880     Min Key         | 0xFF             | still unsupported
19881 
19882     @warning The mapping is **incomplete**. The unsupported mappings
19883              are indicated in the table above.
19884 
19885     @param[in] i  an input in BSON format convertible to an input adapter
19886     @param[in] strict  whether to expect the input to be consumed until EOF
19887                        (true by default)
19888     @param[in] allow_exceptions  whether to throw exceptions in case of a
19889     parse error (optional, true by default)
19890 
19891     @return deserialized JSON value; in case of a parse error and
19892             @a allow_exceptions set to `false`, the return value will be
19893             value_t::discarded.
19894 
19895     @throw parse_error.114 if an unsupported BSON record type is encountered
19896 
19897     @complexity Linear in the size of the input @a i.
19898 
19899     @liveexample{The example shows the deserialization of a byte vector in
19900     BSON format to a JSON value.,from_bson}
19901 
19902     @sa http://bsonspec.org/spec.html
19903     @sa @ref to_bson(const basic_json&) for the analogous serialization
19904     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19905         related CBOR format
19906     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
19907         the related MessagePack format
19908     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19909         related UBJSON format
19910     */
19911     JSON_NODISCARD
from_bson(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19912     static basic_json from_bson(detail::input_adapter&& i,
19913                                 const bool strict = true,
19914                                 const bool allow_exceptions = true)
19915     {
19916         basic_json result;
19917         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19918         const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
19919         return res ? result : basic_json(value_t::discarded);
19920     }
19921 
19922     /*!
19923     @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
19924     */
19925     template<typename A1, typename A2,
19926              detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19927     JSON_NODISCARD
from_bson(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19928     static basic_json from_bson(A1 && a1, A2 && a2,
19929                                 const bool strict = true,
19930                                 const bool allow_exceptions = true)
19931     {
19932         basic_json result;
19933         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19934         const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
19935         return res ? result : basic_json(value_t::discarded);
19936     }
19937 
19938 
19939 
19940     /// @}
19941 
19942     //////////////////////////
19943     // JSON Pointer support //
19944     //////////////////////////
19945 
19946     /// @name JSON Pointer functions
19947     /// @{
19948 
19949     /*!
19950     @brief access specified element via JSON Pointer
19951 
19952     Uses a JSON pointer to retrieve a reference to the respective JSON value.
19953     No bound checking is performed. Similar to @ref operator[](const typename
19954     object_t::key_type&), `null` values are created in arrays and objects if
19955     necessary.
19956 
19957     In particular:
19958     - If the JSON pointer points to an object key that does not exist, it
19959       is created an filled with a `null` value before a reference to it
19960       is returned.
19961     - If the JSON pointer points to an array index that does not exist, it
19962       is created an filled with a `null` value before a reference to it
19963       is returned. All indices between the current maximum and the given
19964       index are also filled with `null`.
19965     - The special value `-` is treated as a synonym for the index past the
19966       end.
19967 
19968     @param[in] ptr  a JSON pointer
19969 
19970     @return reference to the element pointed to by @a ptr
19971 
19972     @complexity Constant.
19973 
19974     @throw parse_error.106   if an array index begins with '0'
19975     @throw parse_error.109   if an array index was not a number
19976     @throw out_of_range.404  if the JSON pointer can not be resolved
19977 
19978     @liveexample{The behavior is shown in the example.,operatorjson_pointer}
19979 
19980     @since version 2.0.0
19981     */
operator [](const json_pointer & ptr)19982     reference operator[](const json_pointer& ptr)
19983     {
19984         return ptr.get_unchecked(this);
19985     }
19986 
19987     /*!
19988     @brief access specified element via JSON Pointer
19989 
19990     Uses a JSON pointer to retrieve a reference to the respective JSON value.
19991     No bound checking is performed. The function does not change the JSON
19992     value; no `null` values are created. In particular, the the special value
19993     `-` yields an exception.
19994 
19995     @param[in] ptr  JSON pointer to the desired element
19996 
19997     @return const reference to the element pointed to by @a ptr
19998 
19999     @complexity Constant.
20000 
20001     @throw parse_error.106   if an array index begins with '0'
20002     @throw parse_error.109   if an array index was not a number
20003     @throw out_of_range.402  if the array index '-' is used
20004     @throw out_of_range.404  if the JSON pointer can not be resolved
20005 
20006     @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
20007 
20008     @since version 2.0.0
20009     */
operator [](const json_pointer & ptr) const20010     const_reference operator[](const json_pointer& ptr) const
20011     {
20012         return ptr.get_unchecked(this);
20013     }
20014 
20015     /*!
20016     @brief access specified element via JSON Pointer
20017 
20018     Returns a reference to the element at with specified JSON pointer @a ptr,
20019     with bounds checking.
20020 
20021     @param[in] ptr  JSON pointer to the desired element
20022 
20023     @return reference to the element pointed to by @a ptr
20024 
20025     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
20026     begins with '0'. See example below.
20027 
20028     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
20029     is not a number. See example below.
20030 
20031     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
20032     is out of range. See example below.
20033 
20034     @throw out_of_range.402 if the array index '-' is used in the passed JSON
20035     pointer @a ptr. As `at` provides checked access (and no elements are
20036     implicitly inserted), the index '-' is always invalid. See example below.
20037 
20038     @throw out_of_range.403 if the JSON pointer describes a key of an object
20039     which cannot be found. See example below.
20040 
20041     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
20042     See example below.
20043 
20044     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20045     changes in the JSON value.
20046 
20047     @complexity Constant.
20048 
20049     @since version 2.0.0
20050 
20051     @liveexample{The behavior is shown in the example.,at_json_pointer}
20052     */
at(const json_pointer & ptr)20053     reference at(const json_pointer& ptr)
20054     {
20055         return ptr.get_checked(this);
20056     }
20057 
20058     /*!
20059     @brief access specified element via JSON Pointer
20060 
20061     Returns a const reference to the element at with specified JSON pointer @a
20062     ptr, with bounds checking.
20063 
20064     @param[in] ptr  JSON pointer to the desired element
20065 
20066     @return reference to the element pointed to by @a ptr
20067 
20068     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
20069     begins with '0'. See example below.
20070 
20071     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
20072     is not a number. See example below.
20073 
20074     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
20075     is out of range. See example below.
20076 
20077     @throw out_of_range.402 if the array index '-' is used in the passed JSON
20078     pointer @a ptr. As `at` provides checked access (and no elements are
20079     implicitly inserted), the index '-' is always invalid. See example below.
20080 
20081     @throw out_of_range.403 if the JSON pointer describes a key of an object
20082     which cannot be found. See example below.
20083 
20084     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
20085     See example below.
20086 
20087     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20088     changes in the JSON value.
20089 
20090     @complexity Constant.
20091 
20092     @since version 2.0.0
20093 
20094     @liveexample{The behavior is shown in the example.,at_json_pointer_const}
20095     */
at(const json_pointer & ptr) const20096     const_reference at(const json_pointer& ptr) const
20097     {
20098         return ptr.get_checked(this);
20099     }
20100 
20101     /*!
20102     @brief return flattened JSON value
20103 
20104     The function creates a JSON object whose keys are JSON pointers (see [RFC
20105     6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
20106     primitive. The original JSON value can be restored using the @ref
20107     unflatten() function.
20108 
20109     @return an object that maps JSON pointers to primitive values
20110 
20111     @note Empty objects and arrays are flattened to `null` and will not be
20112           reconstructed correctly by the @ref unflatten() function.
20113 
20114     @complexity Linear in the size the JSON value.
20115 
20116     @liveexample{The following code shows how a JSON object is flattened to an
20117     object whose keys consist of JSON pointers.,flatten}
20118 
20119     @sa @ref unflatten() for the reverse function
20120 
20121     @since version 2.0.0
20122     */
flatten() const20123     basic_json flatten() const
20124     {
20125         basic_json result(value_t::object);
20126         json_pointer::flatten("", *this, result);
20127         return result;
20128     }
20129 
20130     /*!
20131     @brief unflatten a previously flattened JSON value
20132 
20133     The function restores the arbitrary nesting of a JSON value that has been
20134     flattened before using the @ref flatten() function. The JSON value must
20135     meet certain constraints:
20136     1. The value must be an object.
20137     2. The keys must be JSON pointers (see
20138        [RFC 6901](https://tools.ietf.org/html/rfc6901))
20139     3. The mapped values must be primitive JSON types.
20140 
20141     @return the original JSON from a flattened version
20142 
20143     @note Empty objects and arrays are flattened by @ref flatten() to `null`
20144           values and can not unflattened to their original type. Apart from
20145           this example, for a JSON value `j`, the following is always true:
20146           `j == j.flatten().unflatten()`.
20147 
20148     @complexity Linear in the size the JSON value.
20149 
20150     @throw type_error.314  if value is not an object
20151     @throw type_error.315  if object values are not primitive
20152 
20153     @liveexample{The following code shows how a flattened JSON object is
20154     unflattened into the original nested JSON object.,unflatten}
20155 
20156     @sa @ref flatten() for the reverse function
20157 
20158     @since version 2.0.0
20159     */
unflatten() const20160     basic_json unflatten() const
20161     {
20162         return json_pointer::unflatten(*this);
20163     }
20164 
20165     /// @}
20166 
20167     //////////////////////////
20168     // JSON Patch functions //
20169     //////////////////////////
20170 
20171     /// @name JSON Patch functions
20172     /// @{
20173 
20174     /*!
20175     @brief applies a JSON patch
20176 
20177     [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
20178     expressing a sequence of operations to apply to a JSON) document. With
20179     this function, a JSON Patch is applied to the current JSON value by
20180     executing all operations from the patch.
20181 
20182     @param[in] json_patch  JSON patch document
20183     @return patched document
20184 
20185     @note The application of a patch is atomic: Either all operations succeed
20186           and the patched document is returned or an exception is thrown. In
20187           any case, the original value is not changed: the patch is applied
20188           to a copy of the value.
20189 
20190     @throw parse_error.104 if the JSON patch does not consist of an array of
20191     objects
20192 
20193     @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
20194     attributes are missing); example: `"operation add must have member path"`
20195 
20196     @throw out_of_range.401 if an array index is out of range.
20197 
20198     @throw out_of_range.403 if a JSON pointer inside the patch could not be
20199     resolved successfully in the current JSON value; example: `"key baz not
20200     found"`
20201 
20202     @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
20203     "move")
20204 
20205     @throw other_error.501 if "test" operation was unsuccessful
20206 
20207     @complexity Linear in the size of the JSON value and the length of the
20208     JSON patch. As usually only a fraction of the JSON value is affected by
20209     the patch, the complexity can usually be neglected.
20210 
20211     @liveexample{The following code shows how a JSON patch is applied to a
20212     value.,patch}
20213 
20214     @sa @ref diff -- create a JSON patch by comparing two JSON values
20215 
20216     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
20217     @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
20218 
20219     @since version 2.0.0
20220     */
patch(const basic_json & json_patch) const20221     basic_json patch(const basic_json& json_patch) const
20222     {
20223         // make a working copy to apply the patch to
20224         basic_json result = *this;
20225 
20226         // the valid JSON Patch operations
20227         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
20228 
20229         const auto get_op = [](const std::string & op)
20230         {
20231             if (op == "add")
20232             {
20233                 return patch_operations::add;
20234             }
20235             if (op == "remove")
20236             {
20237                 return patch_operations::remove;
20238             }
20239             if (op == "replace")
20240             {
20241                 return patch_operations::replace;
20242             }
20243             if (op == "move")
20244             {
20245                 return patch_operations::move;
20246             }
20247             if (op == "copy")
20248             {
20249                 return patch_operations::copy;
20250             }
20251             if (op == "test")
20252             {
20253                 return patch_operations::test;
20254             }
20255 
20256             return patch_operations::invalid;
20257         };
20258 
20259         // wrapper for "add" operation; add value at ptr
20260         const auto operation_add = [&result](json_pointer & ptr, basic_json val)
20261         {
20262             // adding to the root of the target document means replacing it
20263             if (ptr.empty())
20264             {
20265                 result = val;
20266                 return;
20267             }
20268 
20269             // make sure the top element of the pointer exists
20270             json_pointer top_pointer = ptr.top();
20271             if (top_pointer != ptr)
20272             {
20273                 result.at(top_pointer);
20274             }
20275 
20276             // get reference to parent of JSON pointer ptr
20277             const auto last_path = ptr.back();
20278             ptr.pop_back();
20279             basic_json& parent = result[ptr];
20280 
20281             switch (parent.m_type)
20282             {
20283                 case value_t::null:
20284                 case value_t::object:
20285                 {
20286                     // use operator[] to add value
20287                     parent[last_path] = val;
20288                     break;
20289                 }
20290 
20291                 case value_t::array:
20292                 {
20293                     if (last_path == "-")
20294                     {
20295                         // special case: append to back
20296                         parent.push_back(val);
20297                     }
20298                     else
20299                     {
20300                         const auto idx = json_pointer::array_index(last_path);
20301                         if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
20302                         {
20303                             // avoid undefined behavior
20304                             JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20305                         }
20306 
20307                         // default case: insert add offset
20308                         parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
20309                     }
20310                     break;
20311                 }
20312 
20313                 // if there exists a parent it cannot be primitive
20314                 default:            // LCOV_EXCL_LINE
20315                     assert(false);  // LCOV_EXCL_LINE
20316             }
20317         };
20318 
20319         // wrapper for "remove" operation; remove value at ptr
20320         const auto operation_remove = [&result](json_pointer & ptr)
20321         {
20322             // get reference to parent of JSON pointer ptr
20323             const auto last_path = ptr.back();
20324             ptr.pop_back();
20325             basic_json& parent = result.at(ptr);
20326 
20327             // remove child
20328             if (parent.is_object())
20329             {
20330                 // perform range check
20331                 auto it = parent.find(last_path);
20332                 if (JSON_LIKELY(it != parent.end()))
20333                 {
20334                     parent.erase(it);
20335                 }
20336                 else
20337                 {
20338                     JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
20339                 }
20340             }
20341             else if (parent.is_array())
20342             {
20343                 // note erase performs range check
20344                 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
20345             }
20346         };
20347 
20348         // type check: top level value must be an array
20349         if (JSON_UNLIKELY(not json_patch.is_array()))
20350         {
20351             JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
20352         }
20353 
20354         // iterate and apply the operations
20355         for (const auto& val : json_patch)
20356         {
20357             // wrapper to get a value for an operation
20358             const auto get_value = [&val](const std::string & op,
20359                                           const std::string & member,
20360                                           bool string_type) -> basic_json &
20361             {
20362                 // find value
20363                 auto it = val.m_value.object->find(member);
20364 
20365                 // context-sensitive error message
20366                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
20367 
20368                 // check if desired value is present
20369                 if (JSON_UNLIKELY(it == val.m_value.object->end()))
20370                 {
20371                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
20372                 }
20373 
20374                 // check if result is of type string
20375                 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
20376                 {
20377                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
20378                 }
20379 
20380                 // no error: return value
20381                 return it->second;
20382             };
20383 
20384             // type check: every element of the array must be an object
20385             if (JSON_UNLIKELY(not val.is_object()))
20386             {
20387                 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
20388             }
20389 
20390             // collect mandatory members
20391             const std::string op = get_value("op", "op", true);
20392             const std::string path = get_value(op, "path", true);
20393             json_pointer ptr(path);
20394 
20395             switch (get_op(op))
20396             {
20397                 case patch_operations::add:
20398                 {
20399                     operation_add(ptr, get_value("add", "value", false));
20400                     break;
20401                 }
20402 
20403                 case patch_operations::remove:
20404                 {
20405                     operation_remove(ptr);
20406                     break;
20407                 }
20408 
20409                 case patch_operations::replace:
20410                 {
20411                     // the "path" location must exist - use at()
20412                     result.at(ptr) = get_value("replace", "value", false);
20413                     break;
20414                 }
20415 
20416                 case patch_operations::move:
20417                 {
20418                     const std::string from_path = get_value("move", "from", true);
20419                     json_pointer from_ptr(from_path);
20420 
20421                     // the "from" location must exist - use at()
20422                     basic_json v = result.at(from_ptr);
20423 
20424                     // The move operation is functionally identical to a
20425                     // "remove" operation on the "from" location, followed
20426                     // immediately by an "add" operation at the target
20427                     // location with the value that was just removed.
20428                     operation_remove(from_ptr);
20429                     operation_add(ptr, v);
20430                     break;
20431                 }
20432 
20433                 case patch_operations::copy:
20434                 {
20435                     const std::string from_path = get_value("copy", "from", true);
20436                     const json_pointer from_ptr(from_path);
20437 
20438                     // the "from" location must exist - use at()
20439                     basic_json v = result.at(from_ptr);
20440 
20441                     // The copy is functionally identical to an "add"
20442                     // operation at the target location using the value
20443                     // specified in the "from" member.
20444                     operation_add(ptr, v);
20445                     break;
20446                 }
20447 
20448                 case patch_operations::test:
20449                 {
20450                     bool success = false;
20451                     JSON_TRY
20452                     {
20453                         // check if "value" matches the one at "path"
20454                         // the "path" location must exist - use at()
20455                         success = (result.at(ptr) == get_value("test", "value", false));
20456                     }
20457                     JSON_INTERNAL_CATCH (out_of_range&)
20458                     {
20459                         // ignore out of range errors: success remains false
20460                     }
20461 
20462                     // throw an exception if test fails
20463                     if (JSON_UNLIKELY(not success))
20464                     {
20465                         JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
20466                     }
20467 
20468                     break;
20469                 }
20470 
20471                 default:
20472                 {
20473                     // op must be "add", "remove", "replace", "move", "copy", or
20474                     // "test"
20475                     JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
20476                 }
20477             }
20478         }
20479 
20480         return result;
20481     }
20482 
20483     /*!
20484     @brief creates a diff as a JSON patch
20485 
20486     Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
20487     be changed into the value @a target by calling @ref patch function.
20488 
20489     @invariant For two JSON values @a source and @a target, the following code
20490     yields always `true`:
20491     @code {.cpp}
20492     source.patch(diff(source, target)) == target;
20493     @endcode
20494 
20495     @note Currently, only `remove`, `add`, and `replace` operations are
20496           generated.
20497 
20498     @param[in] source  JSON value to compare from
20499     @param[in] target  JSON value to compare against
20500     @param[in] path    helper value to create JSON pointers
20501 
20502     @return a JSON patch to convert the @a source to @a target
20503 
20504     @complexity Linear in the lengths of @a source and @a target.
20505 
20506     @liveexample{The following code shows how a JSON patch is created as a
20507     diff for two JSON values.,diff}
20508 
20509     @sa @ref patch -- apply a JSON patch
20510     @sa @ref merge_patch -- apply a JSON Merge Patch
20511 
20512     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
20513 
20514     @since version 2.0.0
20515     */
20516     JSON_NODISCARD
diff(const basic_json & source,const basic_json & target,const std::string & path="")20517     static basic_json diff(const basic_json& source, const basic_json& target,
20518                            const std::string& path = "")
20519     {
20520         // the patch
20521         basic_json result(value_t::array);
20522 
20523         // if the values are the same, return empty patch
20524         if (source == target)
20525         {
20526             return result;
20527         }
20528 
20529         if (source.type() != target.type())
20530         {
20531             // different types: replace value
20532             result.push_back(
20533             {
20534                 {"op", "replace"}, {"path", path}, {"value", target}
20535             });
20536             return result;
20537         }
20538 
20539         switch (source.type())
20540         {
20541             case value_t::array:
20542             {
20543                 // first pass: traverse common elements
20544                 std::size_t i = 0;
20545                 while (i < source.size() and i < target.size())
20546                 {
20547                     // recursive call to compare array values at index i
20548                     auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
20549                     result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20550                     ++i;
20551                 }
20552 
20553                 // i now reached the end of at least one array
20554                 // in a second pass, traverse the remaining elements
20555 
20556                 // remove my remaining elements
20557                 const auto end_index = static_cast<difference_type>(result.size());
20558                 while (i < source.size())
20559                 {
20560                     // add operations in reverse order to avoid invalid
20561                     // indices
20562                     result.insert(result.begin() + end_index, object(
20563                     {
20564                         {"op", "remove"},
20565                         {"path", path + "/" + std::to_string(i)}
20566                     }));
20567                     ++i;
20568                 }
20569 
20570                 // add other remaining elements
20571                 while (i < target.size())
20572                 {
20573                     result.push_back(
20574                     {
20575                         {"op", "add"},
20576                         {"path", path + "/" + std::to_string(i)},
20577                         {"value", target[i]}
20578                     });
20579                     ++i;
20580                 }
20581 
20582                 break;
20583             }
20584 
20585             case value_t::object:
20586             {
20587                 // first pass: traverse this object's elements
20588                 for (auto it = source.cbegin(); it != source.cend(); ++it)
20589                 {
20590                     // escape the key name to be used in a JSON patch
20591                     const auto key = json_pointer::escape(it.key());
20592 
20593                     if (target.find(it.key()) != target.end())
20594                     {
20595                         // recursive call to compare object values at key it
20596                         auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
20597                         result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20598                     }
20599                     else
20600                     {
20601                         // found a key that is not in o -> remove it
20602                         result.push_back(object(
20603                         {
20604                             {"op", "remove"}, {"path", path + "/" + key}
20605                         }));
20606                     }
20607                 }
20608 
20609                 // second pass: traverse other object's elements
20610                 for (auto it = target.cbegin(); it != target.cend(); ++it)
20611                 {
20612                     if (source.find(it.key()) == source.end())
20613                     {
20614                         // found a key that is not in this -> add it
20615                         const auto key = json_pointer::escape(it.key());
20616                         result.push_back(
20617                         {
20618                             {"op", "add"}, {"path", path + "/" + key},
20619                             {"value", it.value()}
20620                         });
20621                     }
20622                 }
20623 
20624                 break;
20625             }
20626 
20627             default:
20628             {
20629                 // both primitive type: replace value
20630                 result.push_back(
20631                 {
20632                     {"op", "replace"}, {"path", path}, {"value", target}
20633                 });
20634                 break;
20635             }
20636         }
20637 
20638         return result;
20639     }
20640 
20641     /// @}
20642 
20643     ////////////////////////////////
20644     // JSON Merge Patch functions //
20645     ////////////////////////////////
20646 
20647     /// @name JSON Merge Patch functions
20648     /// @{
20649 
20650     /*!
20651     @brief applies a JSON Merge Patch
20652 
20653     The merge patch format is primarily intended for use with the HTTP PATCH
20654     method as a means of describing a set of modifications to a target
20655     resource's content. This function applies a merge patch to the current
20656     JSON value.
20657 
20658     The function implements the following algorithm from Section 2 of
20659     [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
20660 
20661     ```
20662     define MergePatch(Target, Patch):
20663       if Patch is an Object:
20664         if Target is not an Object:
20665           Target = {} // Ignore the contents and set it to an empty Object
20666         for each Name/Value pair in Patch:
20667           if Value is null:
20668             if Name exists in Target:
20669               remove the Name/Value pair from Target
20670           else:
20671             Target[Name] = MergePatch(Target[Name], Value)
20672         return Target
20673       else:
20674         return Patch
20675     ```
20676 
20677     Thereby, `Target` is the current object; that is, the patch is applied to
20678     the current value.
20679 
20680     @param[in] apply_patch  the patch to apply
20681 
20682     @complexity Linear in the lengths of @a patch.
20683 
20684     @liveexample{The following code shows how a JSON Merge Patch is applied to
20685     a JSON document.,merge_patch}
20686 
20687     @sa @ref patch -- apply a JSON patch
20688     @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
20689 
20690     @since version 3.0.0
20691     */
merge_patch(const basic_json & apply_patch)20692     void merge_patch(const basic_json& apply_patch)
20693     {
20694         if (apply_patch.is_object())
20695         {
20696             if (not is_object())
20697             {
20698                 *this = object();
20699             }
20700             for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
20701             {
20702                 if (it.value().is_null())
20703                 {
20704                     erase(it.key());
20705                 }
20706                 else
20707                 {
20708                     operator[](it.key()).merge_patch(it.value());
20709                 }
20710             }
20711         }
20712         else
20713         {
20714             *this = apply_patch;
20715         }
20716     }
20717 
20718     /// @}
20719 };
20720 } // namespace nlohmann
20721 
20722 ///////////////////////
20723 // nonmember support //
20724 ///////////////////////
20725 
20726 // specialization of std::swap, and std::hash
20727 namespace std
20728 {
20729 
20730 /// hash value for JSON objects
20731 template<>
20732 struct hash<nlohmann::json>
20733 {
20734     /*!
20735     @brief return a hash value for a JSON object
20736 
20737     @since version 1.0.0
20738     */
operator ()std::hash20739     std::size_t operator()(const nlohmann::json& j) const
20740     {
20741         // a naive hashing via the string representation
20742         const auto& h = hash<nlohmann::json::string_t>();
20743         return h(j.dump());
20744     }
20745 };
20746 
20747 /// specialization for std::less<value_t>
20748 /// @note: do not remove the space after '<',
20749 ///        see https://github.com/nlohmann/json/pull/679
20750 template<>
20751 struct less< ::nlohmann::detail::value_t>
20752 {
20753     /*!
20754     @brief compare two value_t enum values
20755     @since version 3.0.0
20756     */
operator ()std::less20757     bool operator()(nlohmann::detail::value_t lhs,
20758                     nlohmann::detail::value_t rhs) const noexcept
20759     {
20760         return nlohmann::detail::operator<(lhs, rhs);
20761     }
20762 };
20763 
20764 /*!
20765 @brief exchanges the values of two JSON objects
20766 
20767 @since version 1.0.0
20768 */
20769 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)20770 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
20771     is_nothrow_move_constructible<nlohmann::json>::value and
20772     is_nothrow_move_assignable<nlohmann::json>::value
20773 )
20774 {
20775     j1.swap(j2);
20776 }
20777 
20778 } // namespace std
20779 
20780 /*!
20781 @brief user-defined string literal for JSON values
20782 
20783 This operator implements a user-defined string literal for JSON objects. It
20784 can be used by adding `"_json"` to a string literal and returns a JSON object
20785 if no parse error occurred.
20786 
20787 @param[in] s  a string representation of a JSON object
20788 @param[in] n  the length of string @a s
20789 @return a JSON object
20790 
20791 @since version 1.0.0
20792 */
operator ""_json(const char * s,std::size_t n)20793 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
20794 {
20795     return nlohmann::json::parse(s, s + n);
20796 }
20797 
20798 /*!
20799 @brief user-defined string literal for JSON pointer
20800 
20801 This operator implements a user-defined string literal for JSON Pointers. It
20802 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
20803 object if no parse error occurred.
20804 
20805 @param[in] s  a string representation of a JSON Pointer
20806 @param[in] n  the length of string @a s
20807 @return a JSON pointer object
20808 
20809 @since version 2.0.0
20810 */
operator ""_json_pointer(const char * s,std::size_t n)20811 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
20812 {
20813     return nlohmann::json::json_pointer(std::string(s, n));
20814 }
20815 
20816 // #include <nlohmann/detail/macro_unscope.hpp>
20817 
20818 
20819 // restore GCC/clang diagnostic settings
20820 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
20821     #pragma GCC diagnostic pop
20822 #endif
20823 #if defined(__clang__)
20824     #pragma GCC diagnostic pop
20825 #endif
20826 
20827 // clean up
20828 #undef JSON_INTERNAL_CATCH
20829 #undef JSON_CATCH
20830 #undef JSON_THROW
20831 #undef JSON_TRY
20832 #undef JSON_LIKELY
20833 #undef JSON_UNLIKELY
20834 #undef JSON_DEPRECATED
20835 #undef JSON_NODISCARD
20836 #undef JSON_HAS_CPP_14
20837 #undef JSON_HAS_CPP_17
20838 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
20839 #undef NLOHMANN_BASIC_JSON_TPL
20840 
20841 
20842 #endif  // INCLUDE_NLOHMANN_JSON_HPP_
20843