Coverage Report

Created: 2024-02-25 07:28

/src/jsonnet/third_party/json/nlohmann/json.hpp
Line
Count
Source (jump to first uncovered line)
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
99
    constexpr operator size_t() const
100
0
    {
101
0
        return chars_read_total;
102
0
    }
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
149
    const char* what() const noexcept override
150
0
    {
151
0
        return m.what();
152
0
    }
153
154
    /// the id of the exception
155
    const int id;
156
157
  protected:
158
0
    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
159
160
    static std::string name(const std::string& ename, int id_)
161
0
    {
162
0
        return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
163
0
    }
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
    */
226
    static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
227
0
    {
228
0
        std::string w = exception::name("parse_error", id_) + "parse error" +
229
0
                        position_string(pos) + ": " + what_arg;
230
0
        return parse_error(id_, pos.chars_read_total, w.c_str());
231
0
    }
232
233
    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
234
0
    {
235
0
        std::string w = exception::name("parse_error", id_) + "parse error" +
236
0
                        (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
237
0
                        ": " + what_arg;
238
0
        return parse_error(id_, byte_, w.c_str());
239
0
    }
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:
253
    parse_error(int id_, std::size_t byte_, const char* what_arg)
254
0
        : exception(id_, what_arg), byte(byte_) {}
255
256
    static std::string position_string(const position_t& pos)
257
0
    {
258
0
        return " at line " + std::to_string(pos.lines_read + 1) +
259
0
               ", column " + std::to_string(pos.chars_read_current_line);
260
0
    }
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:
303
    static invalid_iterator create(int id_, const std::string& what_arg)
304
0
    {
305
0
        std::string w = exception::name("invalid_iterator", id_) + what_arg;
306
0
        return invalid_iterator(id_, w.c_str());
307
0
    }
308
309
  private:
310
    invalid_iterator(int id_, const char* what_arg)
311
0
        : 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:
356
    static type_error create(int id_, const std::string& what_arg)
357
0
    {
358
0
        std::string w = exception::name("type_error", id_) + what_arg;
359
0
        return type_error(id_, w.c_str());
360
0
    }
361
362
  private:
363
0
    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:
402
    static out_of_range create(int id_, const std::string& what_arg)
403
0
    {
404
0
        std::string w = exception::name("out_of_range", id_) + what_arg;
405
0
        return out_of_range(id_, w.c_str());
406
0
    }
407
408
  private:
409
0
    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:
439
    static other_error create(int id_, const std::string& what_arg)
440
0
    {
441
0
        std::string w = exception::name("other_error", id_) + what_arg;
442
0
        return other_error(id_, w.c_str());
443
0
    }
444
445
  private:
446
0
    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
0
    #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
0
    #define JSON_LIKELY(x)      __builtin_expect(x, 1)
543
0
    #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;
629
    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
*/
1277
inline bool operator<(const value_t lhs, const value_t rhs) noexcept
1278
0
{
1279
0
    static constexpr std::array<std::uint8_t, 8> order = {{
1280
0
            0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
1281
0
            1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
1282
0
        }
1283
0
    };
1284
0
1285
0
    const auto l_index = static_cast<std::size_t>(lhs);
1286
0
    const auto r_index = static_cast<std::size_t>(rhs);
1287
0
    return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1288
0
}
1289
}  // namespace detail
1290
}  // namespace nlohmann
1291
1292
1293
namespace nlohmann
1294
{
1295
namespace detail
1296
{
1297
template<typename BasicJsonType>
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>
1312
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1313
0
{
1314
0
    switch (static_cast<value_t>(j))
1315
0
    {
1316
0
        case value_t::number_unsigned:
1317
0
        {
1318
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1319
0
            break;
1320
0
        }
1321
0
        case value_t::number_integer:
1322
0
        {
1323
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1324
0
            break;
1325
0
        }
1326
0
        case value_t::number_float:
1327
0
        {
1328
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1329
0
            break;
1330
0
        }
1331
1332
0
        default:
1333
0
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1334
0
    }
1335
0
}
1336
1337
template<typename BasicJsonType>
1338
void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1339
0
{
1340
0
    if (JSON_UNLIKELY(not j.is_boolean()))
1341
0
    {
1342
0
        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1343
0
    }
1344
0
    b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1345
0
}
1346
1347
template<typename BasicJsonType>
1348
void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1349
0
{
1350
0
    if (JSON_UNLIKELY(not j.is_string()))
1351
0
    {
1352
0
        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1353
0
    }
1354
0
    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1355
0
}
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 >
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>
1375
void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1376
0
{
1377
0
    get_arithmetic_value(j, val);
1378
0
}
1379
1380
template<typename BasicJsonType>
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>
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>
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>
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>
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>
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>
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>
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>
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
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>
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>
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>
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>
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>
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>>
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>>
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>
1625
    auto operator()(const BasicJsonType& j, T& val) const
1626
    noexcept(noexcept(from_json(j, val)))
1627
    -> decltype(from_json(j, val), void())
1628
0
    {
1629
0
        return from_json(j, val);
1630
0
    }
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, bool>(nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const&, bool&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, double>(nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const&, double&) const
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:
1695
    explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
1696
1697
    /// dereference operator (needed for range-based for)
1698
    iteration_proxy_value& operator*()
1699
    {
1700
        return *this;
1701
    }
1702
1703
    /// increment operator (needed for range-based for)
1704
    iteration_proxy_value& operator++()
1705
    {
1706
        ++anchor;
1707
        ++array_index;
1708
1709
        return *this;
1710
    }
1711
1712
    /// equality operator (needed for InputIterator)
1713
    bool operator==(const iteration_proxy_value& o) const
1714
    {
1715
        return anchor == o.anchor;
1716
    }
1717
1718
    /// inequality operator (needed for range-based for)
1719
    bool operator!=(const iteration_proxy_value& o) const
1720
    {
1721
        return anchor != o.anchor;
1722
    }
1723
1724
    /// return key of the iterator
1725
    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
1753
    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
1768
    explicit iteration_proxy(typename IteratorType::reference cont) noexcept
1769
        : container(cont) {}
1770
1771
    /// return iterator begin (needed for range-based for)
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)
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>
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>
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>
1851
    static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1852
0
    {
1853
0
        j.m_type = value_t::boolean;
1854
0
        j.m_value = b;
1855
0
        j.assert_invariant();
1856
0
    }
1857
};
1858
1859
template<>
1860
struct external_constructor<value_t::string>
1861
{
1862
    template<typename BasicJsonType>
1863
    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1864
0
    {
1865
0
        j.m_type = value_t::string;
1866
0
        j.m_value = s;
1867
0
        j.assert_invariant();
1868
0
    }
1869
1870
    template<typename BasicJsonType>
1871
    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>
1881
    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>
1893
    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1894
0
    {
1895
0
        j.m_type = value_t::number_float;
1896
0
        j.m_value = val;
1897
0
        j.assert_invariant();
1898
0
    }
1899
};
1900
1901
template<>
1902
struct external_constructor<value_t::number_unsigned>
1903
{
1904
    template<typename BasicJsonType>
1905
    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1906
0
    {
1907
0
        j.m_type = value_t::number_unsigned;
1908
0
        j.m_value = val;
1909
0
        j.assert_invariant();
1910
0
    }
1911
};
1912
1913
template<>
1914
struct external_constructor<value_t::number_integer>
1915
{
1916
    template<typename BasicJsonType>
1917
    static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1918
0
    {
1919
0
        j.m_type = value_t::number_integer;
1920
0
        j.m_value = val;
1921
0
        j.assert_invariant();
1922
0
    }
1923
};
1924
1925
template<>
1926
struct external_constructor<value_t::array>
1927
{
1928
    template<typename BasicJsonType>
1929
    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>
1937
    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>
1947
    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>
1957
    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>
1971
    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>
1985
    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>
1993
    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>
2002
    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>
2019
void to_json(BasicJsonType& j, T b) noexcept
2020
0
{
2021
0
    external_constructor<value_t::boolean>::construct(j, b);
2022
0
}
2023
2024
template<typename BasicJsonType, typename CompatibleString,
2025
         enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
2026
void to_json(BasicJsonType& j, const CompatibleString& s)
2027
0
{
2028
0
    external_constructor<value_t::string>::construct(j, s);
2029
0
}
2030
2031
template<typename BasicJsonType>
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>
2039
void to_json(BasicJsonType& j, FloatType val) noexcept
2040
0
{
2041
0
    external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
2042
0
}
2043
2044
template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
2045
         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
2046
void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
2047
0
{
2048
0
    external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
2049
0
}
2050
2051
template<typename BasicJsonType, typename CompatibleNumberIntegerType,
2052
         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
2053
void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
2054
0
{
2055
0
    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
2056
0
}
2057
2058
template<typename BasicJsonType, typename EnumType,
2059
         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
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>
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>
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>
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>
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>
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>
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 >
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>
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>
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>
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>
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>
2150
    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
0
    {
2153
0
        return to_json(j, std::forward<T>(val));
2154
0
    }
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerEEERSC_EEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerEEERdEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerEEERbEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerEEERlEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerEEERmEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
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>
2182
    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
0
    {
2186
0
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
2187
0
    }
Unexecuted instantiation: _ZN8nlohmann14adl_serializerINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEvE9from_jsonIRKNS_10basic_jsonINS1_3mapENS1_6vectorES7_blmdS5_S0_EES7_EEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSH_RT0_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIbvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_EEbEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSH_RT0_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIdvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_EEdEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSH_RT0_
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>
2199
    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
0
    {
2203
0
        ::nlohmann::to_json(j, std::forward<ValueType>(val));
2204
0
    }
Unexecuted instantiation: _ZN8nlohmann14adl_serializerINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEvE7to_jsonINS_10basic_jsonINS1_3mapENS1_6vectorES7_blmdS5_S0_EERS7_EEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIdvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_EERdEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIbvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_EERbEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIlvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_EERlEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerImvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_EERmEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSG_
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
0
    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:
2293
    explicit file_input_adapter(std::FILE* f)  noexcept
2294
        : m_file(f)
2295
0
    {}
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
2304
    std::char_traits<char>::int_type get_character() noexcept override
2305
0
    {
2306
0
        return std::fgetc(m_file);
2307
0
    }
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:
2327
    ~input_stream_adapter() override
2328
0
    {
2329
0
        // clear stream flags; we use underlying streambuf I/O, do not
2330
0
        // maintain ifstream flags, except eof
2331
0
        is.clear(is.rdstate() & std::ios::eofbit);
2332
0
    }
2333
2334
    explicit input_stream_adapter(std::istream& i)
2335
        : is(i), sb(*i.rdbuf())
2336
0
    {}
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.
2347
    std::char_traits<char>::int_type get_character() override
2348
0
    {
2349
0
        auto res = sb.sbumpc();
2350
0
        // set eof manually, as we don't use the istream interface.
2351
0
        if (res == EOF)
2352
0
        {
2353
0
            is.clear(is.rdstate() | std::ios::eofbit);
2354
0
        }
2355
0
        return res;
2356
0
    }
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:
2368
    input_buffer_adapter(const char* b, const std::size_t l) noexcept
2369
        : cursor(b), limit(b + l)
2370
0
    {}
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
2379
    std::char_traits<char>::int_type get_character() noexcept override
2380
0
    {
2381
0
        if (JSON_LIKELY(cursor < limit))
2382
0
        {
2383
0
            return std::char_traits<char>::to_int_type(*(cursor++));
2384
0
        }
2385
2386
0
        return std::char_traits<char>::eof();
2387
0
    }
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
2400
    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
0
    {
2406
0
        utf8_bytes_index = 0;
2407
0
2408
0
        if (current_wchar == str.size())
2409
0
        {
2410
0
            utf8_bytes[0] = std::char_traits<char>::eof();
2411
0
            utf8_bytes_filled = 1;
2412
0
        }
2413
0
        else
2414
0
        {
2415
0
            // get the current character
2416
0
            const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2417
0
2418
0
            // UTF-32 to UTF-8 encoding
2419
0
            if (wc < 0x80)
2420
0
            {
2421
0
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2422
0
                utf8_bytes_filled = 1;
2423
0
            }
2424
0
            else if (wc <= 0x7FF)
2425
0
            {
2426
0
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
2427
0
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2428
0
                utf8_bytes_filled = 2;
2429
0
            }
2430
0
            else if (wc <= 0xFFFF)
2431
0
            {
2432
0
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
2433
0
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2434
0
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2435
0
                utf8_bytes_filled = 3;
2436
0
            }
2437
0
            else if (wc <= 0x10FFFF)
2438
0
            {
2439
0
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
2440
0
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
2441
0
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2442
0
                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2443
0
                utf8_bytes_filled = 4;
2444
0
            }
2445
0
            else
2446
0
            {
2447
0
                // unknown character
2448
0
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2449
0
                utf8_bytes_filled = 1;
2450
0
            }
2451
0
        }
2452
0
    }
Unexecuted instantiation: nlohmann::detail::wide_string_input_helper<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, 4ul>::fill_buffer(std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > const&, unsigned long&, std::__1::array<int, 4ul>&, unsigned long&, unsigned long&)
Unexecuted instantiation: nlohmann::detail::wide_string_input_helper<std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, std::__1::allocator<char32_t> >, 4ul>::fill_buffer(std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, std::__1::allocator<char32_t> > const&, unsigned long&, std::__1::array<int, 4ul>&, unsigned long&, unsigned long&)
2453
};
2454
2455
template<typename WideStringType>
2456
struct wide_string_input_helper<WideStringType, 2>
2457
{
2458
    // UTF-16
2459
    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
0
    {
2465
0
        utf8_bytes_index = 0;
2466
0
2467
0
        if (current_wchar == str.size())
2468
0
        {
2469
0
            utf8_bytes[0] = std::char_traits<char>::eof();
2470
0
            utf8_bytes_filled = 1;
2471
0
        }
2472
0
        else
2473
0
        {
2474
0
            // get the current character
2475
0
            const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2476
0
2477
0
            // UTF-16 to UTF-8 encoding
2478
0
            if (wc < 0x80)
2479
0
            {
2480
0
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2481
0
                utf8_bytes_filled = 1;
2482
0
            }
2483
0
            else if (wc <= 0x7FF)
2484
0
            {
2485
0
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
2486
0
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2487
0
                utf8_bytes_filled = 2;
2488
0
            }
2489
0
            else if (0xD800 > wc or wc >= 0xE000)
2490
0
            {
2491
0
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
2492
0
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2493
0
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2494
0
                utf8_bytes_filled = 3;
2495
0
            }
2496
0
            else
2497
0
            {
2498
0
                if (current_wchar < str.size())
2499
0
                {
2500
0
                    const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
2501
0
                    const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
2502
0
                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
2503
0
                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
2504
0
                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
2505
0
                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
2506
0
                    utf8_bytes_filled = 4;
2507
0
                }
2508
0
                else
2509
0
                {
2510
0
                    // unknown character
2511
0
                    ++current_wchar;
2512
0
                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2513
0
                    utf8_bytes_filled = 1;
2514
0
                }
2515
0
            }
2516
0
        }
2517
0
    }
2518
};
2519
2520
template<typename WideStringType>
2521
class wide_string_input_adapter : public input_adapter_protocol
2522
{
2523
  public:
2524
    explicit wide_string_input_adapter(const WideStringType& w) noexcept
2525
        : str(w)
2526
    {}
2527
2528
    std::char_traits<char>::int_type get_character() noexcept override
2529
0
    {
2530
0
        // check if buffer needs to be filled
2531
0
        if (utf8_bytes_index == utf8_bytes_filled)
2532
0
        {
2533
0
            fill_buffer<sizeof(typename WideStringType::value_type)>();
2534
0
2535
0
            assert(utf8_bytes_filled > 0);
2536
0
            assert(utf8_bytes_index == 0);
2537
0
        }
2538
0
2539
0
        // use buffer
2540
0
        assert(utf8_bytes_filled > 0);
2541
0
        assert(utf8_bytes_index < utf8_bytes_filled);
2542
0
        return utf8_bytes[utf8_bytes_index++];
2543
0
    }
Unexecuted instantiation: nlohmann::detail::wide_string_input_adapter<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > >::get_character()
Unexecuted instantiation: nlohmann::detail::wide_string_input_adapter<std::__1::basic_string<char16_t, std::__1::char_traits<char16_t>, std::__1::allocator<char16_t> > >::get_character()
Unexecuted instantiation: nlohmann::detail::wide_string_input_adapter<std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, std::__1::allocator<char32_t> > >::get_character()
2544
2545
  private:
2546
    template<size_t T>
2547
    void fill_buffer()
2548
0
    {
2549
0
        wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2550
0
    }
Unexecuted instantiation: void nlohmann::detail::wide_string_input_adapter<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > >::fill_buffer<4ul>()
Unexecuted instantiation: void nlohmann::detail::wide_string_input_adapter<std::__1::basic_string<char16_t, std::__1::char_traits<char16_t>, std::__1::allocator<char16_t> > >::fill_buffer<2ul>()
Unexecuted instantiation: void nlohmann::detail::wide_string_input_adapter<std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, std::__1::allocator<char32_t> > >::fill_buffer<4ul>()
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
2571
    input_adapter(std::FILE* file)
2572
0
        : ia(std::make_shared<file_input_adapter>(file)) {}
2573
    /// input adapter for input stream
2574
    input_adapter(std::istream& i)
2575
0
        : ia(std::make_shared<input_stream_adapter>(i)) {}
2576
2577
    /// input adapter for input stream
2578
    input_adapter(std::istream&& i)
2579
0
        : ia(std::make_shared<input_stream_adapter>(i)) {}
2580
2581
    input_adapter(const std::wstring& ws)
2582
0
        : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2583
2584
    input_adapter(const std::u16string& ws)
2585
0
        : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2586
2587
    input_adapter(const std::u32string& ws)
2588
0
        : 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>
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>
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>
2618
    input_adapter(IteratorType first, IteratorType last)
2619
0
    {
2620
0
#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
0
        const auto is_contiguous = std::accumulate(
2624
0
                                       first, last, std::pair<bool, int>(true, 0),
2625
0
                                       [&first](std::pair<bool, int> res, decltype(*first) val)
2626
0
        {
2627
0
            res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2628
0
            return res;
2629
0
        }).first;
2630
0
        assert(is_contiguous);
2631
0
#endif
2632
2633
        // assertion to check that each element is 1 byte long
2634
0
        static_assert(
2635
0
            sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
2636
0
            "each element in the iterator range must have the size of 1 byte");
2637
2638
0
        const auto len = static_cast<size_t>(std::distance(first, last));
2639
0
        if (JSON_LIKELY(len > 0))
2640
0
        {
2641
            // there is at least one element: use the address of first
2642
0
            ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2643
0
        }
2644
0
        else
2645
0
        {
2646
            // the address of first cannot be used: use nullptr
2647
0
            ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2648
0
        }
2649
0
    }
2650
2651
    /// input adapter for array
2652
    template<class T, std::size_t 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>
2661
    input_adapter(const ContiguousContainer& c)
2662
0
        : input_adapter(std::begin(c), std::end(c)) {}
2663
2664
    operator input_adapter_t()
2665
0
    {
2666
0
        return ia;
2667
0
    }
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
    */
2836
    explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
2837
        : root(r), allow_exceptions(allow_exceptions_)
2838
0
    {}
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
0
    ~json_sax_dom_parser() = default;
2846
2847
    bool null()
2848
0
    {
2849
0
        handle_value(nullptr);
2850
0
        return true;
2851
0
    }
2852
2853
    bool boolean(bool val)
2854
0
    {
2855
0
        handle_value(val);
2856
0
        return true;
2857
0
    }
2858
2859
    bool number_integer(number_integer_t val)
2860
0
    {
2861
0
        handle_value(val);
2862
0
        return true;
2863
0
    }
2864
2865
    bool number_unsigned(number_unsigned_t val)
2866
0
    {
2867
0
        handle_value(val);
2868
0
        return true;
2869
0
    }
2870
2871
    bool number_float(number_float_t val, const string_t& /*unused*/)
2872
0
    {
2873
0
        handle_value(val);
2874
0
        return true;
2875
0
    }
2876
2877
    bool string(string_t& val)
2878
0
    {
2879
0
        handle_value(val);
2880
0
        return true;
2881
0
    }
2882
2883
    bool start_object(std::size_t len)
2884
0
    {
2885
0
        ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
2886
2887
0
        if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2888
0
        {
2889
0
            JSON_THROW(out_of_range::create(408,
2890
0
                                            "excessive object size: " + std::to_string(len)));
2891
0
        }
2892
2893
0
        return true;
2894
0
    }
2895
2896
    bool key(string_t& val)
2897
0
    {
2898
        // add null at given key and store the reference for later
2899
0
        object_element = &(ref_stack.back()->m_value.object->operator[](val));
2900
0
        return true;
2901
0
    }
2902
2903
    bool end_object()
2904
0
    {
2905
0
        ref_stack.pop_back();
2906
0
        return true;
2907
0
    }
2908
2909
    bool start_array(std::size_t len)
2910
0
    {
2911
0
        ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
2912
2913
0
        if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2914
0
        {
2915
0
            JSON_THROW(out_of_range::create(408,
2916
0
                                            "excessive array size: " + std::to_string(len)));
2917
0
        }
2918
2919
0
        return true;
2920
0
    }
2921
2922
    bool end_array()
2923
0
    {
2924
0
        ref_stack.pop_back();
2925
0
        return true;
2926
0
    }
2927
2928
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
2929
                     const detail::exception& ex)
2930
0
    {
2931
0
        errored = true;
2932
0
        if (allow_exceptions)
2933
0
        {
2934
            // determine the proper exception type from the id
2935
0
            switch ((ex.id / 100) % 100)
2936
0
            {
2937
0
                case 1:
2938
0
                    JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
2939
0
                case 4:
2940
0
                    JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
2941
                // LCOV_EXCL_START
2942
0
                case 2:
2943
0
                    JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
2944
0
                case 3:
2945
0
                    JSON_THROW(*static_cast<const detail::type_error*>(&ex));
2946
0
                case 5:
2947
0
                    JSON_THROW(*static_cast<const detail::other_error*>(&ex));
2948
0
                default:
2949
0
                    assert(false);
2950
                    // LCOV_EXCL_STOP
2951
0
            }
2952
0
        }
2953
0
        return false;
2954
0
    }
2955
2956
    constexpr bool is_errored() const
2957
0
    {
2958
0
        return errored;
2959
0
    }
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>
2969
    BasicJsonType* handle_value(Value&& v)
2970
0
    {
2971
0
        if (ref_stack.empty())
2972
0
        {
2973
0
            root = BasicJsonType(std::forward<Value>(v));
2974
0
            return &root;
2975
0
        }
2976
2977
0
        assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
2978
2979
0
        if (ref_stack.back()->is_array())
2980
0
        {
2981
0
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
2982
0
            return &(ref_stack.back()->m_value.array->back());
2983
0
        }
2984
2985
0
        assert(ref_stack.back()->is_object());
2986
0
        assert(object_element);
2987
0
        *object_element = BasicJsonType(std::forward<Value>(v));
2988
0
        return object_element;
2989
0
    }
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<nlohmann::detail::value_t>(nlohmann::detail::value_t&&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<double&>(double&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<bool&>(bool&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<decltype(nullptr)>(decltype(nullptr)&&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<long&>(long&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>* nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<unsigned long&>(unsigned long&)
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
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
0
    {
3019
0
        keep_stack.push_back(true);
3020
0
    }
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
0
    ~json_sax_dom_callback_parser() = default;
3028
3029
    bool null()
3030
0
    {
3031
0
        handle_value(nullptr);
3032
0
        return true;
3033
0
    }
3034
3035
    bool boolean(bool val)
3036
0
    {
3037
0
        handle_value(val);
3038
0
        return true;
3039
0
    }
3040
3041
    bool number_integer(number_integer_t val)
3042
0
    {
3043
0
        handle_value(val);
3044
0
        return true;
3045
0
    }
3046
3047
    bool number_unsigned(number_unsigned_t val)
3048
0
    {
3049
0
        handle_value(val);
3050
0
        return true;
3051
0
    }
3052
3053
    bool number_float(number_float_t val, const string_t& /*unused*/)
3054
0
    {
3055
0
        handle_value(val);
3056
0
        return true;
3057
0
    }
3058
3059
    bool string(string_t& val)
3060
0
    {
3061
0
        handle_value(val);
3062
0
        return true;
3063
0
    }
3064
3065
    bool start_object(std::size_t len)
3066
0
    {
3067
        // check callback for object start
3068
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
3069
0
        keep_stack.push_back(keep);
3070
3071
0
        auto val = handle_value(BasicJsonType::value_t::object, true);
3072
0
        ref_stack.push_back(val.second);
3073
3074
        // check object limit
3075
0
        if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3076
0
        {
3077
0
            JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
3078
0
        }
3079
3080
0
        return true;
3081
0
    }
3082
3083
    bool key(string_t& val)
3084
0
    {
3085
0
        BasicJsonType k = BasicJsonType(val);
3086
3087
        // check callback for key
3088
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
3089
0
        key_keep_stack.push_back(keep);
3090
3091
        // add discarded value at given key and store the reference for later
3092
0
        if (keep and ref_stack.back())
3093
0
        {
3094
0
            object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
3095
0
        }
3096
3097
0
        return true;
3098
0
    }
3099
3100
    bool end_object()
3101
0
    {
3102
0
        if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
3103
0
        {
3104
            // discard object
3105
0
            *ref_stack.back() = discarded;
3106
0
        }
3107
3108
0
        assert(not ref_stack.empty());
3109
0
        assert(not keep_stack.empty());
3110
0
        ref_stack.pop_back();
3111
0
        keep_stack.pop_back();
3112
3113
0
        if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
3114
0
        {
3115
            // remove discarded value
3116
0
            for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
3117
0
            {
3118
0
                if (it->is_discarded())
3119
0
                {
3120
0
                    ref_stack.back()->erase(it);
3121
0
                    break;
3122
0
                }
3123
0
            }
3124
0
        }
3125
3126
0
        return true;
3127
0
    }
3128
3129
    bool start_array(std::size_t len)
3130
0
    {
3131
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
3132
0
        keep_stack.push_back(keep);
3133
3134
0
        auto val = handle_value(BasicJsonType::value_t::array, true);
3135
0
        ref_stack.push_back(val.second);
3136
3137
        // check array limit
3138
0
        if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3139
0
        {
3140
0
            JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
3141
0
        }
3142
3143
0
        return true;
3144
0
    }
3145
3146
    bool end_array()
3147
0
    {
3148
0
        bool keep = true;
3149
3150
0
        if (ref_stack.back())
3151
0
        {
3152
0
            keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
3153
0
            if (not keep)
3154
0
            {
3155
                // discard array
3156
0
                *ref_stack.back() = discarded;
3157
0
            }
3158
0
        }
3159
3160
0
        assert(not ref_stack.empty());
3161
0
        assert(not keep_stack.empty());
3162
0
        ref_stack.pop_back();
3163
0
        keep_stack.pop_back();
3164
3165
        // remove discarded value
3166
0
        if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
3167
0
        {
3168
0
            ref_stack.back()->m_value.array->pop_back();
3169
0
        }
3170
3171
0
        return true;
3172
0
    }
3173
3174
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
3175
                     const detail::exception& ex)
3176
0
    {
3177
0
        errored = true;
3178
0
        if (allow_exceptions)
3179
0
        {
3180
            // determine the proper exception type from the id
3181
0
            switch ((ex.id / 100) % 100)
3182
0
            {
3183
0
                case 1:
3184
0
                    JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
3185
0
                case 4:
3186
0
                    JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
3187
                // LCOV_EXCL_START
3188
0
                case 2:
3189
0
                    JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
3190
0
                case 3:
3191
0
                    JSON_THROW(*static_cast<const detail::type_error*>(&ex));
3192
0
                case 5:
3193
0
                    JSON_THROW(*static_cast<const detail::other_error*>(&ex));
3194
0
                default:
3195
0
                    assert(false);
3196
                    // LCOV_EXCL_STOP
3197
0
            }
3198
0
        }
3199
0
        return false;
3200
0
    }
3201
3202
    constexpr bool is_errored() const
3203
0
    {
3204
0
        return errored;
3205
0
    }
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>
3224
    std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
3225
0
    {
3226
0
        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
0
        if (not keep_stack.back())
3231
0
        {
3232
0
            return {false, nullptr};
3233
0
        }
3234
3235
        // create value
3236
0
        auto value = BasicJsonType(std::forward<Value>(v));
3237
3238
        // check callback
3239
0
        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
0
        if (not keep)
3243
0
        {
3244
0
            return {false, nullptr};
3245
0
        }
3246
3247
0
        if (ref_stack.empty())
3248
0
        {
3249
0
            root = std::move(value);
3250
0
            return {true, &root};
3251
0
        }
3252
3253
        // skip this value if we already decided to skip the parent
3254
        // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
3255
0
        if (not ref_stack.back())
3256
0
        {
3257
0
            return {false, nullptr};
3258
0
        }
3259
3260
        // we now only expect arrays and objects
3261
0
        assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
3262
3263
        // array
3264
0
        if (ref_stack.back()->is_array())
3265
0
        {
3266
0
            ref_stack.back()->m_value.array->push_back(std::move(value));
3267
0
            return {true, &(ref_stack.back()->m_value.array->back())};
3268
0
        }
3269
3270
        // object
3271
0
        assert(ref_stack.back()->is_object());
3272
        // check if we should store an element for the current key
3273
0
        assert(not key_keep_stack.empty());
3274
0
        const bool store_element = key_keep_stack.back();
3275
0
        key_keep_stack.pop_back();
3276
3277
0
        if (not store_element)
3278
0
        {
3279
0
            return {false, nullptr};
3280
0
        }
3281
3282
0
        assert(object_element);
3283
0
        *object_element = std::move(value);
3284
0
        return {true, object_element};
3285
0
    }
Unexecuted instantiation: std::__1::pair<bool, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>*> nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<nlohmann::detail::value_t>(nlohmann::detail::value_t&&, bool)
Unexecuted instantiation: std::__1::pair<bool, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>*> nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<double&>(double&, bool)
Unexecuted instantiation: std::__1::pair<bool, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>*> nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<bool&>(bool&, bool)
Unexecuted instantiation: std::__1::pair<bool, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>*> nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<decltype(nullptr)>(decltype(nullptr)&&, bool)
Unexecuted instantiation: std::__1::pair<bool, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>*> nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<long&>(long&, bool)
Unexecuted instantiation: std::__1::pair<bool, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>*> nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, bool)
Unexecuted instantiation: std::__1::pair<bool, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>*> nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::handle_value<unsigned long&>(unsigned long&, bool)
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
3316
    bool null()
3317
    {
3318
        return true;
3319
    }
3320
3321
    bool boolean(bool /*unused*/)
3322
    {
3323
        return true;
3324
    }
3325
3326
    bool number_integer(number_integer_t /*unused*/)
3327
    {
3328
        return true;
3329
    }
3330
3331
    bool number_unsigned(number_unsigned_t /*unused*/)
3332
    {
3333
        return true;
3334
    }
3335
3336
    bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
3337
    {
3338
        return true;
3339
    }
3340
3341
    bool string(string_t& /*unused*/)
3342
    {
3343
        return true;
3344
    }
3345
3346
    bool start_object(std::size_t  /*unused*/ = std::size_t(-1))
3347
    {
3348
        return true;
3349
    }
3350
3351
    bool key(string_t& /*unused*/)
3352
    {
3353
        return true;
3354
    }
3355
3356
    bool end_object()
3357
    {
3358
        return true;
3359
    }
3360
3361
    bool start_array(std::size_t  /*unused*/ = std::size_t(-1))
3362
    {
3363
        return true;
3364
    }
3365
3366
    bool end_array()
3367
    {
3368
        return true;
3369
    }
3370
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
    */
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
    */
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
    */
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
    */
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
    */
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>
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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>
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>
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
    */
5420
    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
    */
5433
    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
    */
5446
    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)
5563
    static const char* token_type_name(const token_type t) noexcept
5564
0
    {
5565
0
        switch (t)
5566
0
        {
5567
0
            case token_type::uninitialized:
5568
0
                return "<uninitialized>";
5569
0
            case token_type::literal_true:
5570
0
                return "true literal";
5571
0
            case token_type::literal_false:
5572
0
                return "false literal";
5573
0
            case token_type::literal_null:
5574
0
                return "null literal";
5575
0
            case token_type::value_string:
5576
0
                return "string literal";
5577
0
            case lexer::token_type::value_unsigned:
5578
0
            case lexer::token_type::value_integer:
5579
0
            case lexer::token_type::value_float:
5580
0
                return "number literal";
5581
0
            case token_type::begin_array:
5582
0
                return "'['";
5583
0
            case token_type::begin_object:
5584
0
                return "'{'";
5585
0
            case token_type::end_array:
5586
0
                return "']'";
5587
0
            case token_type::end_object:
5588
0
                return "'}'";
5589
0
            case token_type::name_separator:
5590
0
                return "':'";
5591
0
            case token_type::value_separator:
5592
0
                return "','";
5593
0
            case token_type::parse_error:
5594
0
                return "<parse error>";
5595
0
            case token_type::end_of_input:
5596
0
                return "end of input";
5597
0
            case token_type::literal_or_value:
5598
0
                return "'[', '{', or a literal";
5599
            // LCOV_EXCL_START
5600
0
            default: // catch non-enum values
5601
0
                return "unknown token";
5602
                // LCOV_EXCL_STOP
5603
0
        }
5604
0
    }
5605
5606
    explicit lexer(detail::input_adapter_t&& adapter)
5607
0
        : 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
0
    ~lexer() = default;
5615
5616
  private:
5617
    /////////////////////
5618
    // locales
5619
    /////////////////////
5620
5621
    /// return the locale-dependent decimal point
5622
    static char get_decimal_point() noexcept
5623
0
    {
5624
0
        const auto loc = localeconv();
5625
0
        assert(loc != nullptr);
5626
0
        return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
5627
0
    }
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
    */
5648
    int get_codepoint()
5649
0
    {
5650
        // this function only makes sense after reading `\u`
5651
0
        assert(current == 'u');
5652
0
        int codepoint = 0;
5653
5654
0
        const auto factors = { 12u, 8u, 4u, 0u };
5655
0
        for (const auto factor : factors)
5656
0
        {
5657
0
            get();
5658
5659
0
            if (current >= '0' and current <= '9')
5660
0
            {
5661
0
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
5662
0
            }
5663
0
            else if (current >= 'A' and current <= 'F')
5664
0
            {
5665
0
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
5666
0
            }
5667
0
            else if (current >= 'a' and current <= 'f')
5668
0
            {
5669
0
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
5670
0
            }
5671
0
            else
5672
0
            {
5673
0
                return -1;
5674
0
            }
5675
0
        }
5676
5677
0
        assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
5678
0
        return codepoint;
5679
0
    }
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
    */
5696
    bool next_byte_in_range(std::initializer_list<int> ranges)
5697
0
    {
5698
0
        assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
5699
0
        add(current);
5700
5701
0
        for (auto range = ranges.begin(); range != ranges.end(); ++range)
5702
0
        {
5703
0
            get();
5704
0
            if (JSON_LIKELY(*range <= current and current <= *(++range)))
5705
0
            {
5706
0
                add(current);
5707
0
            }
5708
0
            else
5709
0
            {
5710
0
                error_message = "invalid string: ill-formed UTF-8 byte";
5711
0
                return false;
5712
0
            }
5713
0
        }
5714
5715
0
        return true;
5716
0
    }
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
    */
5733
    token_type scan_string()
5734
0
    {
5735
        // reset token_buffer (ignore opening quote)
5736
0
        reset();
5737
5738
        // we entered the function by reading an open quote
5739
0
        assert(current == '\"');
5740
5741
0
        while (true)
5742
0
        {
5743
            // get next character
5744
0
            switch (get())
5745
0
            {
5746
                // end of file while parsing string
5747
0
                case std::char_traits<char>::eof():
5748
0
                {
5749
0
                    error_message = "invalid string: missing closing quote";
5750
0
                    return token_type::parse_error;
5751
0
                }
5752
5753
                // closing quote
5754
0
                case '\"':
5755
0
                {
5756
0
                    return token_type::value_string;
5757
0
                }
5758
5759
                // escapes
5760
0
                case '\\':
5761
0
                {
5762
0
                    switch (get())
5763
0
                    {
5764
                        // quotation mark
5765
0
                        case '\"':
5766
0
                            add('\"');
5767
0
                            break;
5768
                        // reverse solidus
5769
0
                        case '\\':
5770
0
                            add('\\');
5771
0
                            break;
5772
                        // solidus
5773
0
                        case '/':
5774
0
                            add('/');
5775
0
                            break;
5776
                        // backspace
5777
0
                        case 'b':
5778
0
                            add('\b');
5779
0
                            break;
5780
                        // form feed
5781
0
                        case 'f':
5782
0
                            add('\f');
5783
0
                            break;
5784
                        // line feed
5785
0
                        case 'n':
5786
0
                            add('\n');
5787
0
                            break;
5788
                        // carriage return
5789
0
                        case 'r':
5790
0
                            add('\r');
5791
0
                            break;
5792
                        // tab
5793
0
                        case 't':
5794
0
                            add('\t');
5795
0
                            break;
5796
5797
                        // unicode escapes
5798
0
                        case 'u':
5799
0
                        {
5800
0
                            const int codepoint1 = get_codepoint();
5801
0
                            int codepoint = codepoint1; // start with codepoint1
5802
5803
0
                            if (JSON_UNLIKELY(codepoint1 == -1))
5804
0
                            {
5805
0
                                error_message = "invalid string: '\\u' must be followed by 4 hex digits";
5806
0
                                return token_type::parse_error;
5807
0
                            }
5808
5809
                            // check if code point is a high surrogate
5810
0
                            if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
5811
0
                            {
5812
                                // expect next \uxxxx entry
5813
0
                                if (JSON_LIKELY(get() == '\\' and get() == 'u'))
5814
0
                                {
5815
0
                                    const int codepoint2 = get_codepoint();
5816
5817
0
                                    if (JSON_UNLIKELY(codepoint2 == -1))
5818
0
                                    {
5819
0
                                        error_message = "invalid string: '\\u' must be followed by 4 hex digits";
5820
0
                                        return token_type::parse_error;
5821
0
                                    }
5822
5823
                                    // check if codepoint2 is a low surrogate
5824
0
                                    if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
5825
0
                                    {
5826
                                        // overwrite codepoint
5827
0
                                        codepoint = static_cast<int>(
5828
                                                        // high surrogate occupies the most significant 22 bits
5829
0
                                                        (static_cast<unsigned int>(codepoint1) << 10u)
5830
                                                        // low surrogate occupies the least significant 15 bits
5831
0
                                                        + 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
0
                                                        - 0x35FDC00u);
5836
0
                                    }
5837
0
                                    else
5838
0
                                    {
5839
0
                                        error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5840
0
                                        return token_type::parse_error;
5841
0
                                    }
5842
0
                                }
5843
0
                                else
5844
0
                                {
5845
0
                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5846
0
                                    return token_type::parse_error;
5847
0
                                }
5848
0
                            }
5849
0
                            else
5850
0
                            {
5851
0
                                if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
5852
0
                                {
5853
0
                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
5854
0
                                    return token_type::parse_error;
5855
0
                                }
5856
0
                            }
5857
5858
                            // result of the above calculation yields a proper codepoint
5859
0
                            assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
5860
5861
                            // translate codepoint into bytes
5862
0
                            if (codepoint < 0x80)
5863
0
                            {
5864
                                // 1-byte characters: 0xxxxxxx (ASCII)
5865
0
                                add(codepoint);
5866
0
                            }
5867
0
                            else if (codepoint <= 0x7FF)
5868
0
                            {
5869
                                // 2-byte characters: 110xxxxx 10xxxxxx
5870
0
                                add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
5871
0
                                add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5872
0
                            }
5873
0
                            else if (codepoint <= 0xFFFF)
5874
0
                            {
5875
                                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
5876
0
                                add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
5877
0
                                add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5878
0
                                add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5879
0
                            }
5880
0
                            else
5881
0
                            {
5882
                                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5883
0
                                add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
5884
0
                                add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
5885
0
                                add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5886
0
                                add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5887
0
                            }
5888
5889
0
                            break;
5890
0
                        }
5891
5892
                        // other characters after escape
5893
0
                        default:
5894
0
                            error_message = "invalid string: forbidden character after backslash";
5895
0
                            return token_type::parse_error;
5896
0
                    }
5897
5898
0
                    break;
5899
0
                }
5900
5901
                // invalid control characters
5902
0
                case 0x00:
5903
0
                {
5904
0
                    error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
5905
0
                    return token_type::parse_error;
5906
0
                }
5907
5908
0
                case 0x01:
5909
0
                {
5910
0
                    error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
5911
0
                    return token_type::parse_error;
5912
0
                }
5913
5914
0
                case 0x02:
5915
0
                {
5916
0
                    error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
5917
0
                    return token_type::parse_error;
5918
0
                }
5919
5920
0
                case 0x03:
5921
0
                {
5922
0
                    error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
5923
0
                    return token_type::parse_error;
5924
0
                }
5925
5926
0
                case 0x04:
5927
0
                {
5928
0
                    error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
5929
0
                    return token_type::parse_error;
5930
0
                }
5931
5932
0
                case 0x05:
5933
0
                {
5934
0
                    error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
5935
0
                    return token_type::parse_error;
5936
0
                }
5937
5938
0
                case 0x06:
5939
0
                {
5940
0
                    error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
5941
0
                    return token_type::parse_error;
5942
0
                }
5943
5944
0
                case 0x07:
5945
0
                {
5946
0
                    error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
5947
0
                    return token_type::parse_error;
5948
0
                }
5949
5950
0
                case 0x08:
5951
0
                {
5952
0
                    error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
5953
0
                    return token_type::parse_error;
5954
0
                }
5955
5956
0
                case 0x09:
5957
0
                {
5958
0
                    error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
5959
0
                    return token_type::parse_error;
5960
0
                }
5961
5962
0
                case 0x0A:
5963
0
                {
5964
0
                    error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
5965
0
                    return token_type::parse_error;
5966
0
                }
5967
5968
0
                case 0x0B:
5969
0
                {
5970
0
                    error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
5971
0
                    return token_type::parse_error;
5972
0
                }
5973
5974
0
                case 0x0C:
5975
0
                {
5976
0
                    error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
5977
0
                    return token_type::parse_error;
5978
0
                }
5979
5980
0
                case 0x0D:
5981
0
                {
5982
0
                    error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
5983
0
                    return token_type::parse_error;
5984
0
                }
5985
5986
0
                case 0x0E:
5987
0
                {
5988
0
                    error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
5989
0
                    return token_type::parse_error;
5990
0
                }
5991
5992
0
                case 0x0F:
5993
0
                {
5994
0
                    error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
5995
0
                    return token_type::parse_error;
5996
0
                }
5997
5998
0
                case 0x10:
5999
0
                {
6000
0
                    error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6001
0
                    return token_type::parse_error;
6002
0
                }
6003
6004
0
                case 0x11:
6005
0
                {
6006
0
                    error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6007
0
                    return token_type::parse_error;
6008
0
                }
6009
6010
0
                case 0x12:
6011
0
                {
6012
0
                    error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6013
0
                    return token_type::parse_error;
6014
0
                }
6015
6016
0
                case 0x13:
6017
0
                {
6018
0
                    error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6019
0
                    return token_type::parse_error;
6020
0
                }
6021
6022
0
                case 0x14:
6023
0
                {
6024
0
                    error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6025
0
                    return token_type::parse_error;
6026
0
                }
6027
6028
0
                case 0x15:
6029
0
                {
6030
0
                    error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6031
0
                    return token_type::parse_error;
6032
0
                }
6033
6034
0
                case 0x16:
6035
0
                {
6036
0
                    error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6037
0
                    return token_type::parse_error;
6038
0
                }
6039
6040
0
                case 0x17:
6041
0
                {
6042
0
                    error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6043
0
                    return token_type::parse_error;
6044
0
                }
6045
6046
0
                case 0x18:
6047
0
                {
6048
0
                    error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6049
0
                    return token_type::parse_error;
6050
0
                }
6051
6052
0
                case 0x19:
6053
0
                {
6054
0
                    error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6055
0
                    return token_type::parse_error;
6056
0
                }
6057
6058
0
                case 0x1A:
6059
0
                {
6060
0
                    error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6061
0
                    return token_type::parse_error;
6062
0
                }
6063
6064
0
                case 0x1B:
6065
0
                {
6066
0
                    error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6067
0
                    return token_type::parse_error;
6068
0
                }
6069
6070
0
                case 0x1C:
6071
0
                {
6072
0
                    error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6073
0
                    return token_type::parse_error;
6074
0
                }
6075
6076
0
                case 0x1D:
6077
0
                {
6078
0
                    error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6079
0
                    return token_type::parse_error;
6080
0
                }
6081
6082
0
                case 0x1E:
6083
0
                {
6084
0
                    error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6085
0
                    return token_type::parse_error;
6086
0
                }
6087
6088
0
                case 0x1F:
6089
0
                {
6090
0
                    error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6091
0
                    return token_type::parse_error;
6092
0
                }
6093
6094
                // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6095
0
                case 0x20:
6096
0
                case 0x21:
6097
0
                case 0x23:
6098
0
                case 0x24:
6099
0
                case 0x25:
6100
0
                case 0x26:
6101
0
                case 0x27:
6102
0
                case 0x28:
6103
0
                case 0x29:
6104
0
                case 0x2A:
6105
0
                case 0x2B:
6106
0
                case 0x2C:
6107
0
                case 0x2D:
6108
0
                case 0x2E:
6109
0
                case 0x2F:
6110
0
                case 0x30:
6111
0
                case 0x31:
6112
0
                case 0x32:
6113
0
                case 0x33:
6114
0
                case 0x34:
6115
0
                case 0x35:
6116
0
                case 0x36:
6117
0
                case 0x37:
6118
0
                case 0x38:
6119
0
                case 0x39:
6120
0
                case 0x3A:
6121
0
                case 0x3B:
6122
0
                case 0x3C:
6123
0
                case 0x3D:
6124
0
                case 0x3E:
6125
0
                case 0x3F:
6126
0
                case 0x40:
6127
0
                case 0x41:
6128
0
                case 0x42:
6129
0
                case 0x43:
6130
0
                case 0x44:
6131
0
                case 0x45:
6132
0
                case 0x46:
6133
0
                case 0x47:
6134
0
                case 0x48:
6135
0
                case 0x49:
6136
0
                case 0x4A:
6137
0
                case 0x4B:
6138
0
                case 0x4C:
6139
0
                case 0x4D:
6140
0
                case 0x4E:
6141
0
                case 0x4F:
6142
0
                case 0x50:
6143
0
                case 0x51:
6144
0
                case 0x52:
6145
0
                case 0x53:
6146
0
                case 0x54:
6147
0
                case 0x55:
6148
0
                case 0x56:
6149
0
                case 0x57:
6150
0
                case 0x58:
6151
0
                case 0x59:
6152
0
                case 0x5A:
6153
0
                case 0x5B:
6154
0
                case 0x5D:
6155
0
                case 0x5E:
6156
0
                case 0x5F:
6157
0
                case 0x60:
6158
0
                case 0x61:
6159
0
                case 0x62:
6160
0
                case 0x63:
6161
0
                case 0x64:
6162
0
                case 0x65:
6163
0
                case 0x66:
6164
0
                case 0x67:
6165
0
                case 0x68:
6166
0
                case 0x69:
6167
0
                case 0x6A:
6168
0
                case 0x6B:
6169
0
                case 0x6C:
6170
0
                case 0x6D:
6171
0
                case 0x6E:
6172
0
                case 0x6F:
6173
0
                case 0x70:
6174
0
                case 0x71:
6175
0
                case 0x72:
6176
0
                case 0x73:
6177
0
                case 0x74:
6178
0
                case 0x75:
6179
0
                case 0x76:
6180
0
                case 0x77:
6181
0
                case 0x78:
6182
0
                case 0x79:
6183
0
                case 0x7A:
6184
0
                case 0x7B:
6185
0
                case 0x7C:
6186
0
                case 0x7D:
6187
0
                case 0x7E:
6188
0
                case 0x7F:
6189
0
                {
6190
0
                    add(current);
6191
0
                    break;
6192
0
                }
6193
6194
                // U+0080..U+07FF: bytes C2..DF 80..BF
6195
0
                case 0xC2:
6196
0
                case 0xC3:
6197
0
                case 0xC4:
6198
0
                case 0xC5:
6199
0
                case 0xC6:
6200
0
                case 0xC7:
6201
0
                case 0xC8:
6202
0
                case 0xC9:
6203
0
                case 0xCA:
6204
0
                case 0xCB:
6205
0
                case 0xCC:
6206
0
                case 0xCD:
6207
0
                case 0xCE:
6208
0
                case 0xCF:
6209
0
                case 0xD0:
6210
0
                case 0xD1:
6211
0
                case 0xD2:
6212
0
                case 0xD3:
6213
0
                case 0xD4:
6214
0
                case 0xD5:
6215
0
                case 0xD6:
6216
0
                case 0xD7:
6217
0
                case 0xD8:
6218
0
                case 0xD9:
6219
0
                case 0xDA:
6220
0
                case 0xDB:
6221
0
                case 0xDC:
6222
0
                case 0xDD:
6223
0
                case 0xDE:
6224
0
                case 0xDF:
6225
0
                {
6226
0
                    if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
6227
0
                    {
6228
0
                        return token_type::parse_error;
6229
0
                    }
6230
0
                    break;
6231
0
                }
6232
6233
                // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6234
0
                case 0xE0:
6235
0
                {
6236
0
                    if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6237
0
                    {
6238
0
                        return token_type::parse_error;
6239
0
                    }
6240
0
                    break;
6241
0
                }
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
0
                case 0xE1:
6246
0
                case 0xE2:
6247
0
                case 0xE3:
6248
0
                case 0xE4:
6249
0
                case 0xE5:
6250
0
                case 0xE6:
6251
0
                case 0xE7:
6252
0
                case 0xE8:
6253
0
                case 0xE9:
6254
0
                case 0xEA:
6255
0
                case 0xEB:
6256
0
                case 0xEC:
6257
0
                case 0xEE:
6258
0
                case 0xEF:
6259
0
                {
6260
0
                    if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6261
0
                    {
6262
0
                        return token_type::parse_error;
6263
0
                    }
6264
0
                    break;
6265
0
                }
6266
6267
                // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6268
0
                case 0xED:
6269
0
                {
6270
0
                    if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6271
0
                    {
6272
0
                        return token_type::parse_error;
6273
0
                    }
6274
0
                    break;
6275
0
                }
6276
6277
                // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6278
0
                case 0xF0:
6279
0
                {
6280
0
                    if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6281
0
                    {
6282
0
                        return token_type::parse_error;
6283
0
                    }
6284
0
                    break;
6285
0
                }
6286
6287
                // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6288
0
                case 0xF1:
6289
0
                case 0xF2:
6290
0
                case 0xF3:
6291
0
                {
6292
0
                    if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6293
0
                    {
6294
0
                        return token_type::parse_error;
6295
0
                    }
6296
0
                    break;
6297
0
                }
6298
6299
                // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6300
0
                case 0xF4:
6301
0
                {
6302
0
                    if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6303
0
                    {
6304
0
                        return token_type::parse_error;
6305
0
                    }
6306
0
                    break;
6307
0
                }
6308
6309
                // remaining bytes (80..C1 and F5..FF) are ill-formed
6310
0
                default:
6311
0
                {
6312
0
                    error_message = "invalid string: ill-formed UTF-8 byte";
6313
0
                    return token_type::parse_error;
6314
0
                }
6315
0
            }
6316
0
        }
6317
0
    }
6318
6319
    static void strtof(float& f, const char* str, char** endptr) noexcept
6320
    {
6321
        f = std::strtof(str, endptr);
6322
    }
6323
6324
    static void strtof(double& f, const char* str, char** endptr) noexcept
6325
0
    {
6326
0
        f = std::strtod(str, endptr);
6327
0
    }
6328
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
    */
6374
    token_type scan_number()  // lgtm [cpp/use-of-goto]
6375
0
    {
6376
        // reset token_buffer to store the number's bytes
6377
0
        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
0
        token_type number_type = token_type::value_unsigned;
6382
6383
        // state (init): we just found out we need to scan a number
6384
0
        switch (current)
6385
0
        {
6386
0
            case '-':
6387
0
            {
6388
0
                add(current);
6389
0
                goto scan_number_minus;
6390
0
            }
6391
6392
0
            case '0':
6393
0
            {
6394
0
                add(current);
6395
0
                goto scan_number_zero;
6396
0
            }
6397
6398
0
            case '1':
6399
0
            case '2':
6400
0
            case '3':
6401
0
            case '4':
6402
0
            case '5':
6403
0
            case '6':
6404
0
            case '7':
6405
0
            case '8':
6406
0
            case '9':
6407
0
            {
6408
0
                add(current);
6409
0
                goto scan_number_any1;
6410
0
            }
6411
6412
            // all other characters are rejected outside scan_number()
6413
0
            default:            // LCOV_EXCL_LINE
6414
0
                assert(false);  // LCOV_EXCL_LINE
6415
0
        }
6416
6417
0
scan_number_minus:
6418
        // state: we just parsed a leading minus sign
6419
0
        number_type = token_type::value_integer;
6420
0
        switch (get())
6421
0
        {
6422
0
            case '0':
6423
0
            {
6424
0
                add(current);
6425
0
                goto scan_number_zero;
6426
0
            }
6427
6428
0
            case '1':
6429
0
            case '2':
6430
0
            case '3':
6431
0
            case '4':
6432
0
            case '5':
6433
0
            case '6':
6434
0
            case '7':
6435
0
            case '8':
6436
0
            case '9':
6437
0
            {
6438
0
                add(current);
6439
0
                goto scan_number_any1;
6440
0
            }
6441
6442
0
            default:
6443
0
            {
6444
0
                error_message = "invalid number; expected digit after '-'";
6445
0
                return token_type::parse_error;
6446
0
            }
6447
0
        }
6448
6449
0
scan_number_zero:
6450
        // state: we just parse a zero (maybe with a leading minus sign)
6451
0
        switch (get())
6452
0
        {
6453
0
            case '.':
6454
0
            {
6455
0
                add(decimal_point_char);
6456
0
                goto scan_number_decimal1;
6457
0
            }
6458
6459
0
            case 'e':
6460
0
            case 'E':
6461
0
            {
6462
0
                add(current);
6463
0
                goto scan_number_exponent;
6464
0
            }
6465
6466
0
            default:
6467
0
                goto scan_number_done;
6468
0
        }
6469
6470
0
scan_number_any1:
6471
        // state: we just parsed a number 0-9 (maybe with a leading minus sign)
6472
0
        switch (get())
6473
0
        {
6474
0
            case '0':
6475
0
            case '1':
6476
0
            case '2':
6477
0
            case '3':
6478
0
            case '4':
6479
0
            case '5':
6480
0
            case '6':
6481
0
            case '7':
6482
0
            case '8':
6483
0
            case '9':
6484
0
            {
6485
0
                add(current);
6486
0
                goto scan_number_any1;
6487
0
            }
6488
6489
0
            case '.':
6490
0
            {
6491
0
                add(decimal_point_char);
6492
0
                goto scan_number_decimal1;
6493
0
            }
6494
6495
0
            case 'e':
6496
0
            case 'E':
6497
0
            {
6498
0
                add(current);
6499
0
                goto scan_number_exponent;
6500
0
            }
6501
6502
0
            default:
6503
0
                goto scan_number_done;
6504
0
        }
6505
6506
0
scan_number_decimal1:
6507
        // state: we just parsed a decimal point
6508
0
        number_type = token_type::value_float;
6509
0
        switch (get())
6510
0
        {
6511
0
            case '0':
6512
0
            case '1':
6513
0
            case '2':
6514
0
            case '3':
6515
0
            case '4':
6516
0
            case '5':
6517
0
            case '6':
6518
0
            case '7':
6519
0
            case '8':
6520
0
            case '9':
6521
0
            {
6522
0
                add(current);
6523
0
                goto scan_number_decimal2;
6524
0
            }
6525
6526
0
            default:
6527
0
            {
6528
0
                error_message = "invalid number; expected digit after '.'";
6529
0
                return token_type::parse_error;
6530
0
            }
6531
0
        }
6532
6533
0
scan_number_decimal2:
6534
        // we just parsed at least one number after a decimal point
6535
0
        switch (get())
6536
0
        {
6537
0
            case '0':
6538
0
            case '1':
6539
0
            case '2':
6540
0
            case '3':
6541
0
            case '4':
6542
0
            case '5':
6543
0
            case '6':
6544
0
            case '7':
6545
0
            case '8':
6546
0
            case '9':
6547
0
            {
6548
0
                add(current);
6549
0
                goto scan_number_decimal2;
6550
0
            }
6551
6552
0
            case 'e':
6553
0
            case 'E':
6554
0
            {
6555
0
                add(current);
6556
0
                goto scan_number_exponent;
6557
0
            }
6558
6559
0
            default:
6560
0
                goto scan_number_done;
6561
0
        }
6562
6563
0
scan_number_exponent:
6564
        // we just parsed an exponent
6565
0
        number_type = token_type::value_float;
6566
0
        switch (get())
6567
0
        {
6568
0
            case '+':
6569
0
            case '-':
6570
0
            {
6571
0
                add(current);
6572
0
                goto scan_number_sign;
6573
0
            }
6574
6575
0
            case '0':
6576
0
            case '1':
6577
0
            case '2':
6578
0
            case '3':
6579
0
            case '4':
6580
0
            case '5':
6581
0
            case '6':
6582
0
            case '7':
6583
0
            case '8':
6584
0
            case '9':
6585
0
            {
6586
0
                add(current);
6587
0
                goto scan_number_any2;
6588
0
            }
6589
6590
0
            default:
6591
0
            {
6592
0
                error_message =
6593
0
                    "invalid number; expected '+', '-', or digit after exponent";
6594
0
                return token_type::parse_error;
6595
0
            }
6596
0
        }
6597
6598
0
scan_number_sign:
6599
        // we just parsed an exponent sign
6600
0
        switch (get())
6601
0
        {
6602
0
            case '0':
6603
0
            case '1':
6604
0
            case '2':
6605
0
            case '3':
6606
0
            case '4':
6607
0
            case '5':
6608
0
            case '6':
6609
0
            case '7':
6610
0
            case '8':
6611
0
            case '9':
6612
0
            {
6613
0
                add(current);
6614
0
                goto scan_number_any2;
6615
0
            }
6616
6617
0
            default:
6618
0
            {
6619
0
                error_message = "invalid number; expected digit after exponent sign";
6620
0
                return token_type::parse_error;
6621
0
            }
6622
0
        }
6623
6624
0
scan_number_any2:
6625
        // we just parsed a number after the exponent or exponent sign
6626
0
        switch (get())
6627
0
        {
6628
0
            case '0':
6629
0
            case '1':
6630
0
            case '2':
6631
0
            case '3':
6632
0
            case '4':
6633
0
            case '5':
6634
0
            case '6':
6635
0
            case '7':
6636
0
            case '8':
6637
0
            case '9':
6638
0
            {
6639
0
                add(current);
6640
0
                goto scan_number_any2;
6641
0
            }
6642
6643
0
            default:
6644
0
                goto scan_number_done;
6645
0
        }
6646
6647
0
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
0
        unget();
6651
6652
0
        char* endptr = nullptr;
6653
0
        errno = 0;
6654
6655
        // try to parse integers first and fall back to floats
6656
0
        if (number_type == token_type::value_unsigned)
6657
0
        {
6658
0
            const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
6659
6660
            // we checked the number format before
6661
0
            assert(endptr == token_buffer.data() + token_buffer.size());
6662
6663
0
            if (errno == 0)
6664
0
            {
6665
0
                value_unsigned = static_cast<number_unsigned_t>(x);
6666
0
                if (value_unsigned == x)
6667
0
                {
6668
0
                    return token_type::value_unsigned;
6669
0
                }
6670
0
            }
6671
0
        }
6672
0
        else if (number_type == token_type::value_integer)
6673
0
        {
6674
0
            const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
6675
6676
            // we checked the number format before
6677
0
            assert(endptr == token_buffer.data() + token_buffer.size());
6678
6679
0
            if (errno == 0)
6680
0
            {
6681
0
                value_integer = static_cast<number_integer_t>(x);
6682
0
                if (value_integer == x)
6683
0
                {
6684
0
                    return token_type::value_integer;
6685
0
                }
6686
0
            }
6687
0
        }
6688
6689
        // this code is reached if we parse a floating-point number or if an
6690
        // integer conversion above failed
6691
0
        strtof(value_float, token_buffer.data(), &endptr);
6692
6693
        // we checked the number format before
6694
0
        assert(endptr == token_buffer.data() + token_buffer.size());
6695
6696
0
        return token_type::value_float;
6697
0
    }
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
    */
6704
    token_type scan_literal(const char* literal_text, const std::size_t length,
6705
                            token_type return_type)
6706
0
    {
6707
0
        assert(current == literal_text[0]);
6708
0
        for (std::size_t i = 1; i < length; ++i)
6709
0
        {
6710
0
            if (JSON_UNLIKELY(get() != literal_text[i]))
6711
0
            {
6712
0
                error_message = "invalid literal";
6713
0
                return token_type::parse_error;
6714
0
            }
6715
0
        }
6716
0
        return return_type;
6717
0
    }
6718
6719
    /////////////////////
6720
    // input management
6721
    /////////////////////
6722
6723
    /// reset token_buffer; current character is beginning of token
6724
    void reset() noexcept
6725
0
    {
6726
0
        token_buffer.clear();
6727
0
        token_string.clear();
6728
0
        token_string.push_back(std::char_traits<char>::to_char_type(current));
6729
0
    }
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
    */
6741
    std::char_traits<char>::int_type get()
6742
0
    {
6743
0
        ++position.chars_read_total;
6744
0
        ++position.chars_read_current_line;
6745
6746
0
        if (next_unget)
6747
0
        {
6748
            // just reset the next_unget variable and work with current
6749
0
            next_unget = false;
6750
0
        }
6751
0
        else
6752
0
        {
6753
0
            current = ia->get_character();
6754
0
        }
6755
6756
0
        if (JSON_LIKELY(current != std::char_traits<char>::eof()))
6757
0
        {
6758
0
            token_string.push_back(std::char_traits<char>::to_char_type(current));
6759
0
        }
6760
6761
0
        if (current == '\n')
6762
0
        {
6763
0
            ++position.lines_read;
6764
0
            position.chars_read_current_line = 0;
6765
0
        }
6766
6767
0
        return current;
6768
0
    }
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
    */
6778
    void unget()
6779
0
    {
6780
0
        next_unget = true;
6781
6782
0
        --position.chars_read_total;
6783
6784
        // in case we "unget" a newline, we have to also decrement the lines_read
6785
0
        if (position.chars_read_current_line == 0)
6786
0
        {
6787
0
            if (position.lines_read > 0)
6788
0
            {
6789
0
                --position.lines_read;
6790
0
            }
6791
0
        }
6792
0
        else
6793
0
        {
6794
0
            --position.chars_read_current_line;
6795
0
        }
6796
6797
0
        if (JSON_LIKELY(current != std::char_traits<char>::eof()))
6798
0
        {
6799
0
            assert(not token_string.empty());
6800
0
            token_string.pop_back();
6801
0
        }
6802
0
    }
6803
6804
    /// add a character to token_buffer
6805
    void add(int c)
6806
0
    {
6807
0
        token_buffer.push_back(std::char_traits<char>::to_char_type(c));
6808
0
    }
6809
6810
  public:
6811
    /////////////////////
6812
    // value getters
6813
    /////////////////////
6814
6815
    /// return integer value
6816
    constexpr number_integer_t get_number_integer() const noexcept
6817
0
    {
6818
0
        return value_integer;
6819
0
    }
6820
6821
    /// return unsigned integer value
6822
    constexpr number_unsigned_t get_number_unsigned() const noexcept
6823
0
    {
6824
0
        return value_unsigned;
6825
0
    }
6826
6827
    /// return floating-point value
6828
    constexpr number_float_t get_number_float() const noexcept
6829
0
    {
6830
0
        return value_float;
6831
0
    }
6832
6833
    /// return current string value (implicitly resets the token; useful only once)
6834
    string_t& get_string()
6835
0
    {
6836
0
        return token_buffer;
6837
0
    }
6838
6839
    /////////////////////
6840
    // diagnostics
6841
    /////////////////////
6842
6843
    /// return position of last read token
6844
    constexpr position_t get_position() const noexcept
6845
0
    {
6846
0
        return position;
6847
0
    }
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.
6852
    std::string get_token_string() const
6853
0
    {
6854
        // escape control characters
6855
0
        std::string result;
6856
0
        for (const auto c : token_string)
6857
0
        {
6858
0
            if ('\x00' <= c and c <= '\x1F')
6859
0
            {
6860
                // escape control characters
6861
0
                std::array<char, 9> cs{{}};
6862
0
                (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
6863
0
                result += cs.data();
6864
0
            }
6865
0
            else
6866
0
            {
6867
                // add character as is
6868
0
                result.push_back(c);
6869
0
            }
6870
0
        }
6871
6872
0
        return result;
6873
0
    }
6874
6875
    /// return syntax error message
6876
    constexpr const char* get_error_message() const noexcept
6877
0
    {
6878
0
        return error_message;
6879
0
    }
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
    */
6889
    bool skip_bom()
6890
0
    {
6891
0
        if (get() == 0xEF)
6892
0
        {
6893
            // check if we completely parse the BOM
6894
0
            return get() == 0xBB and get() == 0xBF;
6895
0
        }
6896
6897
        // the first character is not the beginning of the BOM; unget it to
6898
        // process is later
6899
0
        unget();
6900
0
        return true;
6901
0
    }
6902
6903
    token_type scan()
6904
0
    {
6905
        // initially, skip the BOM
6906
0
        if (position.chars_read_total == 0 and not skip_bom())
6907
0
        {
6908
0
            error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
6909
0
            return token_type::parse_error;
6910
0
        }
6911
6912
        // read next character and ignore whitespace
6913
0
        do
6914
0
        {
6915
0
            get();
6916
0
        }
6917
0
        while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
6918
6919
0
        switch (current)
6920
0
        {
6921
            // structural characters
6922
0
            case '[':
6923
0
                return token_type::begin_array;
6924
0
            case ']':
6925
0
                return token_type::end_array;
6926
0
            case '{':
6927
0
                return token_type::begin_object;
6928
0
            case '}':
6929
0
                return token_type::end_object;
6930
0
            case ':':
6931
0
                return token_type::name_separator;
6932
0
            case ',':
6933
0
                return token_type::value_separator;
6934
6935
            // literals
6936
0
            case 't':
6937
0
                return scan_literal("true", 4, token_type::literal_true);
6938
0
            case 'f':
6939
0
                return scan_literal("false", 5, token_type::literal_false);
6940
0
            case 'n':
6941
0
                return scan_literal("null", 4, token_type::literal_null);
6942
6943
            // string
6944
0
            case '\"':
6945
0
                return scan_string();
6946
6947
            // number
6948
0
            case '-':
6949
0
            case '0':
6950
0
            case '1':
6951
0
            case '2':
6952
0
            case '3':
6953
0
            case '4':
6954
0
            case '5':
6955
0
            case '6':
6956
0
            case '7':
6957
0
            case '8':
6958
0
            case '9':
6959
0
                return scan_number();
6960
6961
            // end of input (the null byte is needed when parsing from
6962
            // string literals)
6963
0
            case '\0':
6964
0
            case std::char_traits<char>::eof():
6965
0
                return token_type::end_of_input;
6966
6967
            // error
6968
0
            default:
6969
0
                error_message = "invalid literal";
6970
0
                return token_type::parse_error;
6971
0
        }
6972
0
    }
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
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
0
    {
7082
        // read first token
7083
0
        get_token();
7084
0
    }
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
    */
7096
    void parse(const bool strict, BasicJsonType& result)
7097
0
    {
7098
0
        if (callback)
7099
0
        {
7100
0
            json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
7101
0
            sax_parse_internal(&sdp);
7102
0
            result.assert_invariant();
7103
7104
            // in strict mode, input must be completely read
7105
0
            if (strict and (get_token() != token_type::end_of_input))
7106
0
            {
7107
0
                sdp.parse_error(m_lexer.get_position(),
7108
0
                                m_lexer.get_token_string(),
7109
0
                                parse_error::create(101, m_lexer.get_position(),
7110
0
                                                    exception_message(token_type::end_of_input, "value")));
7111
0
            }
7112
7113
            // in case of an error, return discarded value
7114
0
            if (sdp.is_errored())
7115
0
            {
7116
0
                result = value_t::discarded;
7117
0
                return;
7118
0
            }
7119
7120
            // set top-level value to null if it was discarded by the callback
7121
            // function
7122
0
            if (result.is_discarded())
7123
0
            {
7124
0
                result = nullptr;
7125
0
            }
7126
0
        }
7127
0
        else
7128
0
        {
7129
0
            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
7130
0
            sax_parse_internal(&sdp);
7131
0
            result.assert_invariant();
7132
7133
            // in strict mode, input must be completely read
7134
0
            if (strict and (get_token() != token_type::end_of_input))
7135
0
            {
7136
0
                sdp.parse_error(m_lexer.get_position(),
7137
0
                                m_lexer.get_token_string(),
7138
0
                                parse_error::create(101, m_lexer.get_position(),
7139
0
                                                    exception_message(token_type::end_of_input, "value")));
7140
0
            }
7141
7142
            // in case of an error, return discarded value
7143
0
            if (sdp.is_errored())
7144
0
            {
7145
0
                result = value_t::discarded;
7146
0
                return;
7147
0
            }
7148
0
        }
7149
0
    }
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
    */
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>
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>
7183
    bool sax_parse_internal(SAX* sax)
7184
0
    {
7185
        // stack to remember the hierarchy of structured values we are parsing
7186
        // true = array; false = object
7187
0
        std::vector<bool> states;
7188
        // value to avoid a goto (see comment where set to true)
7189
0
        bool skip_to_state_evaluation = false;
7190
7191
0
        while (true)
7192
0
        {
7193
0
            if (not skip_to_state_evaluation)
7194
0
            {
7195
                // invariant: get_token() was called before each iteration
7196
0
                switch (last_token)
7197
0
                {
7198
0
                    case token_type::begin_object:
7199
0
                    {
7200
0
                        if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
7201
0
                        {
7202
0
                            return false;
7203
0
                        }
7204
7205
                        // closing } -> we are done
7206
0
                        if (get_token() == token_type::end_object)
7207
0
                        {
7208
0
                            if (JSON_UNLIKELY(not sax->end_object()))
7209
0
                            {
7210
0
                                return false;
7211
0
                            }
7212
0
                            break;
7213
0
                        }
7214
7215
                        // parse key
7216
0
                        if (JSON_UNLIKELY(last_token != token_type::value_string))
7217
0
                        {
7218
0
                            return sax->parse_error(m_lexer.get_position(),
7219
0
                                                    m_lexer.get_token_string(),
7220
0
                                                    parse_error::create(101, m_lexer.get_position(),
7221
0
                                                            exception_message(token_type::value_string, "object key")));
7222
0
                        }
7223
0
                        if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
7224
0
                        {
7225
0
                            return false;
7226
0
                        }
7227
7228
                        // parse separator (:)
7229
0
                        if (JSON_UNLIKELY(get_token() != token_type::name_separator))
7230
0
                        {
7231
0
                            return sax->parse_error(m_lexer.get_position(),
7232
0
                                                    m_lexer.get_token_string(),
7233
0
                                                    parse_error::create(101, m_lexer.get_position(),
7234
0
                                                            exception_message(token_type::name_separator, "object separator")));
7235
0
                        }
7236
7237
                        // remember we are now inside an object
7238
0
                        states.push_back(false);
7239
7240
                        // parse values
7241
0
                        get_token();
7242
0
                        continue;
7243
0
                    }
7244
7245
0
                    case token_type::begin_array:
7246
0
                    {
7247
0
                        if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
7248
0
                        {
7249
0
                            return false;
7250
0
                        }
7251
7252
                        // closing ] -> we are done
7253
0
                        if (get_token() == token_type::end_array)
7254
0
                        {
7255
0
                            if (JSON_UNLIKELY(not sax->end_array()))
7256
0
                            {
7257
0
                                return false;
7258
0
                            }
7259
0
                            break;
7260
0
                        }
7261
7262
                        // remember we are now inside an array
7263
0
                        states.push_back(true);
7264
7265
                        // parse values (no need to call get_token)
7266
0
                        continue;
7267
0
                    }
7268
7269
0
                    case token_type::value_float:
7270
0
                    {
7271
0
                        const auto res = m_lexer.get_number_float();
7272
7273
0
                        if (JSON_UNLIKELY(not std::isfinite(res)))
7274
0
                        {
7275
0
                            return sax->parse_error(m_lexer.get_position(),
7276
0
                                                    m_lexer.get_token_string(),
7277
0
                                                    out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
7278
0
                        }
7279
7280
0
                        if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
7281
0
                        {
7282
0
                            return false;
7283
0
                        }
7284
7285
0
                        break;
7286
0
                    }
7287
7288
0
                    case token_type::literal_false:
7289
0
                    {
7290
0
                        if (JSON_UNLIKELY(not sax->boolean(false)))
7291
0
                        {
7292
0
                            return false;
7293
0
                        }
7294
0
                        break;
7295
0
                    }
7296
7297
0
                    case token_type::literal_null:
7298
0
                    {
7299
0
                        if (JSON_UNLIKELY(not sax->null()))
7300
0
                        {
7301
0
                            return false;
7302
0
                        }
7303
0
                        break;
7304
0
                    }
7305
7306
0
                    case token_type::literal_true:
7307
0
                    {
7308
0
                        if (JSON_UNLIKELY(not sax->boolean(true)))
7309
0
                        {
7310
0
                            return false;
7311
0
                        }
7312
0
                        break;
7313
0
                    }
7314
7315
0
                    case token_type::value_integer:
7316
0
                    {
7317
0
                        if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
7318
0
                        {
7319
0
                            return false;
7320
0
                        }
7321
0
                        break;
7322
0
                    }
7323
7324
0
                    case token_type::value_string:
7325
0
                    {
7326
0
                        if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
7327
0
                        {
7328
0
                            return false;
7329
0
                        }
7330
0
                        break;
7331
0
                    }
7332
7333
0
                    case token_type::value_unsigned:
7334
0
                    {
7335
0
                        if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
7336
0
                        {
7337
0
                            return false;
7338
0
                        }
7339
0
                        break;
7340
0
                    }
7341
7342
0
                    case token_type::parse_error:
7343
0
                    {
7344
                        // using "uninitialized" to avoid "expected" message
7345
0
                        return sax->parse_error(m_lexer.get_position(),
7346
0
                                                m_lexer.get_token_string(),
7347
0
                                                parse_error::create(101, m_lexer.get_position(),
7348
0
                                                        exception_message(token_type::uninitialized, "value")));
7349
0
                    }
7350
7351
0
                    default: // the last token was unexpected
7352
0
                    {
7353
0
                        return sax->parse_error(m_lexer.get_position(),
7354
0
                                                m_lexer.get_token_string(),
7355
0
                                                parse_error::create(101, m_lexer.get_position(),
7356
0
                                                        exception_message(token_type::literal_or_value, "value")));
7357
0
                    }
7358
0
                }
7359
0
            }
7360
0
            else
7361
0
            {
7362
0
                skip_to_state_evaluation = false;
7363
0
            }
7364
7365
            // we reached this line after we successfully parsed a value
7366
0
            if (states.empty())
7367
0
            {
7368
                // empty stack: we reached the end of the hierarchy: done
7369
0
                return true;
7370
0
            }
7371
7372
0
            if (states.back())  // array
7373
0
            {
7374
                // comma -> next value
7375
0
                if (get_token() == token_type::value_separator)
7376
0
                {
7377
                    // parse a new value
7378
0
                    get_token();
7379
0
                    continue;
7380
0
                }
7381
7382
                // closing ]
7383
0
                if (JSON_LIKELY(last_token == token_type::end_array))
7384
0
                {
7385
0
                    if (JSON_UNLIKELY(not sax->end_array()))
7386
0
                    {
7387
0
                        return false;
7388
0
                    }
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
0
                    assert(not states.empty());
7395
0
                    states.pop_back();
7396
0
                    skip_to_state_evaluation = true;
7397
0
                    continue;
7398
0
                }
7399
7400
0
                return sax->parse_error(m_lexer.get_position(),
7401
0
                                        m_lexer.get_token_string(),
7402
0
                                        parse_error::create(101, m_lexer.get_position(),
7403
0
                                                exception_message(token_type::end_array, "array")));
7404
0
            }
7405
0
            else  // object
7406
0
            {
7407
                // comma -> next value
7408
0
                if (get_token() == token_type::value_separator)
7409
0
                {
7410
                    // parse key
7411
0
                    if (JSON_UNLIKELY(get_token() != token_type::value_string))
7412
0
                    {
7413
0
                        return sax->parse_error(m_lexer.get_position(),
7414
0
                                                m_lexer.get_token_string(),
7415
0
                                                parse_error::create(101, m_lexer.get_position(),
7416
0
                                                        exception_message(token_type::value_string, "object key")));
7417
0
                    }
7418
7419
0
                    if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
7420
0
                    {
7421
0
                        return false;
7422
0
                    }
7423
7424
                    // parse separator (:)
7425
0
                    if (JSON_UNLIKELY(get_token() != token_type::name_separator))
7426
0
                    {
7427
0
                        return sax->parse_error(m_lexer.get_position(),
7428
0
                                                m_lexer.get_token_string(),
7429
0
                                                parse_error::create(101, m_lexer.get_position(),
7430
0
                                                        exception_message(token_type::name_separator, "object separator")));
7431
0
                    }
7432
7433
                    // parse values
7434
0
                    get_token();
7435
0
                    continue;
7436
0
                }
7437
7438
                // closing }
7439
0
                if (JSON_LIKELY(last_token == token_type::end_object))
7440
0
                {
7441
0
                    if (JSON_UNLIKELY(not sax->end_object()))
7442
0
                    {
7443
0
                        return false;
7444
0
                    }
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
0
                    assert(not states.empty());
7451
0
                    states.pop_back();
7452
0
                    skip_to_state_evaluation = true;
7453
0
                    continue;
7454
0
                }
7455
7456
0
                return sax->parse_error(m_lexer.get_position(),
7457
0
                                        m_lexer.get_token_string(),
7458
0
                                        parse_error::create(101, m_lexer.get_position(),
7459
0
                                                exception_message(token_type::end_object, "object")));
7460
0
            }
7461
0
        }
7462
0
    }
Unexecuted instantiation: bool nlohmann::detail::parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::sax_parse_internal<nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >(nlohmann::detail::json_sax_dom_callback_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >*)
Unexecuted instantiation: bool nlohmann::detail::parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::sax_parse_internal<nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >(nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >*)
7463
7464
    /// get next token from lexer
7465
    token_type get_token()
7466
0
    {
7467
0
        return last_token = m_lexer.scan();
7468
0
    }
7469
7470
    std::string exception_message(const token_type expected, const std::string& context)
7471
0
    {
7472
0
        std::string error_msg = "syntax error ";
7473
7474
0
        if (not context.empty())
7475
0
        {
7476
0
            error_msg += "while parsing " + context + " ";
7477
0
        }
7478
7479
0
        error_msg += "- ";
7480
7481
0
        if (last_token == token_type::parse_error)
7482
0
        {
7483
0
            error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
7484
0
                         m_lexer.get_token_string() + "'";
7485
0
        }
7486
0
        else
7487
0
        {
7488
0
            error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
7489
0
        }
7490
7491
0
        if (expected != token_type::uninitialized)
7492
0
        {
7493
0
            error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
7494
0
        }
7495
7496
0
        return error_msg;
7497
0
    }
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:
7545
    constexpr difference_type get_value() const noexcept
7546
0
    {
7547
0
        return m_it;
7548
0
    }
7549
7550
    /// set iterator to a defined beginning
7551
    void set_begin() noexcept
7552
0
    {
7553
0
        m_it = begin_value;
7554
0
    }
7555
7556
    /// set iterator to a defined past the end
7557
    void set_end() noexcept
7558
0
    {
7559
0
        m_it = end_value;
7560
0
    }
7561
7562
    /// return whether the iterator can be dereferenced
7563
    constexpr bool is_begin() const noexcept
7564
0
    {
7565
0
        return m_it == begin_value;
7566
0
    }
7567
7568
    /// return whether the iterator is at end
7569
    constexpr bool is_end() const noexcept
7570
0
    {
7571
0
        return m_it == end_value;
7572
0
    }
7573
7574
    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7575
0
    {
7576
0
        return lhs.m_it == rhs.m_it;
7577
0
    }
7578
7579
    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7580
0
    {
7581
0
        return lhs.m_it < rhs.m_it;
7582
0
    }
7583
7584
    primitive_iterator_t operator+(difference_type n) noexcept
7585
0
    {
7586
0
        auto result = *this;
7587
0
        result += n;
7588
0
        return result;
7589
0
    }
7590
7591
    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7592
0
    {
7593
0
        return lhs.m_it - rhs.m_it;
7594
0
    }
7595
7596
    primitive_iterator_t& operator++() noexcept
7597
0
    {
7598
0
        ++m_it;
7599
0
        return *this;
7600
0
    }
7601
7602
    primitive_iterator_t const operator++(int) noexcept
7603
0
    {
7604
0
        auto result = *this;
7605
0
        ++m_it;
7606
0
        return result;
7607
0
    }
7608
7609
    primitive_iterator_t& operator--() noexcept
7610
0
    {
7611
0
        --m_it;
7612
0
        return *this;
7613
0
    }
7614
7615
    primitive_iterator_t const operator--(int) noexcept
7616
0
    {
7617
0
        auto result = *this;
7618
0
        --m_it;
7619
0
        return result;
7620
0
    }
7621
7622
    primitive_iterator_t& operator+=(difference_type n) noexcept
7623
0
    {
7624
0
        m_it += n;
7625
0
        return *this;
7626
0
    }
7627
7628
    primitive_iterator_t& operator-=(difference_type n) noexcept
7629
0
    {
7630
0
        m_it -= n;
7631
0
        return *this;
7632
0
    }
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
    */
7753
    explicit iter_impl(pointer object) noexcept : m_object(object)
7754
0
    {
7755
0
        assert(m_object != nullptr);
7756
7757
0
        switch (m_object->m_type)
7758
0
        {
7759
0
            case value_t::object:
7760
0
            {
7761
0
                m_it.object_iterator = typename object_t::iterator();
7762
0
                break;
7763
0
            }
7764
7765
0
            case value_t::array:
7766
0
            {
7767
0
                m_it.array_iterator = typename array_t::iterator();
7768
0
                break;
7769
0
            }
7770
7771
0
            default:
7772
0
            {
7773
0
                m_it.primitive_iterator = primitive_iterator_t();
7774
0
                break;
7775
0
            }
7776
0
        }
7777
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::iter_impl(nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>*)
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const>::iter_impl(nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const*)
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
    */
7793
    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
7794
0
        : 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
    */
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
    */
7814
    void set_begin() noexcept
7815
0
    {
7816
0
        assert(m_object != nullptr);
7817
7818
0
        switch (m_object->m_type)
7819
0
        {
7820
0
            case value_t::object:
7821
0
            {
7822
0
                m_it.object_iterator = m_object->m_value.object->begin();
7823
0
                break;
7824
0
            }
7825
7826
0
            case value_t::array:
7827
0
            {
7828
0
                m_it.array_iterator = m_object->m_value.array->begin();
7829
0
                break;
7830
0
            }
7831
7832
0
            case value_t::null:
7833
0
            {
7834
                // set to end so begin()==end() is true: null is empty
7835
0
                m_it.primitive_iterator.set_end();
7836
0
                break;
7837
0
            }
7838
7839
0
            default:
7840
0
            {
7841
0
                m_it.primitive_iterator.set_begin();
7842
0
                break;
7843
0
            }
7844
0
        }
7845
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::set_begin()
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const>::set_begin()
7846
7847
    /*!
7848
    @brief set the iterator past the last value
7849
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
7850
    */
7851
    void set_end() noexcept
7852
0
    {
7853
0
        assert(m_object != nullptr);
7854
7855
0
        switch (m_object->m_type)
7856
0
        {
7857
0
            case value_t::object:
7858
0
            {
7859
0
                m_it.object_iterator = m_object->m_value.object->end();
7860
0
                break;
7861
0
            }
7862
7863
0
            case value_t::array:
7864
0
            {
7865
0
                m_it.array_iterator = m_object->m_value.array->end();
7866
0
                break;
7867
0
            }
7868
7869
0
            default:
7870
0
            {
7871
0
                m_it.primitive_iterator.set_end();
7872
0
                break;
7873
0
            }
7874
0
        }
7875
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::set_end()
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const>::set_end()
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
    */
7882
    reference operator*() const
7883
0
    {
7884
0
        assert(m_object != nullptr);
7885
7886
0
        switch (m_object->m_type)
7887
0
        {
7888
0
            case value_t::object:
7889
0
            {
7890
0
                assert(m_it.object_iterator != m_object->m_value.object->end());
7891
0
                return m_it.object_iterator->second;
7892
0
            }
7893
7894
0
            case value_t::array:
7895
0
            {
7896
0
                assert(m_it.array_iterator != m_object->m_value.array->end());
7897
0
                return *m_it.array_iterator;
7898
0
            }
7899
7900
0
            case value_t::null:
7901
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7902
7903
0
            default:
7904
0
            {
7905
0
                if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7906
0
                {
7907
0
                    return *m_object;
7908
0
                }
7909
7910
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7911
0
            }
7912
0
        }
7913
0
    }
7914
7915
    /*!
7916
    @brief dereference the iterator
7917
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
7918
    */
7919
    pointer operator->() const
7920
0
    {
7921
0
        assert(m_object != nullptr);
7922
7923
0
        switch (m_object->m_type)
7924
0
        {
7925
0
            case value_t::object:
7926
0
            {
7927
0
                assert(m_it.object_iterator != m_object->m_value.object->end());
7928
0
                return &(m_it.object_iterator->second);
7929
0
            }
7930
7931
0
            case value_t::array:
7932
0
            {
7933
0
                assert(m_it.array_iterator != m_object->m_value.array->end());
7934
0
                return &*m_it.array_iterator;
7935
0
            }
7936
7937
0
            default:
7938
0
            {
7939
0
                if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7940
0
                {
7941
0
                    return m_object;
7942
0
                }
7943
7944
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7945
0
            }
7946
0
        }
7947
0
    }
7948
7949
    /*!
7950
    @brief post-increment (it++)
7951
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
7952
    */
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
    */
7964
    iter_impl& operator++()
7965
0
    {
7966
0
        assert(m_object != nullptr);
7967
7968
0
        switch (m_object->m_type)
7969
0
        {
7970
0
            case value_t::object:
7971
0
            {
7972
0
                std::advance(m_it.object_iterator, 1);
7973
0
                break;
7974
0
            }
7975
7976
0
            case value_t::array:
7977
0
            {
7978
0
                std::advance(m_it.array_iterator, 1);
7979
0
                break;
7980
0
            }
7981
7982
0
            default:
7983
0
            {
7984
0
                ++m_it.primitive_iterator;
7985
0
                break;
7986
0
            }
7987
0
        }
7988
7989
0
        return *this;
7990
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::operator++()
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const>::operator++()
7991
7992
    /*!
7993
    @brief post-decrement (it--)
7994
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
7995
    */
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
    */
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
    */
8039
    bool operator==(const iter_impl& other) const
8040
0
    {
8041
        // if objects are not the same, the comparison is undefined
8042
0
        if (JSON_UNLIKELY(m_object != other.m_object))
8043
0
        {
8044
0
            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8045
0
        }
8046
8047
0
        assert(m_object != nullptr);
8048
8049
0
        switch (m_object->m_type)
8050
0
        {
8051
0
            case value_t::object:
8052
0
                return (m_it.object_iterator == other.m_it.object_iterator);
8053
8054
0
            case value_t::array:
8055
0
                return (m_it.array_iterator == other.m_it.array_iterator);
8056
8057
0
            default:
8058
0
                return (m_it.primitive_iterator == other.m_it.primitive_iterator);
8059
0
        }
8060
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::operator==(nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > const&) const
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const>::operator==(nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const> const&) const
8061
8062
    /*!
8063
    @brief  comparison: not equal
8064
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
8065
    */
8066
    bool operator!=(const iter_impl& other) const
8067
0
    {
8068
0
        return not operator==(other);
8069
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::operator!=(nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > const&) const
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const>::operator!=(nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> const> const&) const
8070
8071
    /*!
8072
    @brief  comparison: smaller
8073
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
8074
    */
8075
    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
    */
8102
    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
    */
8111
    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
    */
8120
    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
    */
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
    */
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
    */
8167
    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
    */
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
    */
8189
    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
    */
8200
    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
    */
8221
    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
    */
8252
    const typename object_t::key_type& key() const
8253
0
    {
8254
0
        assert(m_object != nullptr);
8255
8256
0
        if (JSON_LIKELY(m_object->is_object()))
8257
0
        {
8258
0
            return m_it.object_iterator->first;
8259
0
        }
8260
8261
0
        JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
8262
0
    }
8263
8264
    /*!
8265
    @brief  return the value of an iterator
8266
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
8267
    */
8268
    reference value() const
8269
0
    {
8270
0
        return operator*();
8271
0
    }
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
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
8332
    explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
8333
8334
    /// post-increment (it++)
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)
8341
    json_reverse_iterator& operator++()
8342
    {
8343
        return static_cast<json_reverse_iterator&>(base_iterator::operator++());
8344
    }
8345
8346
    /// post-decrement (it--)
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)
8353
    json_reverse_iterator& operator--()
8354
    {
8355
        return static_cast<json_reverse_iterator&>(base_iterator::operator--());
8356
    }
8357
8358
    /// add to iterator
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
8365
    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
8371
    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
8377
    difference_type operator-(const json_reverse_iterator& other) const
8378
    {
8379
        return base_iterator(*this) - base_iterator(other);
8380
    }
8381
8382
    /// access to successor
8383
    reference operator[](difference_type n) const
8384
    {
8385
        return *(this->operator+(n));
8386
    }
8387
8388
    /// return the key of an object iterator
8389
    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
8396
    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
    */
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
    */
8473
    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()
8484
    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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
8630
    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
    */
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
    */
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
    */
8701
    void push_back(const std::string& token)
8702
    {
8703
        reference_tokens.push_back(token);
8704
    }
8705
8706
    /// @copydoc push_back(const std::string&)
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
    */
8726
    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
    */
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
8753
    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
    */
8773
    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
    */
8853
    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
    */
8929
    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
    */
8994
    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
    */
9053
    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
    */
9114
    static std::vector<std::string> split(const std::string& reference_string)
9115
0
    {
9116
0
        std::vector<std::string> result;
9117
0
9118
0
        // special case: empty reference string -> no reference tokens
9119
0
        if (reference_string.empty())
9120
0
        {
9121
0
            return result;
9122
0
        }
9123
0
9124
0
        // check if nonempty reference string begins with slash
9125
0
        if (JSON_UNLIKELY(reference_string[0] != '/'))
9126
0
        {
9127
0
            JSON_THROW(detail::parse_error::create(107, 1,
9128
0
                                                   "JSON pointer must be empty or begin with '/' - was: '" +
9129
0
                                                   reference_string + "'"));
9130
0
        }
9131
0
9132
0
        // extract the reference tokens:
9133
0
        // - slash: position of the last read slash (or end of string)
9134
0
        // - start: position after the previous slash
9135
0
        for (
9136
0
            // search for the first slash after the first character
9137
0
            std::size_t slash = reference_string.find_first_of('/', 1),
9138
0
            // set the beginning of the first reference token
9139
0
            start = 1;
9140
0
            // we can stop if start == 0 (if slash == std::string::npos)
9141
0
            start != 0;
9142
0
            // set the beginning of the next reference token
9143
0
            // (will eventually be 0 if slash == std::string::npos)
9144
0
            start = (slash == std::string::npos) ? 0 : slash + 1,
9145
0
            // find next slash
9146
0
            slash = reference_string.find_first_of('/', start))
9147
0
        {
9148
0
            // use the text between the beginning of the reference token
9149
0
            // (start) and the last slash (slash).
9150
0
            auto reference_token = reference_string.substr(start, slash - start);
9151
0
9152
0
            // check reference tokens are properly escaped
9153
0
            for (std::size_t pos = reference_token.find_first_of('~');
9154
0
                    pos != std::string::npos;
9155
0
                    pos = reference_token.find_first_of('~', pos + 1))
9156
0
            {
9157
0
                assert(reference_token[pos] == '~');
9158
0
9159
0
                // ~ must be followed by 0 or 1
9160
0
                if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
9161
0
                                  (reference_token[pos + 1] != '0' and
9162
0
                                   reference_token[pos + 1] != '1')))
9163
0
                {
9164
0
                    JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
9165
0
                }
9166
0
            }
9167
0
9168
0
            // finally, store the reference token
9169
0
            unescape(reference_token);
9170
0
            result.push_back(reference_token);
9171
0
        }
9172
0
9173
0
        return result;
9174
0
    }
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
    */
9189
    static void replace_substring(std::string& s, const std::string& f,
9190
                                  const std::string& t)
9191
0
    {
9192
0
        assert(not f.empty());
9193
0
        for (auto pos = s.find(f);                // find first occurrence of f
9194
0
                pos != std::string::npos;         // make sure f was found
9195
0
                s.replace(pos, f.size(), t),      // replace with t, and
9196
0
                pos = s.find(f, pos + t.size()))  // find next occurrence of f
9197
0
        {}
9198
0
    }
9199
9200
    /// escape "~" to "~0" and "/" to "~1"
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!)
9209
    static void unescape(std::string& s)
9210
0
    {
9211
0
        replace_substring(s, "~1", "/");
9212
0
        replace_substring(s, "~0", "~");
9213
0
    }
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
    */
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
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
    */
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
    */
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
9370
    json_ref(value_type&& value)
9371
        : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
9372
    {}
9373
9374
    json_ref(const value_type& value)
9375
        : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
9376
    {}
9377
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 >
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
9396
    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
9405
    value_type const& operator*() const
9406
    {
9407
        return *static_cast<value_type const*>(value_ref);
9408
    }
9409
9410
    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:
9474
    explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
9475
        : v(vec)
9476
    {}
9477
9478
    void write_character(CharType c) override
9479
    {
9480
        v.push_back(c);
9481
    }
9482
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:
9497
    explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
9498
        : stream(s)
9499
    {}
9500
9501
    void write_character(CharType c) override
9502
    {
9503
        stream.put(c);
9504
    }
9505
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:
9520
    explicit output_string_adapter(StringType& s) noexcept
9521
        : str(s)
9522
    {}
9523
9524
    void write_character(CharType c) override
9525
0
    {
9526
0
        str.push_back(c);
9527
0
    }
9528
9529
    void write_characters(const CharType* s, std::size_t length) override
9530
0
    {
9531
0
        str.append(s, length);
9532
0
    }
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:
9542
    output_adapter(std::vector<CharType>& vec)
9543
        : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
9544
9545
    output_adapter(std::basic_ostream<CharType>& s)
9546
        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
9547
9548
    output_adapter(StringType& s)
9549
        : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
9550
9551
    operator output_adapter_t<CharType>()
9552
0
    {
9553
0
        return oa;
9554
0
    }
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
10566
    static constexpr CharType get_cbor_float_prefix(float /*unused*/)
10567
    {
10568
        return to_char_type(0xFA);  // Single-Precision Float
10569
    }
10570
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
10580
    static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
10581
    {
10582
        return to_char_type(0xCA);  // float 32
10583
    }
10584
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>
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>
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>
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
    */
10723
    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
10794
    static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
10795
    {
10796
        return 'd';  // float 32
10797
    }
10798
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>
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 >
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 >
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>
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 >
10872
    static constexpr CharType to_char_type(InputCharType x) noexcept
10873
0
    {
10874
0
        return x;
10875
0
    }
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
0
{
10948
0
    static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
10949
0
10950
0
    Target target;
10951
0
    std::memcpy(&target, &source, sizeof(Source));
10952
0
    return target;
10953
0
}
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
10962
0
    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
    */
10968
    static diyfp sub(const diyfp& x, const diyfp& y) noexcept
10969
0
    {
10970
0
        assert(x.e == y.e);
10971
0
        assert(x.f >= y.f);
10972
0
10973
0
        return {x.f - y.f, x.e};
10974
0
    }
10975
10976
    /*!
10977
    @brief returns x * y
10978
    @note The result is rounded. (Only the upper q bits are returned.)
10979
    */
10980
    static diyfp mul(const diyfp& x, const diyfp& y) noexcept
10981
0
    {
10982
0
        static_assert(kPrecision == 64, "internal error");
10983
0
10984
0
        // Computes:
10985
0
        //  f = round((x.f * y.f) / 2^q)
10986
0
        //  e = x.e + y.e + q
10987
0
10988
0
        // Emulate the 64-bit * 64-bit multiplication:
10989
0
        //
10990
0
        // p = u * v
10991
0
        //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
10992
0
        //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
10993
0
        //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
10994
0
        //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
10995
0
        //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
10996
0
        //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
10997
0
        //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
10998
0
        //
10999
0
        // (Since Q might be larger than 2^32 - 1)
11000
0
        //
11001
0
        //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
11002
0
        //
11003
0
        // (Q_hi + H does not overflow a 64-bit int)
11004
0
        //
11005
0
        //   = p_lo + 2^64 p_hi
11006
0
11007
0
        const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
11008
0
        const std::uint64_t u_hi = x.f >> 32u;
11009
0
        const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
11010
0
        const std::uint64_t v_hi = y.f >> 32u;
11011
0
11012
0
        const std::uint64_t p0 = u_lo * v_lo;
11013
0
        const std::uint64_t p1 = u_lo * v_hi;
11014
0
        const std::uint64_t p2 = u_hi * v_lo;
11015
0
        const std::uint64_t p3 = u_hi * v_hi;
11016
0
11017
0
        const std::uint64_t p0_hi = p0 >> 32u;
11018
0
        const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
11019
0
        const std::uint64_t p1_hi = p1 >> 32u;
11020
0
        const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
11021
0
        const std::uint64_t p2_hi = p2 >> 32u;
11022
0
11023
0
        std::uint64_t Q = p0_hi + p1_lo + p2_lo;
11024
0
11025
0
        // The full product might now be computed as
11026
0
        //
11027
0
        // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
11028
0
        // p_lo = p0_lo + (Q << 32)
11029
0
        //
11030
0
        // But in this particular case here, the full p_lo is not required.
11031
0
        // Effectively we only need to add the highest bit in p_lo to p_hi (and
11032
0
        // Q_hi + 1 does not overflow).
11033
0
11034
0
        Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
11035
0
11036
0
        const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
11037
0
11038
0
        return {h, x.e + y.e + 64};
11039
0
    }
11040
11041
    /*!
11042
    @brief normalize x such that the significand is >= 2^(q-1)
11043
    @pre x.f != 0
11044
    */
11045
    static diyfp normalize(diyfp x) noexcept
11046
0
    {
11047
0
        assert(x.f != 0);
11048
0
11049
0
        while ((x.f >> 63u) == 0)
11050
0
        {
11051
0
            x.f <<= 1u;
11052
0
            x.e--;
11053
0
        }
11054
0
11055
0
        return x;
11056
0
    }
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
    */
11062
    static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
11063
0
    {
11064
0
        const int delta = x.e - target_exponent;
11065
0
11066
0
        assert(delta >= 0);
11067
0
        assert(((x.f << delta) >> delta) == x.f);
11068
0
11069
0
        return {x.f << delta, target_exponent};
11070
0
    }
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>
11087
boundaries compute_boundaries(FloatType value)
11088
0
{
11089
0
    assert(std::isfinite(value));
11090
0
    assert(value > 0);
11091
0
11092
0
    // Convert the IEEE representation into a diyfp.
11093
0
    //
11094
0
    // If v is denormal:
11095
0
    //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
11096
0
    // If v is normalized:
11097
0
    //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
11098
0
11099
0
    static_assert(std::numeric_limits<FloatType>::is_iec559,
11100
0
                  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
11101
0
11102
0
    constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
11103
0
    constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
11104
0
    constexpr int      kMinExp    = 1 - kBias;
11105
0
    constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
11106
0
11107
0
    using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
11108
0
11109
0
    const std::uint64_t bits = reinterpret_bits<bits_type>(value);
11110
0
    const std::uint64_t E = bits >> (kPrecision - 1);
11111
0
    const std::uint64_t F = bits & (kHiddenBit - 1);
11112
0
11113
0
    const bool is_denormal = E == 0;
11114
0
    const diyfp v = is_denormal
11115
0
                    ? diyfp(F, kMinExp)
11116
0
                    : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
11117
0
11118
0
    // Compute the boundaries m- and m+ of the floating-point value
11119
0
    // v = f * 2^e.
11120
0
    //
11121
0
    // Determine v- and v+, the floating-point predecessor and successor if v,
11122
0
    // respectively.
11123
0
    //
11124
0
    //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
11125
0
    //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
11126
0
    //
11127
0
    //      v+ = v + 2^e
11128
0
    //
11129
0
    // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
11130
0
    // between m- and m+ round to v, regardless of how the input rounding
11131
0
    // algorithm breaks ties.
11132
0
    //
11133
0
    //      ---+-------------+-------------+-------------+-------------+---  (A)
11134
0
    //         v-            m-            v             m+            v+
11135
0
    //
11136
0
    //      -----------------+------+------+-------------+-------------+---  (B)
11137
0
    //                       v-     m-     v             m+            v+
11138
0
11139
0
    const bool lower_boundary_is_closer = F == 0 and E > 1;
11140
0
    const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
11141
0
    const diyfp m_minus = lower_boundary_is_closer
11142
0
                          ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
11143
0
                          : diyfp(2 * v.f - 1, v.e - 1); // (A)
11144
0
11145
0
    // Determine the normalized w+ = m+.
11146
0
    const diyfp w_plus = diyfp::normalize(m_plus);
11147
0
11148
0
    // Determine w- = m- such that e_(w-) = e_(w+).
11149
0
    const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
11150
0
11151
0
    return {diyfp::normalize(v), w_minus, w_plus};
11152
0
}
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
*/
11226
inline cached_power get_cached_power_for_binary_exponent(int e)
11227
0
{
11228
0
    // Now
11229
0
    //
11230
0
    //      alpha <= e_c + e + q <= gamma                                    (1)
11231
0
    //      ==> f_c * 2^alpha <= c * 2^e * 2^q
11232
0
    //
11233
0
    // and since the c's are normalized, 2^(q-1) <= f_c,
11234
0
    //
11235
0
    //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
11236
0
    //      ==> 2^(alpha - e - 1) <= c
11237
0
    //
11238
0
    // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
11239
0
    //
11240
0
    //      k = ceil( log_10( 2^(alpha - e - 1) ) )
11241
0
    //        = ceil( (alpha - e - 1) * log_10(2) )
11242
0
    //
11243
0
    // From the paper:
11244
0
    // "In theory the result of the procedure could be wrong since c is rounded,
11245
0
    //  and the computation itself is approximated [...]. In practice, however,
11246
0
    //  this simple function is sufficient."
11247
0
    //
11248
0
    // For IEEE double precision floating-point numbers converted into
11249
0
    // normalized diyfp's w = f * 2^e, with q = 64,
11250
0
    //
11251
0
    //      e >= -1022      (min IEEE exponent)
11252
0
    //           -52        (p - 1)
11253
0
    //           -52        (p - 1, possibly normalize denormal IEEE numbers)
11254
0
    //           -11        (normalize the diyfp)
11255
0
    //         = -1137
11256
0
    //
11257
0
    // and
11258
0
    //
11259
0
    //      e <= +1023      (max IEEE exponent)
11260
0
    //           -52        (p - 1)
11261
0
    //           -11        (normalize the diyfp)
11262
0
    //         = 960
11263
0
    //
11264
0
    // This binary exponent range [-1137,960] results in a decimal exponent
11265
0
    // range [-307,324]. One does not need to store a cached power for each
11266
0
    // k in this range. For each such k it suffices to find a cached power
11267
0
    // such that the exponent of the product lies in [alpha,gamma].
11268
0
    // This implies that the difference of the decimal exponents of adjacent
11269
0
    // table entries must be less than or equal to
11270
0
    //
11271
0
    //      floor( (gamma - alpha) * log_10(2) ) = 8.
11272
0
    //
11273
0
    // (A smaller distance gamma-alpha would require a larger table.)
11274
0
11275
0
    // NB:
11276
0
    // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
11277
0
11278
0
    constexpr int kCachedPowersMinDecExp = -300;
11279
0
    constexpr int kCachedPowersDecStep = 8;
11280
0
11281
0
    static constexpr std::array<cached_power, 79> kCachedPowers =
11282
0
    {
11283
0
        {
11284
0
            { 0xAB70FE17C79AC6CA, -1060, -300 },
11285
0
            { 0xFF77B1FCBEBCDC4F, -1034, -292 },
11286
0
            { 0xBE5691EF416BD60C, -1007, -284 },
11287
0
            { 0x8DD01FAD907FFC3C,  -980, -276 },
11288
0
            { 0xD3515C2831559A83,  -954, -268 },
11289
0
            { 0x9D71AC8FADA6C9B5,  -927, -260 },
11290
0
            { 0xEA9C227723EE8BCB,  -901, -252 },
11291
0
            { 0xAECC49914078536D,  -874, -244 },
11292
0
            { 0x823C12795DB6CE57,  -847, -236 },
11293
0
            { 0xC21094364DFB5637,  -821, -228 },
11294
0
            { 0x9096EA6F3848984F,  -794, -220 },
11295
0
            { 0xD77485CB25823AC7,  -768, -212 },
11296
0
            { 0xA086CFCD97BF97F4,  -741, -204 },
11297
0
            { 0xEF340A98172AACE5,  -715, -196 },
11298
0
            { 0xB23867FB2A35B28E,  -688, -188 },
11299
0
            { 0x84C8D4DFD2C63F3B,  -661, -180 },
11300
0
            { 0xC5DD44271AD3CDBA,  -635, -172 },
11301
0
            { 0x936B9FCEBB25C996,  -608, -164 },
11302
0
            { 0xDBAC6C247D62A584,  -582, -156 },
11303
0
            { 0xA3AB66580D5FDAF6,  -555, -148 },
11304
0
            { 0xF3E2F893DEC3F126,  -529, -140 },
11305
0
            { 0xB5B5ADA8AAFF80B8,  -502, -132 },
11306
0
            { 0x87625F056C7C4A8B,  -475, -124 },
11307
0
            { 0xC9BCFF6034C13053,  -449, -116 },
11308
0
            { 0x964E858C91BA2655,  -422, -108 },
11309
0
            { 0xDFF9772470297EBD,  -396, -100 },
11310
0
            { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
11311
0
            { 0xF8A95FCF88747D94,  -343,  -84 },
11312
0
            { 0xB94470938FA89BCF,  -316,  -76 },
11313
0
            { 0x8A08F0F8BF0F156B,  -289,  -68 },
11314
0
            { 0xCDB02555653131B6,  -263,  -60 },
11315
0
            { 0x993FE2C6D07B7FAC,  -236,  -52 },
11316
0
            { 0xE45C10C42A2B3B06,  -210,  -44 },
11317
0
            { 0xAA242499697392D3,  -183,  -36 },
11318
0
            { 0xFD87B5F28300CA0E,  -157,  -28 },
11319
0
            { 0xBCE5086492111AEB,  -130,  -20 },
11320
0
            { 0x8CBCCC096F5088CC,  -103,  -12 },
11321
0
            { 0xD1B71758E219652C,   -77,   -4 },
11322
0
            { 0x9C40000000000000,   -50,    4 },
11323
0
            { 0xE8D4A51000000000,   -24,   12 },
11324
0
            { 0xAD78EBC5AC620000,     3,   20 },
11325
0
            { 0x813F3978F8940984,    30,   28 },
11326
0
            { 0xC097CE7BC90715B3,    56,   36 },
11327
0
            { 0x8F7E32CE7BEA5C70,    83,   44 },
11328
0
            { 0xD5D238A4ABE98068,   109,   52 },
11329
0
            { 0x9F4F2726179A2245,   136,   60 },
11330
0
            { 0xED63A231D4C4FB27,   162,   68 },
11331
0
            { 0xB0DE65388CC8ADA8,   189,   76 },
11332
0
            { 0x83C7088E1AAB65DB,   216,   84 },
11333
0
            { 0xC45D1DF942711D9A,   242,   92 },
11334
0
            { 0x924D692CA61BE758,   269,  100 },
11335
0
            { 0xDA01EE641A708DEA,   295,  108 },
11336
0
            { 0xA26DA3999AEF774A,   322,  116 },
11337
0
            { 0xF209787BB47D6B85,   348,  124 },
11338
0
            { 0xB454E4A179DD1877,   375,  132 },
11339
0
            { 0x865B86925B9BC5C2,   402,  140 },
11340
0
            { 0xC83553C5C8965D3D,   428,  148 },
11341
0
            { 0x952AB45CFA97A0B3,   455,  156 },
11342
0
            { 0xDE469FBD99A05FE3,   481,  164 },
11343
0
            { 0xA59BC234DB398C25,   508,  172 },
11344
0
            { 0xF6C69A72A3989F5C,   534,  180 },
11345
0
            { 0xB7DCBF5354E9BECE,   561,  188 },
11346
0
            { 0x88FCF317F22241E2,   588,  196 },
11347
0
            { 0xCC20CE9BD35C78A5,   614,  204 },
11348
0
            { 0x98165AF37B2153DF,   641,  212 },
11349
0
            { 0xE2A0B5DC971F303A,   667,  220 },
11350
0
            { 0xA8D9D1535CE3B396,   694,  228 },
11351
0
            { 0xFB9B7CD9A4A7443C,   720,  236 },
11352
0
            { 0xBB764C4CA7A44410,   747,  244 },
11353
0
            { 0x8BAB8EEFB6409C1A,   774,  252 },
11354
0
            { 0xD01FEF10A657842C,   800,  260 },
11355
0
            { 0x9B10A4E5E9913129,   827,  268 },
11356
0
            { 0xE7109BFBA19C0C9D,   853,  276 },
11357
0
            { 0xAC2820D9623BF429,   880,  284 },
11358
0
            { 0x80444B5E7AA7CF85,   907,  292 },
11359
0
            { 0xBF21E44003ACDD2D,   933,  300 },
11360
0
            { 0x8E679C2F5E44FF8F,   960,  308 },
11361
0
            { 0xD433179D9C8CB841,   986,  316 },
11362
0
            { 0x9E19DB92B4E31BA9,  1013,  324 },
11363
0
        }
11364
0
    };
11365
0
11366
0
    // This computation gives exactly the same results for k as
11367
0
    //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
11368
0
    // for |e| <= 1500, but doesn't require floating-point operations.
11369
0
    // NB: log_10(2) ~= 78913 / 2^18
11370
0
    assert(e >= -1500);
11371
0
    assert(e <=  1500);
11372
0
    const int f = kAlpha - e - 1;
11373
0
    const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
11374
0
11375
0
    const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
11376
0
    assert(index >= 0);
11377
0
    assert(static_cast<std::size_t>(index) < kCachedPowers.size());
11378
0
11379
0
    const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
11380
0
    assert(kAlpha <= cached.e + e + 64);
11381
0
    assert(kGamma >= cached.e + e + 64);
11382
0
11383
0
    return cached;
11384
0
}
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
*/
11390
inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
11391
0
{
11392
0
    // LCOV_EXCL_START
11393
0
    if (n >= 1000000000)
11394
0
    {
11395
0
        pow10 = 1000000000;
11396
0
        return 10;
11397
0
    }
11398
0
    // LCOV_EXCL_STOP
11399
0
    else if (n >= 100000000)
11400
0
    {
11401
0
        pow10 = 100000000;
11402
0
        return  9;
11403
0
    }
11404
0
    else if (n >= 10000000)
11405
0
    {
11406
0
        pow10 = 10000000;
11407
0
        return  8;
11408
0
    }
11409
0
    else if (n >= 1000000)
11410
0
    {
11411
0
        pow10 = 1000000;
11412
0
        return  7;
11413
0
    }
11414
0
    else if (n >= 100000)
11415
0
    {
11416
0
        pow10 = 100000;
11417
0
        return  6;
11418
0
    }
11419
0
    else if (n >= 10000)
11420
0
    {
11421
0
        pow10 = 10000;
11422
0
        return  5;
11423
0
    }
11424
0
    else if (n >= 1000)
11425
0
    {
11426
0
        pow10 = 1000;
11427
0
        return  4;
11428
0
    }
11429
0
    else if (n >= 100)
11430
0
    {
11431
0
        pow10 = 100;
11432
0
        return  3;
11433
0
    }
11434
0
    else if (n >= 10)
11435
0
    {
11436
0
        pow10 = 10;
11437
0
        return  2;
11438
0
    }
11439
0
    else
11440
0
    {
11441
0
        pow10 = 1;
11442
0
        return 1;
11443
0
    }
11444
0
}
11445
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
0
{
11449
0
    assert(len >= 1);
11450
0
    assert(dist <= delta);
11451
0
    assert(rest <= delta);
11452
0
    assert(ten_k > 0);
11453
0
11454
0
    //               <--------------------------- delta ---->
11455
0
    //                                  <---- dist --------->
11456
0
    // --------------[------------------+-------------------]--------------
11457
0
    //               M-                 w                   M+
11458
0
    //
11459
0
    //                                  ten_k
11460
0
    //                                <------>
11461
0
    //                                       <---- rest ---->
11462
0
    // --------------[------------------+----+--------------]--------------
11463
0
    //                                  w    V
11464
0
    //                                       = buf * 10^k
11465
0
    //
11466
0
    // ten_k represents a unit-in-the-last-place in the decimal representation
11467
0
    // stored in buf.
11468
0
    // Decrement buf by ten_k while this takes buf closer to w.
11469
0
11470
0
    // The tests are written in this order to avoid overflow in unsigned
11471
0
    // integer arithmetic.
11472
0
11473
0
    while (rest < dist
11474
0
            and delta - rest >= ten_k
11475
0
            and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
11476
0
    {
11477
0
        assert(buf[len - 1] != '0');
11478
0
        buf[len - 1]--;
11479
0
        rest += ten_k;
11480
0
    }
11481
0
}
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
*/
11487
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
11488
                             diyfp M_minus, diyfp w, diyfp M_plus)
11489
0
{
11490
0
    static_assert(kAlpha >= -60, "internal error");
11491
0
    static_assert(kGamma <= -32, "internal error");
11492
0
11493
0
    // Generates the digits (and the exponent) of a decimal floating-point
11494
0
    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
11495
0
    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
11496
0
    //
11497
0
    //               <--------------------------- delta ---->
11498
0
    //                                  <---- dist --------->
11499
0
    // --------------[------------------+-------------------]--------------
11500
0
    //               M-                 w                   M+
11501
0
    //
11502
0
    // Grisu2 generates the digits of M+ from left to right and stops as soon as
11503
0
    // V is in [M-,M+].
11504
0
11505
0
    assert(M_plus.e >= kAlpha);
11506
0
    assert(M_plus.e <= kGamma);
11507
0
11508
0
    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
11509
0
    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
11510
0
11511
0
    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
11512
0
    //
11513
0
    //      M+ = f * 2^e
11514
0
    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
11515
0
    //         = ((p1        ) * 2^-e + (p2        )) * 2^e
11516
0
    //         = p1 + p2 * 2^e
11517
0
11518
0
    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
11519
0
11520
0
    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
0
    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
11522
0
11523
0
    // 1)
11524
0
    //
11525
0
    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
11526
0
11527
0
    assert(p1 > 0);
11528
0
11529
0
    std::uint32_t pow10;
11530
0
    const int k = find_largest_pow10(p1, pow10);
11531
0
11532
0
    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
11533
0
    //
11534
0
    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
11535
0
    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
11536
0
    //
11537
0
    //      M+ = p1                                             + p2 * 2^e
11538
0
    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
11539
0
    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
11540
0
    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
11541
0
    //
11542
0
    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
11543
0
    //
11544
0
    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
11545
0
    //
11546
0
    // but stop as soon as
11547
0
    //
11548
0
    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
11549
0
11550
0
    int n = k;
11551
0
    while (n > 0)
11552
0
    {
11553
0
        // Invariants:
11554
0
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
11555
0
        //      pow10 = 10^(n-1) <= p1 < 10^n
11556
0
        //
11557
0
        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
11558
0
        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
11559
0
        //
11560
0
        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
11561
0
        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
11562
0
        //
11563
0
        assert(d <= 9);
11564
0
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
11565
0
        //
11566
0
        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
11567
0
        //
11568
0
        p1 = r;
11569
0
        n--;
11570
0
        //
11571
0
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
11572
0
        //      pow10 = 10^n
11573
0
        //
11574
0
11575
0
        // Now check if enough digits have been generated.
11576
0
        // Compute
11577
0
        //
11578
0
        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
11579
0
        //
11580
0
        // Note:
11581
0
        // Since rest and delta share the same exponent e, it suffices to
11582
0
        // compare the significands.
11583
0
        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
11584
0
        if (rest <= delta)
11585
0
        {
11586
0
            // V = buffer * 10^n, with M- <= V <= M+.
11587
0
11588
0
            decimal_exponent += n;
11589
0
11590
0
            // We may now just stop. But instead look if the buffer could be
11591
0
            // decremented to bring V closer to w.
11592
0
            //
11593
0
            // pow10 = 10^n is now 1 ulp in the decimal representation V.
11594
0
            // The rounding procedure works with diyfp's with an implicit
11595
0
            // exponent of e.
11596
0
            //
11597
0
            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
11598
0
            //
11599
0
            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
11600
0
            grisu2_round(buffer, length, dist, delta, rest, ten_n);
11601
0
11602
0
            return;
11603
0
        }
11604
0
11605
0
        pow10 /= 10;
11606
0
        //
11607
0
        //      pow10 = 10^(n-1) <= p1 < 10^n
11608
0
        // Invariants restored.
11609
0
    }
11610
0
11611
0
    // 2)
11612
0
    //
11613
0
    // The digits of the integral part have been generated:
11614
0
    //
11615
0
    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
11616
0
    //         = buffer            + p2 * 2^e
11617
0
    //
11618
0
    // Now generate the digits of the fractional part p2 * 2^e.
11619
0
    //
11620
0
    // Note:
11621
0
    // No decimal point is generated: the exponent is adjusted instead.
11622
0
    //
11623
0
    // p2 actually represents the fraction
11624
0
    //
11625
0
    //      p2 * 2^e
11626
0
    //          = p2 / 2^-e
11627
0
    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
11628
0
    //
11629
0
    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
11630
0
    //
11631
0
    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
11632
0
    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
11633
0
    //
11634
0
    // using
11635
0
    //
11636
0
    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
11637
0
    //                = (                   d) * 2^-e + (                   r)
11638
0
    //
11639
0
    // or
11640
0
    //      10^m * p2 * 2^e = d + r * 2^e
11641
0
    //
11642
0
    // i.e.
11643
0
    //
11644
0
    //      M+ = buffer + p2 * 2^e
11645
0
    //         = buffer + 10^-m * (d + r * 2^e)
11646
0
    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
11647
0
    //
11648
0
    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
11649
0
11650
0
    assert(p2 > delta);
11651
0
11652
0
    int m = 0;
11653
0
    for (;;)
11654
0
    {
11655
0
        // Invariant:
11656
0
        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
11657
0
        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
11658
0
        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
11659
0
        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
11660
0
        //
11661
0
        assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
11662
0
        p2 *= 10;
11663
0
        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
11664
0
        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
11665
0
        //
11666
0
        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
11667
0
        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
11668
0
        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
11669
0
        //
11670
0
        assert(d <= 9);
11671
0
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
11672
0
        //
11673
0
        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
11674
0
        //
11675
0
        p2 = r;
11676
0
        m++;
11677
0
        //
11678
0
        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
11679
0
        // Invariant restored.
11680
0
11681
0
        // Check if enough digits have been generated.
11682
0
        //
11683
0
        //      10^-m * p2 * 2^e <= delta * 2^e
11684
0
        //              p2 * 2^e <= 10^m * delta * 2^e
11685
0
        //                    p2 <= 10^m * delta
11686
0
        delta *= 10;
11687
0
        dist  *= 10;
11688
0
        if (p2 <= delta)
11689
0
        {
11690
0
            break;
11691
0
        }
11692
0
    }
11693
0
11694
0
    // V = buffer * 10^-m, with M- <= V <= M+.
11695
0
11696
0
    decimal_exponent -= m;
11697
0
11698
0
    // 1 ulp in the decimal representation is now 10^-m.
11699
0
    // Since delta and dist are now scaled by 10^m, we need to do the
11700
0
    // same with ulp in order to keep the units in sync.
11701
0
    //
11702
0
    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
11703
0
    //
11704
0
    const std::uint64_t ten_m = one.f;
11705
0
    grisu2_round(buffer, length, dist, delta, p2, ten_m);
11706
0
11707
0
    // By construction this algorithm generates the shortest possible decimal
11708
0
    // number (Loitsch, Theorem 6.2) which rounds back to w.
11709
0
    // For an input number of precision p, at least
11710
0
    //
11711
0
    //      N = 1 + ceil(p * log_10(2))
11712
0
    //
11713
0
    // decimal digits are sufficient to identify all binary floating-point
11714
0
    // numbers (Matula, "In-and-Out conversions").
11715
0
    // This implies that the algorithm does not produce more than N decimal
11716
0
    // digits.
11717
0
    //
11718
0
    //      N = 17 for p = 53 (IEEE double precision)
11719
0
    //      N = 9  for p = 24 (IEEE single precision)
11720
0
}
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
*/
11727
inline void grisu2(char* buf, int& len, int& decimal_exponent,
11728
                   diyfp m_minus, diyfp v, diyfp m_plus)
11729
0
{
11730
0
    assert(m_plus.e == m_minus.e);
11731
0
    assert(m_plus.e == v.e);
11732
0
11733
0
    //  --------(-----------------------+-----------------------)--------    (A)
11734
0
    //          m-                      v                       m+
11735
0
    //
11736
0
    //  --------------------(-----------+-----------------------)--------    (B)
11737
0
    //                      m-          v                       m+
11738
0
    //
11739
0
    // First scale v (and m- and m+) such that the exponent is in the range
11740
0
    // [alpha, gamma].
11741
0
11742
0
    const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
11743
0
11744
0
    const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
11745
0
11746
0
    // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
11747
0
    const diyfp w       = diyfp::mul(v,       c_minus_k);
11748
0
    const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
11749
0
    const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
11750
0
11751
0
    //  ----(---+---)---------------(---+---)---------------(---+---)----
11752
0
    //          w-                      w                       w+
11753
0
    //          = c*m-                  = c*v                   = c*m+
11754
0
    //
11755
0
    // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
11756
0
    // w+ are now off by a small amount.
11757
0
    // In fact:
11758
0
    //
11759
0
    //      w - v * 10^k < 1 ulp
11760
0
    //
11761
0
    // To account for this inaccuracy, add resp. subtract 1 ulp.
11762
0
    //
11763
0
    //  --------+---[---------------(---+---)---------------]---+--------
11764
0
    //          w-  M-                  w                   M+  w+
11765
0
    //
11766
0
    // Now any number in [M-, M+] (bounds included) will round to w when input,
11767
0
    // regardless of how the input rounding algorithm breaks ties.
11768
0
    //
11769
0
    // And digit_gen generates the shortest possible such number in [M-, M+].
11770
0
    // Note that this does not mean that Grisu2 always generates the shortest
11771
0
    // possible number in the interval (m-, m+).
11772
0
    const diyfp M_minus(w_minus.f + 1, w_minus.e);
11773
0
    const diyfp M_plus (w_plus.f  - 1, w_plus.e );
11774
0
11775
0
    decimal_exponent = -cached.k; // = -(-k) = k
11776
0
11777
0
    grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
11778
0
}
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>
11786
void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
11787
0
{
11788
0
    static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
11789
0
                  "internal error: not enough precision");
11790
0
11791
0
    assert(std::isfinite(value));
11792
0
    assert(value > 0);
11793
0
11794
0
    // If the neighbors (and boundaries) of 'value' are always computed for double-precision
11795
0
    // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
11796
0
    // decimal representations are not exactly "short".
11797
0
    //
11798
0
    // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
11799
0
    // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
11800
0
    // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
11801
0
    // does.
11802
0
    // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
11803
0
    // representation using the corresponding std::from_chars function recovers value exactly". That
11804
0
    // indicates that single precision floating-point numbers should be recovered using
11805
0
    // 'std::strtof'.
11806
0
    //
11807
0
    // NB: If the neighbors are computed for single-precision numbers, there is a single float
11808
0
    //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
11809
0
    //     value is off by 1 ulp.
11810
0
#if 0
11811
0
    const boundaries w = compute_boundaries(static_cast<double>(value));
11812
0
#else
11813
0
    const boundaries w = compute_boundaries(value);
11814
0
#endif
11815
0
11816
0
    grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
11817
0
}
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
*/
11824
inline char* append_exponent(char* buf, int e)
11825
0
{
11826
0
    assert(e > -1000);
11827
0
    assert(e <  1000);
11828
0
11829
0
    if (e < 0)
11830
0
    {
11831
0
        e = -e;
11832
0
        *buf++ = '-';
11833
0
    }
11834
0
    else
11835
0
    {
11836
0
        *buf++ = '+';
11837
0
    }
11838
0
11839
0
    auto k = static_cast<std::uint32_t>(e);
11840
0
    if (k < 10)
11841
0
    {
11842
0
        // Always print at least two digits in the exponent.
11843
0
        // This is for compatibility with printf("%g").
11844
0
        *buf++ = '0';
11845
0
        *buf++ = static_cast<char>('0' + k);
11846
0
    }
11847
0
    else if (k < 100)
11848
0
    {
11849
0
        *buf++ = static_cast<char>('0' + k / 10);
11850
0
        k %= 10;
11851
0
        *buf++ = static_cast<char>('0' + k);
11852
0
    }
11853
0
    else
11854
0
    {
11855
0
        *buf++ = static_cast<char>('0' + k / 100);
11856
0
        k %= 100;
11857
0
        *buf++ = static_cast<char>('0' + k / 10);
11858
0
        k %= 10;
11859
0
        *buf++ = static_cast<char>('0' + k);
11860
0
    }
11861
0
11862
0
    return buf;
11863
0
}
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
*/
11874
inline char* format_buffer(char* buf, int len, int decimal_exponent,
11875
                           int min_exp, int max_exp)
11876
0
{
11877
0
    assert(min_exp < 0);
11878
0
    assert(max_exp > 0);
11879
0
11880
0
    const int k = len;
11881
0
    const int n = len + decimal_exponent;
11882
0
11883
0
    // v = buf * 10^(n-k)
11884
0
    // k is the length of the buffer (number of decimal digits)
11885
0
    // n is the position of the decimal point relative to the start of the buffer.
11886
0
11887
0
    if (k <= n and n <= max_exp)
11888
0
    {
11889
0
        // digits[000]
11890
0
        // len <= max_exp + 2
11891
0
11892
0
        std::memset(buf + k, '0', static_cast<size_t>(n - k));
11893
0
        // Make it look like a floating-point number (#362, #378)
11894
0
        buf[n + 0] = '.';
11895
0
        buf[n + 1] = '0';
11896
0
        return buf + (n + 2);
11897
0
    }
11898
0
11899
0
    if (0 < n and n <= max_exp)
11900
0
    {
11901
0
        // dig.its
11902
0
        // len <= max_digits10 + 1
11903
0
11904
0
        assert(k > n);
11905
0
11906
0
        std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
11907
0
        buf[n] = '.';
11908
0
        return buf + (k + 1);
11909
0
    }
11910
0
11911
0
    if (min_exp < n and n <= 0)
11912
0
    {
11913
0
        // 0.[000]digits
11914
0
        // len <= 2 + (-min_exp - 1) + max_digits10
11915
0
11916
0
        std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
11917
0
        buf[0] = '0';
11918
0
        buf[1] = '.';
11919
0
        std::memset(buf + 2, '0', static_cast<size_t>(-n));
11920
0
        return buf + (2 + (-n) + k);
11921
0
    }
11922
0
11923
0
    if (k == 1)
11924
0
    {
11925
0
        // dE+123
11926
0
        // len <= 1 + 5
11927
0
11928
0
        buf += 1;
11929
0
    }
11930
0
    else
11931
0
    {
11932
0
        // d.igitsE+123
11933
0
        // len <= max_digits10 + 1 + 5
11934
0
11935
0
        std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
11936
0
        buf[1] = '.';
11937
0
        buf += 1 + k;
11938
0
    }
11939
0
11940
0
    *buf++ = 'e';
11941
0
    return append_exponent(buf, n - 1);
11942
0
}
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>
11957
char* to_chars(char* first, const char* last, FloatType value)
11958
0
{
11959
0
    static_cast<void>(last); // maybe unused - fix warning
11960
0
    assert(std::isfinite(value));
11961
0
11962
0
    // Use signbit(value) instead of (value < 0) since signbit works for -0.
11963
0
    if (std::signbit(value))
11964
0
    {
11965
0
        value = -value;
11966
0
        *first++ = '-';
11967
0
    }
11968
0
11969
0
    if (value == 0) // +-0
11970
0
    {
11971
0
        *first++ = '0';
11972
0
        // Make it look like a floating-point number (#362, #378)
11973
0
        *first++ = '.';
11974
0
        *first++ = '0';
11975
0
        return first;
11976
0
    }
11977
0
11978
0
    assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
11979
0
11980
0
    // Compute v = buffer * 10^decimal_exponent.
11981
0
    // The decimal digits are stored in the buffer, which needs to be interpreted
11982
0
    // as an unsigned decimal integer.
11983
0
    // len is the length of the buffer, i.e. the number of decimal digits.
11984
0
    int len = 0;
11985
0
    int decimal_exponent = 0;
11986
0
    dtoa_impl::grisu2(first, len, decimal_exponent, value);
11987
0
11988
0
    assert(len <= std::numeric_limits<FloatType>::max_digits10);
11989
0
11990
0
    // Format the buffer like printf("%.*g", prec, value)
11991
0
    constexpr int kMinExp = -4;
11992
0
    // Use digits10 here to increase compatibility with version 2.
11993
0
    constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
11994
0
11995
0
    assert(last - first >= kMaxExp + 2);
11996
0
    assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
11997
0
    assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
11998
0
11999
0
    return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
12000
0
}
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
    */
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
    */
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
0
    {
12090
0
        switch (val.m_type)
12091
0
        {
12092
0
            case value_t::object:
12093
0
            {
12094
0
                if (val.m_value.object->empty())
12095
0
                {
12096
0
                    o->write_characters("{}", 2);
12097
0
                    return;
12098
0
                }
12099
0
12100
0
                if (pretty_print)
12101
0
                {
12102
0
                    o->write_characters("{\n", 2);
12103
0
12104
0
                    // variable to hold indentation for recursive calls
12105
0
                    const auto new_indent = current_indent + indent_step;
12106
0
                    if (JSON_UNLIKELY(indent_string.size() < new_indent))
12107
0
                    {
12108
0
                        indent_string.resize(indent_string.size() * 2, ' ');
12109
0
                    }
12110
0
12111
0
                    // first n-1 elements
12112
0
                    auto i = val.m_value.object->cbegin();
12113
0
                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12114
0
                    {
12115
0
                        o->write_characters(indent_string.c_str(), new_indent);
12116
0
                        o->write_character('\"');
12117
0
                        dump_escaped(i->first, ensure_ascii);
12118
0
                        o->write_characters("\": ", 3);
12119
0
                        dump(i->second, true, ensure_ascii, indent_step, new_indent);
12120
0
                        o->write_characters(",\n", 2);
12121
0
                    }
12122
0
12123
0
                    // last element
12124
0
                    assert(i != val.m_value.object->cend());
12125
0
                    assert(std::next(i) == val.m_value.object->cend());
12126
0
                    o->write_characters(indent_string.c_str(), new_indent);
12127
0
                    o->write_character('\"');
12128
0
                    dump_escaped(i->first, ensure_ascii);
12129
0
                    o->write_characters("\": ", 3);
12130
0
                    dump(i->second, true, ensure_ascii, indent_step, new_indent);
12131
0
12132
0
                    o->write_character('\n');
12133
0
                    o->write_characters(indent_string.c_str(), current_indent);
12134
0
                    o->write_character('}');
12135
0
                }
12136
0
                else
12137
0
                {
12138
0
                    o->write_character('{');
12139
0
12140
0
                    // first n-1 elements
12141
0
                    auto i = val.m_value.object->cbegin();
12142
0
                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12143
0
                    {
12144
0
                        o->write_character('\"');
12145
0
                        dump_escaped(i->first, ensure_ascii);
12146
0
                        o->write_characters("\":", 2);
12147
0
                        dump(i->second, false, ensure_ascii, indent_step, current_indent);
12148
0
                        o->write_character(',');
12149
0
                    }
12150
0
12151
0
                    // last element
12152
0
                    assert(i != val.m_value.object->cend());
12153
0
                    assert(std::next(i) == val.m_value.object->cend());
12154
0
                    o->write_character('\"');
12155
0
                    dump_escaped(i->first, ensure_ascii);
12156
0
                    o->write_characters("\":", 2);
12157
0
                    dump(i->second, false, ensure_ascii, indent_step, current_indent);
12158
0
12159
0
                    o->write_character('}');
12160
0
                }
12161
0
12162
0
                return;
12163
0
            }
12164
0
12165
0
            case value_t::array:
12166
0
            {
12167
0
                if (val.m_value.array->empty())
12168
0
                {
12169
0
                    o->write_characters("[]", 2);
12170
0
                    return;
12171
0
                }
12172
0
12173
0
                if (pretty_print)
12174
0
                {
12175
0
                    o->write_characters("[\n", 2);
12176
0
12177
0
                    // variable to hold indentation for recursive calls
12178
0
                    const auto new_indent = current_indent + indent_step;
12179
0
                    if (JSON_UNLIKELY(indent_string.size() < new_indent))
12180
0
                    {
12181
0
                        indent_string.resize(indent_string.size() * 2, ' ');
12182
0
                    }
12183
0
12184
0
                    // first n-1 elements
12185
0
                    for (auto i = val.m_value.array->cbegin();
12186
0
                            i != val.m_value.array->cend() - 1; ++i)
12187
0
                    {
12188
0
                        o->write_characters(indent_string.c_str(), new_indent);
12189
0
                        dump(*i, true, ensure_ascii, indent_step, new_indent);
12190
0
                        o->write_characters(",\n", 2);
12191
0
                    }
12192
0
12193
0
                    // last element
12194
0
                    assert(not val.m_value.array->empty());
12195
0
                    o->write_characters(indent_string.c_str(), new_indent);
12196
0
                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
12197
0
12198
0
                    o->write_character('\n');
12199
0
                    o->write_characters(indent_string.c_str(), current_indent);
12200
0
                    o->write_character(']');
12201
0
                }
12202
0
                else
12203
0
                {
12204
0
                    o->write_character('[');
12205
0
12206
0
                    // first n-1 elements
12207
0
                    for (auto i = val.m_value.array->cbegin();
12208
0
                            i != val.m_value.array->cend() - 1; ++i)
12209
0
                    {
12210
0
                        dump(*i, false, ensure_ascii, indent_step, current_indent);
12211
0
                        o->write_character(',');
12212
0
                    }
12213
0
12214
0
                    // last element
12215
0
                    assert(not val.m_value.array->empty());
12216
0
                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
12217
0
12218
0
                    o->write_character(']');
12219
0
                }
12220
0
12221
0
                return;
12222
0
            }
12223
0
12224
0
            case value_t::string:
12225
0
            {
12226
0
                o->write_character('\"');
12227
0
                dump_escaped(*val.m_value.string, ensure_ascii);
12228
0
                o->write_character('\"');
12229
0
                return;
12230
0
            }
12231
0
12232
0
            case value_t::boolean:
12233
0
            {
12234
0
                if (val.m_value.boolean)
12235
0
                {
12236
0
                    o->write_characters("true", 4);
12237
0
                }
12238
0
                else
12239
0
                {
12240
0
                    o->write_characters("false", 5);
12241
0
                }
12242
0
                return;
12243
0
            }
12244
0
12245
0
            case value_t::number_integer:
12246
0
            {
12247
0
                dump_integer(val.m_value.number_integer);
12248
0
                return;
12249
0
            }
12250
0
12251
0
            case value_t::number_unsigned:
12252
0
            {
12253
0
                dump_integer(val.m_value.number_unsigned);
12254
0
                return;
12255
0
            }
12256
0
12257
0
            case value_t::number_float:
12258
0
            {
12259
0
                dump_float(val.m_value.number_float);
12260
0
                return;
12261
0
            }
12262
0
12263
0
            case value_t::discarded:
12264
0
            {
12265
0
                o->write_characters("<discarded>", 11);
12266
0
                return;
12267
0
            }
12268
0
12269
0
            case value_t::null:
12270
0
            {
12271
0
                o->write_characters("null", 4);
12272
0
                return;
12273
0
            }
12274
0
12275
0
            default:            // LCOV_EXCL_LINE
12276
0
                assert(false);  // LCOV_EXCL_LINE
12277
0
        }
12278
0
    }
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
    */
12295
    void dump_escaped(const string_t& s, const bool ensure_ascii)
12296
0
    {
12297
0
        std::uint32_t codepoint;
12298
0
        std::uint8_t state = UTF8_ACCEPT;
12299
0
        std::size_t bytes = 0;  // number of bytes written to string_buffer
12300
0
12301
0
        // number of bytes written at the point of the last valid byte
12302
0
        std::size_t bytes_after_last_accept = 0;
12303
0
        std::size_t undumped_chars = 0;
12304
0
12305
0
        for (std::size_t i = 0; i < s.size(); ++i)
12306
0
        {
12307
0
            const auto byte = static_cast<uint8_t>(s[i]);
12308
0
12309
0
            switch (decode(state, codepoint, byte))
12310
0
            {
12311
0
                case UTF8_ACCEPT:  // decode found a new code point
12312
0
                {
12313
0
                    switch (codepoint)
12314
0
                    {
12315
0
                        case 0x08: // backspace
12316
0
                        {
12317
0
                            string_buffer[bytes++] = '\\';
12318
0
                            string_buffer[bytes++] = 'b';
12319
0
                            break;
12320
0
                        }
12321
0
12322
0
                        case 0x09: // horizontal tab
12323
0
                        {
12324
0
                            string_buffer[bytes++] = '\\';
12325
0
                            string_buffer[bytes++] = 't';
12326
0
                            break;
12327
0
                        }
12328
0
12329
0
                        case 0x0A: // newline
12330
0
                        {
12331
0
                            string_buffer[bytes++] = '\\';
12332
0
                            string_buffer[bytes++] = 'n';
12333
0
                            break;
12334
0
                        }
12335
0
12336
0
                        case 0x0C: // formfeed
12337
0
                        {
12338
0
                            string_buffer[bytes++] = '\\';
12339
0
                            string_buffer[bytes++] = 'f';
12340
0
                            break;
12341
0
                        }
12342
0
12343
0
                        case 0x0D: // carriage return
12344
0
                        {
12345
0
                            string_buffer[bytes++] = '\\';
12346
0
                            string_buffer[bytes++] = 'r';
12347
0
                            break;
12348
0
                        }
12349
0
12350
0
                        case 0x22: // quotation mark
12351
0
                        {
12352
0
                            string_buffer[bytes++] = '\\';
12353
0
                            string_buffer[bytes++] = '\"';
12354
0
                            break;
12355
0
                        }
12356
0
12357
0
                        case 0x5C: // reverse solidus
12358
0
                        {
12359
0
                            string_buffer[bytes++] = '\\';
12360
0
                            string_buffer[bytes++] = '\\';
12361
0
                            break;
12362
0
                        }
12363
0
12364
0
                        default:
12365
0
                        {
12366
0
                            // escape control characters (0x00..0x1F) or, if
12367
0
                            // ensure_ascii parameter is used, non-ASCII characters
12368
0
                            if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
12369
0
                            {
12370
0
                                if (codepoint <= 0xFFFF)
12371
0
                                {
12372
0
                                    (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
12373
0
                                                    static_cast<std::uint16_t>(codepoint));
12374
0
                                    bytes += 6;
12375
0
                                }
12376
0
                                else
12377
0
                                {
12378
0
                                    (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
12379
0
                                                    static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
12380
0
                                                    static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
12381
0
                                    bytes += 12;
12382
0
                                }
12383
0
                            }
12384
0
                            else
12385
0
                            {
12386
0
                                // copy byte to buffer (all previous bytes
12387
0
                                // been copied have in default case above)
12388
0
                                string_buffer[bytes++] = s[i];
12389
0
                            }
12390
0
                            break;
12391
0
                        }
12392
0
                    }
12393
0
12394
0
                    // write buffer and reset index; there must be 13 bytes
12395
0
                    // left, as this is the maximal number of bytes to be
12396
0
                    // written ("\uxxxx\uxxxx\0") for one code point
12397
0
                    if (string_buffer.size() - bytes < 13)
12398
0
                    {
12399
0
                        o->write_characters(string_buffer.data(), bytes);
12400
0
                        bytes = 0;
12401
0
                    }
12402
0
12403
0
                    // remember the byte position of this accept
12404
0
                    bytes_after_last_accept = bytes;
12405
0
                    undumped_chars = 0;
12406
0
                    break;
12407
0
                }
12408
0
12409
0
                case UTF8_REJECT:  // decode found invalid UTF-8 byte
12410
0
                {
12411
0
                    switch (error_handler)
12412
0
                    {
12413
0
                        case error_handler_t::strict:
12414
0
                        {
12415
0
                            std::string sn(3, '\0');
12416
0
                            (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
12417
0
                            JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
12418
0
                        }
12419
0
12420
0
                        case error_handler_t::ignore:
12421
0
                        case error_handler_t::replace:
12422
0
                        {
12423
0
                            // in case we saw this character the first time, we
12424
0
                            // would like to read it again, because the byte
12425
0
                            // may be OK for itself, but just not OK for the
12426
0
                            // previous sequence
12427
0
                            if (undumped_chars > 0)
12428
0
                            {
12429
0
                                --i;
12430
0
                            }
12431
0
12432
0
                            // reset length buffer to the last accepted index;
12433
0
                            // thus removing/ignoring the invalid characters
12434
0
                            bytes = bytes_after_last_accept;
12435
0
12436
0
                            if (error_handler == error_handler_t::replace)
12437
0
                            {
12438
0
                                // add a replacement character
12439
0
                                if (ensure_ascii)
12440
0
                                {
12441
0
                                    string_buffer[bytes++] = '\\';
12442
0
                                    string_buffer[bytes++] = 'u';
12443
0
                                    string_buffer[bytes++] = 'f';
12444
0
                                    string_buffer[bytes++] = 'f';
12445
0
                                    string_buffer[bytes++] = 'f';
12446
0
                                    string_buffer[bytes++] = 'd';
12447
0
                                }
12448
0
                                else
12449
0
                                {
12450
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
12451
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
12452
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
12453
0
                                }
12454
0
12455
0
                                // write buffer and reset index; there must be 13 bytes
12456
0
                                // left, as this is the maximal number of bytes to be
12457
0
                                // written ("\uxxxx\uxxxx\0") for one code point
12458
0
                                if (string_buffer.size() - bytes < 13)
12459
0
                                {
12460
0
                                    o->write_characters(string_buffer.data(), bytes);
12461
0
                                    bytes = 0;
12462
0
                                }
12463
0
12464
0
                                bytes_after_last_accept = bytes;
12465
0
                            }
12466
0
12467
0
                            undumped_chars = 0;
12468
0
12469
0
                            // continue processing the string
12470
0
                            state = UTF8_ACCEPT;
12471
0
                            break;
12472
0
                        }
12473
0
12474
0
                        default:            // LCOV_EXCL_LINE
12475
0
                            assert(false);  // LCOV_EXCL_LINE
12476
0
                    }
12477
0
                    break;
12478
0
                }
12479
0
12480
0
                default:  // decode found yet incomplete multi-byte code point
12481
0
                {
12482
0
                    if (not ensure_ascii)
12483
0
                    {
12484
0
                        // code point will not be escaped - copy byte to buffer
12485
0
                        string_buffer[bytes++] = s[i];
12486
0
                    }
12487
0
                    ++undumped_chars;
12488
0
                    break;
12489
0
                }
12490
0
            }
12491
0
        }
12492
0
12493
0
        // we finished processing the string
12494
0
        if (JSON_LIKELY(state == UTF8_ACCEPT))
12495
0
        {
12496
0
            // write buffer
12497
0
            if (bytes > 0)
12498
0
            {
12499
0
                o->write_characters(string_buffer.data(), bytes);
12500
0
            }
12501
0
        }
12502
0
        else
12503
0
        {
12504
0
            // we finish reading, but do not accept: string was incomplete
12505
0
            switch (error_handler)
12506
0
            {
12507
0
                case error_handler_t::strict:
12508
0
                {
12509
0
                    std::string sn(3, '\0');
12510
0
                    (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
12511
0
                    JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
12512
0
                }
12513
0
12514
0
                case error_handler_t::ignore:
12515
0
                {
12516
0
                    // write all accepted bytes
12517
0
                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
12518
0
                    break;
12519
0
                }
12520
0
12521
0
                case error_handler_t::replace:
12522
0
                {
12523
0
                    // write all accepted bytes
12524
0
                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
12525
0
                    // add a replacement character
12526
0
                    if (ensure_ascii)
12527
0
                    {
12528
0
                        o->write_characters("\\ufffd", 6);
12529
0
                    }
12530
0
                    else
12531
0
                    {
12532
0
                        o->write_characters("\xEF\xBF\xBD", 3);
12533
0
                    }
12534
0
                    break;
12535
0
                }
12536
0
12537
0
                default:            // LCOV_EXCL_LINE
12538
0
                    assert(false);  // LCOV_EXCL_LINE
12539
0
            }
12540
0
        }
12541
0
    }
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
    */
12551
    inline unsigned int count_digits(number_unsigned_t x) noexcept
12552
0
    {
12553
0
        unsigned int n_digits = 1;
12554
0
        for (;;)
12555
0
        {
12556
0
            if (x < 10)
12557
0
            {
12558
0
                return n_digits;
12559
0
            }
12560
0
            if (x < 100)
12561
0
            {
12562
0
                return n_digits + 1;
12563
0
            }
12564
0
            if (x < 1000)
12565
0
            {
12566
0
                return n_digits + 2;
12567
0
            }
12568
0
            if (x < 10000)
12569
0
            {
12570
0
                return n_digits + 3;
12571
0
            }
12572
0
            x = x / 10000u;
12573
0
            n_digits += 4;
12574
0
        }
12575
0
    }
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>
12590
    void dump_integer(NumberType x)
12591
0
    {
12592
0
        static constexpr std::array<std::array<char, 2>, 100> digits_to_99
12593
0
        {
12594
0
            {
12595
0
                {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
12596
0
                {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
12597
0
                {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
12598
0
                {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
12599
0
                {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
12600
0
                {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
12601
0
                {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
12602
0
                {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
12603
0
                {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
12604
0
                {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
12605
0
            }
12606
0
        };
12607
0
12608
0
        // special case for "0"
12609
0
        if (x == 0)
12610
0
        {
12611
0
            o->write_character('0');
12612
0
            return;
12613
0
        }
12614
0
12615
0
        // use a pointer to fill the buffer
12616
0
        auto buffer_ptr = number_buffer.begin();
12617
0
12618
0
        const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
12619
0
        number_unsigned_t abs_value;
12620
0
12621
0
        unsigned int n_chars;
12622
0
12623
0
        if (is_negative)
12624
0
        {
12625
0
            *buffer_ptr = '-';
12626
0
            abs_value = static_cast<number_unsigned_t>(std::abs(static_cast<std::intmax_t>(x)));
12627
0
12628
0
            // account one more byte for the minus sign
12629
0
            n_chars = 1 + count_digits(abs_value);
12630
0
        }
12631
0
        else
12632
0
        {
12633
0
            abs_value = static_cast<number_unsigned_t>(x);
12634
0
            n_chars = count_digits(abs_value);
12635
0
        }
12636
0
12637
0
        // spare 1 byte for '\0'
12638
0
        assert(n_chars < number_buffer.size() - 1);
12639
0
12640
0
        // jump to the end to generate the string from backward
12641
0
        // so we later avoid reversing the result
12642
0
        buffer_ptr += n_chars;
12643
0
12644
0
        // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
12645
0
        // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
12646
0
        while (abs_value >= 100)
12647
0
        {
12648
0
            const auto digits_index = static_cast<unsigned>((abs_value % 100));
12649
0
            abs_value /= 100;
12650
0
            *(--buffer_ptr) = digits_to_99[digits_index][1];
12651
0
            *(--buffer_ptr) = digits_to_99[digits_index][0];
12652
0
        }
12653
0
12654
0
        if (abs_value >= 10)
12655
0
        {
12656
0
            const auto digits_index = static_cast<unsigned>(abs_value);
12657
0
            *(--buffer_ptr) = digits_to_99[digits_index][1];
12658
0
            *(--buffer_ptr) = digits_to_99[digits_index][0];
12659
0
        }
12660
0
        else
12661
0
        {
12662
0
            *(--buffer_ptr) = static_cast<char>('0' + abs_value);
12663
0
        }
12664
0
12665
0
        o->write_characters(number_buffer.data(), n_chars);
12666
0
    }
Unexecuted instantiation: void nlohmann::detail::serializer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::dump_integer<long, 0>(long)
Unexecuted instantiation: void nlohmann::detail::serializer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> >::dump_integer<unsigned long, 0>(unsigned long)
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
    */
12676
    void dump_float(number_float_t x)
12677
0
    {
12678
0
        // NaN / inf
12679
0
        if (not std::isfinite(x))
12680
0
        {
12681
0
            o->write_characters("null", 4);
12682
0
            return;
12683
0
        }
12684
0
12685
0
        // If number_float_t is an IEEE-754 single or double precision number,
12686
0
        // use the Grisu2 algorithm to produce short numbers which are
12687
0
        // guaranteed to round-trip, using strtof and strtod, resp.
12688
0
        //
12689
0
        // NB: The test below works if <long double> == <double>.
12690
0
        static constexpr bool is_ieee_single_or_double
12691
0
            = (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
0
              (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
0
12694
0
        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
12695
0
    }
12696
12697
    void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
12698
0
    {
12699
0
        char* begin = number_buffer.data();
12700
0
        char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
12701
0
12702
0
        o->write_characters(begin, static_cast<size_t>(end - begin));
12703
0
    }
12704
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
    */
12775
    static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
12776
0
    {
12777
0
        static const std::array<std::uint8_t, 400> utf8d =
12778
0
        {
12779
0
            {
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, 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, 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, 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, 0, // 60..7F
12784
0
                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
0
                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
0
                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
0
                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
12788
0
                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
12789
0
                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
12790
0
                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
0
                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
0
                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
0
                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
0
            }
12795
0
        };
12796
0
12797
0
        const std::uint8_t type = utf8d[byte];
12798
0
12799
0
        codep = (state != UTF8_ACCEPT)
12800
0
                ? (byte & 0x3fu) | (codep << 6u)
12801
0
                : (0xFFu >> type) & (byte);
12802
0
12803
0
        state = utf8d[256u + state * 16u + type];
12804
0
        return state;
12805
0
    }
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
    */
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
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>
13592
    static T* create(Args&& ... args)
13593
0
    {
13594
0
        AllocatorType<T> alloc;
13595
0
        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13596
13597
0
        auto deleter = [&](T * object)
13598
0
        {
13599
0
            AllocatorTraits::deallocate(alloc, object, 1);
13600
0
        };
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >>()::{lambda(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >*)#1}::operator()(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >*) const
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >>()::{lambda(std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >*)#1}::operator()(std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >*) const
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const (&) [1]>(char const (&) [1])::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)#1}::operator()(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) const
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > > const&>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > > const&)::{lambda(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >*)#1}::operator()(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >*) const
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >, std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > const&>(std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > const&)::{lambda(std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >*)#1}::operator()(std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >*) const
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)#1}::operator()(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) const
13601
0
        std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
13602
0
        AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
13603
0
        assert(object != nullptr);
13604
0
        return object.release();
13605
0
    }
Unexecuted instantiation: std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >* nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >>()
Unexecuted instantiation: std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >* nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >>()
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const (&) [1]>(char const (&) [1])
Unexecuted instantiation: std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >* nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > >, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > > const&>(std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::less<void>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > > const&)
Unexecuted instantiation: std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >* nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > >, std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > const&>(std::__1::vector<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>, std::__1::allocator<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer> > > const&)
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
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
13655
0
        json_value(boolean_t v) noexcept : boolean(v) {}
13656
        /// constructor for numbers (integer)
13657
0
        json_value(number_integer_t v) noexcept : number_integer(v) {}
13658
        /// constructor for numbers (unsigned)
13659
0
        json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
13660
        /// constructor for numbers (floating-point)
13661
0
        json_value(number_float_t v) noexcept : number_float(v) {}
13662
        /// constructor for empty values of a given type
13663
        json_value(value_t t)
13664
0
        {
13665
0
            switch (t)
13666
0
            {
13667
0
                case value_t::object:
13668
0
                {
13669
0
                    object = create<object_t>();
13670
0
                    break;
13671
0
                }
13672
13673
0
                case value_t::array:
13674
0
                {
13675
0
                    array = create<array_t>();
13676
0
                    break;
13677
0
                }
13678
13679
0
                case value_t::string:
13680
0
                {
13681
0
                    string = create<string_t>("");
13682
0
                    break;
13683
0
                }
13684
13685
0
                case value_t::boolean:
13686
0
                {
13687
0
                    boolean = boolean_t(false);
13688
0
                    break;
13689
0
                }
13690
13691
0
                case value_t::number_integer:
13692
0
                {
13693
0
                    number_integer = number_integer_t(0);
13694
0
                    break;
13695
0
                }
13696
13697
0
                case value_t::number_unsigned:
13698
0
                {
13699
0
                    number_unsigned = number_unsigned_t(0);
13700
0
                    break;
13701
0
                }
13702
13703
0
                case value_t::number_float:
13704
0
                {
13705
0
                    number_float = number_float_t(0.0);
13706
0
                    break;
13707
0
                }
13708
13709
0
                case value_t::null:
13710
0
                {
13711
0
                    object = nullptr;  // silence warning, see #821
13712
0
                    break;
13713
0
                }
13714
13715
0
                default:
13716
0
                {
13717
0
                    object = nullptr;  // silence warning, see #821
13718
0
                    if (JSON_UNLIKELY(t == value_t::null))
13719
0
                    {
13720
0
                        JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.6.1")); // LCOV_EXCL_LINE
13721
0
                    }
13722
0
                    break;
13723
0
                }
13724
0
            }
13725
0
        }
13726
13727
        /// constructor for strings
13728
        json_value(const string_t& value)
13729
0
        {
13730
0
            string = create<string_t>(value);
13731
0
        }
13732
13733
        /// constructor for rvalue strings
13734
        json_value(string_t&& value)
13735
        {
13736
            string = create<string_t>(std::move(value));
13737
        }
13738
13739
        /// constructor for objects
13740
        json_value(const object_t& value)
13741
0
        {
13742
0
            object = create<object_t>(value);
13743
0
        }
13744
13745
        /// constructor for rvalue objects
13746
        json_value(object_t&& value)
13747
        {
13748
            object = create<object_t>(std::move(value));
13749
        }
13750
13751
        /// constructor for arrays
13752
        json_value(const array_t& value)
13753
0
        {
13754
0
            array = create<array_t>(value);
13755
0
        }
13756
13757
        /// constructor for rvalue arrays
13758
        json_value(array_t&& value)
13759
        {
13760
            array = create<array_t>(std::move(value));
13761
        }
13762
13763
        void destroy(value_t t) noexcept
13764
0
        {
13765
0
            switch (t)
13766
0
            {
13767
0
                case value_t::object:
13768
0
                {
13769
0
                    AllocatorType<object_t> alloc;
13770
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
13771
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
13772
0
                    break;
13773
0
                }
13774
13775
0
                case value_t::array:
13776
0
                {
13777
0
                    AllocatorType<array_t> alloc;
13778
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
13779
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
13780
0
                    break;
13781
0
                }
13782
13783
0
                case value_t::string:
13784
0
                {
13785
0
                    AllocatorType<string_t> alloc;
13786
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
13787
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
13788
0
                    break;
13789
0
                }
13790
13791
0
                default:
13792
0
                {
13793
0
                    break;
13794
0
                }
13795
0
            }
13796
0
        }
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
    */
13808
    void assert_invariant() const noexcept
13809
0
    {
13810
0
        assert(m_type != value_t::object or m_value.object != nullptr);
13811
0
        assert(m_type != value_t::array or m_value.array != nullptr);
13812
0
        assert(m_type != value_t::string or m_value.string != nullptr);
13813
0
    }
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
    */
13926
    basic_json(const value_t v)
13927
        : m_type(v), m_value(v)
13928
0
    {
13929
0
        assert_invariant();
13930
0
    }
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
    */
13950
    basic_json(std::nullptr_t = nullptr) noexcept
13951
        : basic_json(value_t::null)
13952
0
    {
13953
0
        assert_invariant();
13954
0
    }
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>
14017
    basic_json(CompatibleType && val) noexcept(noexcept(
14018
                JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
14019
                                           std::forward<CompatibleType>(val))))
14020
0
    {
14021
0
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
14022
0
        assert_invariant();
14023
0
    }
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::basic_json<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, 0>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::basic_json<double&, double, 0>(double&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::basic_json<bool&, bool, 0>(bool&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::basic_json<long&, long, 0>(long&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::basic_json<unsigned long&, unsigned long, 0>(unsigned long&)
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>
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
    */
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
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
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
    */
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>
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
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
    */
14523
    basic_json(const basic_json& other)
14524
        : m_type(other.m_type)
14525
0
    {
14526
        // check of passed value is valid
14527
0
        other.assert_invariant();
14528
14529
0
        switch (m_type)
14530
0
        {
14531
0
            case value_t::object:
14532
0
            {
14533
0
                m_value = *other.m_value.object;
14534
0
                break;
14535
0
            }
14536
14537
0
            case value_t::array:
14538
0
            {
14539
0
                m_value = *other.m_value.array;
14540
0
                break;
14541
0
            }
14542
14543
0
            case value_t::string:
14544
0
            {
14545
0
                m_value = *other.m_value.string;
14546
0
                break;
14547
0
            }
14548
14549
0
            case value_t::boolean:
14550
0
            {
14551
0
                m_value = other.m_value.boolean;
14552
0
                break;
14553
0
            }
14554
14555
0
            case value_t::number_integer:
14556
0
            {
14557
0
                m_value = other.m_value.number_integer;
14558
0
                break;
14559
0
            }
14560
14561
0
            case value_t::number_unsigned:
14562
0
            {
14563
0
                m_value = other.m_value.number_unsigned;
14564
0
                break;
14565
0
            }
14566
14567
0
            case value_t::number_float:
14568
0
            {
14569
0
                m_value = other.m_value.number_float;
14570
0
                break;
14571
0
            }
14572
14573
0
            default:
14574
0
                break;
14575
0
        }
14576
14577
0
        assert_invariant();
14578
0
    }
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
    */
14606
    basic_json(basic_json&& other) noexcept
14607
        : m_type(std::move(other.m_type)),
14608
          m_value(std::move(other.m_value))
14609
0
    {
14610
        // check that passed value is valid
14611
0
        other.assert_invariant();
14612
14613
        // invalidate payload
14614
0
        other.m_type = value_t::null;
14615
0
        other.m_value = {};
14616
14617
0
        assert_invariant();
14618
0
    }
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
    */
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
0
    {
14650
        // check that passed value is valid
14651
0
        other.assert_invariant();
14652
14653
0
        using std::swap;
14654
0
        swap(m_type, other.m_type);
14655
0
        swap(m_value, other.m_value);
14656
14657
0
        assert_invariant();
14658
0
        return *this;
14659
0
    }
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
    */
14676
    ~basic_json() noexcept
14677
0
    {
14678
0
        assert_invariant();
14679
0
        m_value.destroy(m_type);
14680
0
    }
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
    */
14734
    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
0
    {
14739
0
        string_t result;
14740
0
        serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
14741
0
14742
0
        if (indent >= 0)
14743
0
        {
14744
0
            s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
14745
0
        }
14746
0
        else
14747
0
        {
14748
0
            s.dump(*this, false, ensure_ascii, 0);
14749
0
        }
14750
0
14751
0
        return result;
14752
0
    }
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
    */
14786
    constexpr value_t type() const noexcept
14787
0
    {
14788
0
        return m_type;
14789
0
    }
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
    */
14816
    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
    */
14843
    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
    */
14865
    constexpr bool is_null() const noexcept
14866
0
    {
14867
0
        return m_type == value_t::null;
14868
0
    }
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
    */
14887
    constexpr bool is_boolean() const noexcept
14888
0
    {
14889
0
        return m_type == value_t::boolean;
14890
0
    }
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
    */
14917
    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
    */
14946
    constexpr bool is_number_integer() const noexcept
14947
0
    {
14948
0
        return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
14949
0
    }
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
    */
14974
    constexpr bool is_number_unsigned() const noexcept
14975
0
    {
14976
0
        return m_type == value_t::number_unsigned;
14977
0
    }
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
    */
15002
    constexpr bool is_number_float() const noexcept
15003
0
    {
15004
0
        return m_type == value_t::number_float;
15005
0
    }
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
    */
15024
    constexpr bool is_object() const noexcept
15025
0
    {
15026
0
        return m_type == value_t::object;
15027
0
    }
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
    */
15046
    constexpr bool is_array() const noexcept
15047
0
    {
15048
0
        return m_type == value_t::array;
15049
0
    }
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
    */
15068
    constexpr bool is_string() const noexcept
15069
0
    {
15070
0
        return m_type == value_t::string;
15071
0
    }
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
    */
15095
    constexpr bool is_discarded() const noexcept
15096
0
    {
15097
0
        return m_type == value_t::discarded;
15098
0
    }
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
    */
15121
    constexpr operator value_t() const noexcept
15122
0
    {
15123
0
        return m_type;
15124
0
    }
15125
15126
    /// @}
15127
15128
  private:
15129
    //////////////////
15130
    // value access //
15131
    //////////////////
15132
15133
    /// get a boolean (explicit)
15134
    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)
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)
15151
    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)
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)
15163
    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)
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)
15175
    constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
15176
0
    {
15177
0
        return is_string() ? m_value.string : nullptr;
15178
0
    }
15179
15180
    /// get a pointer to the value (boolean)
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)
15187
    constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
15188
0
    {
15189
0
        return is_boolean() ? &m_value.boolean : nullptr;
15190
0
    }
15191
15192
    /// get a pointer to the value (integer number)
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)
15199
    constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
15200
0
    {
15201
0
        return is_number_integer() ? &m_value.number_integer : nullptr;
15202
0
    }
15203
15204
    /// get a pointer to the value (unsigned number)
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)
15211
    constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
15212
0
    {
15213
0
        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
15214
0
    }
15215
15216
    /// get a pointer to the value (floating-point number)
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)
15223
    constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
15224
0
    {
15225
0
        return is_number_float() ? &m_value.number_float : nullptr;
15226
0
    }
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>
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>
15275
    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
0
    {
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
0
        static_assert(not std::is_reference<ValueTypeCV>::value,
15355
0
                      "get() cannot be used with reference types, you might want to use get_ref()");
15356
0
        static_assert(std::is_default_constructible<ValueType>::value,
15357
0
                      "types must be DefaultConstructible when used with get()");
15358
15359
0
        ValueType ret;
15360
0
        JSONSerializer<ValueType>::from_json(*this, ret);
15361
0
        return ret;
15362
0
    }
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::get<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, 0>() const
Unexecuted instantiation: bool nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::get<bool, bool, 0>() const
Unexecuted instantiation: double nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer>::get<double, double, 0>() const
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>
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>
15494
    constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15495
0
    {
15496
        // delegate the call to get_impl_ptr<>() const
15497
0
        return get_impl_ptr(static_cast<PointerType>(nullptr));
15498
0
    }
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerEE7get_ptrIPKS9_Li0EEEDTcldtclL_ZNS1_7declvalIRKSB_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISI_EEEEv
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerEE7get_ptrIPKbLi0EEEDTcldtclL_ZNS1_7declvalIRKSB_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISI_EEEEv
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerEE7get_ptrIPKmLi0EEEDTcldtclL_ZNS1_7declvalIRKSB_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISI_EEEEv
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerEE7get_ptrIPKlLi0EEEDTcldtclL_ZNS1_7declvalIRKSB_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISI_EEEEv
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerEE7get_ptrIPKdLi0EEEDTcldtclL_ZNS1_7declvalIRKSB_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISI_EEEEv
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>
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>
15541
    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 >
15637
    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
    */
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
    */
15727
    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
    */
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
    */
15829
    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
    */
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
    */
15921
    const_reference operator[](size_type idx) const
15922
0
    {
15923
        // const operator[] only works for arrays
15924
0
        if (JSON_LIKELY(is_array()))
15925
0
        {
15926
0
            return m_value.array->operator[](idx);
15927
0
        }
15928
15929
0
        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15930
0
    }
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
    */
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
    */
16008
    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>
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>
16098
    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
    */
16182
    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
    */
16253
    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
    */
16283
    reference front()
16284
    {
16285
        return *begin();
16286
    }
16287
16288
    /*!
16289
    @copydoc basic_json::front()
16290
    */
16291
    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
    */
16327
    reference back()
16328
    {
16329
        auto tmp = end();
16330
        --tmp;
16331
        return *tmp;
16332
    }
16333
16334
    /*!
16335
    @copydoc basic_json::back()
16336
    */
16337
    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
0
    {
16396
        // make sure iterator fits the current value
16397
0
        if (JSON_UNLIKELY(this != pos.m_object))
16398
0
        {
16399
0
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16400
0
        }
16401
16402
0
        IteratorType result = end();
16403
16404
0
        switch (m_type)
16405
0
        {
16406
0
            case value_t::boolean:
16407
0
            case value_t::number_float:
16408
0
            case value_t::number_integer:
16409
0
            case value_t::number_unsigned:
16410
0
            case value_t::string:
16411
0
            {
16412
0
                if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
16413
0
                {
16414
0
                    JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
16415
0
                }
16416
16417
0
                if (is_string())
16418
0
                {
16419
0
                    AllocatorType<string_t> alloc;
16420
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16421
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16422
0
                    m_value.string = nullptr;
16423
0
                }
16424
16425
0
                m_type = value_t::null;
16426
0
                assert_invariant();
16427
0
                break;
16428
0
            }
16429
16430
0
            case value_t::object:
16431
0
            {
16432
0
                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
16433
0
                break;
16434
0
            }
16435
16436
0
            case value_t::array:
16437
0
            {
16438
0
                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
16439
0
                break;
16440
0
            }
16441
16442
0
            default:
16443
0
                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16444
0
        }
16445
16446
0
        return result;
16447
0
    }
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
    */
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
    */
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>
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>
16691
    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>
16725
    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>
16756
    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
    */
16795
    iterator begin() noexcept
16796
0
    {
16797
0
        iterator result(this);
16798
0
        result.set_begin();
16799
0
        return result;
16800
0
    }
16801
16802
    /*!
16803
    @copydoc basic_json::cbegin()
16804
    */
16805
    const_iterator begin() const noexcept
16806
0
    {
16807
0
        return cbegin();
16808
0
    }
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
    */
16835
    const_iterator cbegin() const noexcept
16836
0
    {
16837
0
        const_iterator result(this);
16838
0
        result.set_begin();
16839
0
        return result;
16840
0
    }
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
    */
16866
    iterator end() noexcept
16867
0
    {
16868
0
        iterator result(this);
16869
0
        result.set_end();
16870
0
        return result;
16871
0
    }
16872
16873
    /*!
16874
    @copydoc basic_json::cend()
16875
    */
16876
    const_iterator end() const noexcept
16877
0
    {
16878
0
        return cend();
16879
0
    }
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
    */
16906
    const_iterator cend() const noexcept
16907
0
    {
16908
0
        const_iterator result(this);
16909
0
        result.set_end();
16910
0
        return result;
16911
0
    }
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
    */
16936
    reverse_iterator rbegin() noexcept
16937
    {
16938
        return reverse_iterator(end());
16939
    }
16940
16941
    /*!
16942
    @copydoc basic_json::crbegin()
16943
    */
16944
    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
    */
16973
    reverse_iterator rend() noexcept
16974
    {
16975
        return reverse_iterator(begin());
16976
    }
16977
16978
    /*!
16979
    @copydoc basic_json::crend()
16980
    */
16981
    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
    */
17010
    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
    */
17039
    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
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
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
    */
17180
    iteration_proxy<iterator> items() noexcept
17181
    {
17182
        return iteration_proxy<iterator>(*this);
17183
    }
17184
17185
    /*!
17186
    @copydoc items()
17187
    */
17188
    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
    */
17244
    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
    */
17316
    size_type size() const noexcept
17317
0
    {
17318
0
        switch (m_type)
17319
0
        {
17320
0
            case value_t::null:
17321
0
            {
17322
                // null values are empty
17323
0
                return 0;
17324
0
            }
17325
17326
0
            case value_t::array:
17327
0
            {
17328
                // delegate call to array_t::size()
17329
0
                return m_value.array->size();
17330
0
            }
17331
17332
0
            case value_t::object:
17333
0
            {
17334
                // delegate call to object_t::size()
17335
0
                return m_value.object->size();
17336
0
            }
17337
17338
0
            default:
17339
0
            {
17340
                // all other types have size 1
17341
0
                return 1;
17342
0
            }
17343
0
        }
17344
0
    }
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
    */
17386
    size_type max_size() const noexcept
17387
0
    {
17388
0
        switch (m_type)
17389
0
        {
17390
0
            case value_t::array:
17391
0
            {
17392
                // delegate call to array_t::max_size()
17393
0
                return m_value.array->max_size();
17394
0
            }
17395
17396
0
            case value_t::object:
17397
0
            {
17398
                // delegate call to object_t::max_size()
17399
0
                return m_value.object->max_size();
17400
0
            }
17401
17402
0
            default:
17403
0
            {
17404
                // all other types have max_size() == size()
17405
0
                return size();
17406
0
            }
17407
0
        }
17408
0
    }
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
    */
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
    */
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
    */
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
    */
17564
    void push_back(const basic_json& val)
17565
0
    {
17566
        // push_back only works for null objects or arrays
17567
0
        if (JSON_UNLIKELY(not(is_null() or is_array())))
17568
0
        {
17569
0
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17570
0
        }
17571
17572
        // transform null object into an array
17573
0
        if (is_null())
17574
0
        {
17575
0
            m_type = value_t::array;
17576
0
            m_value = value_t::array;
17577
0
            assert_invariant();
17578
0
        }
17579
17580
        // add element to array
17581
0
        m_value.array->push_back(val);
17582
0
    }
17583
17584
    /*!
17585
    @brief add an object to an array
17586
    @copydoc push_back(basic_json&&)
17587
    */
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
    */
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
    */
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
    */
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
    */
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>
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>
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>
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
    */
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
0
    {
18175
0
        std::swap(m_type, other.m_type);
18176
0
        std::swap(m_value, other.m_value);
18177
0
        assert_invariant();
18178
0
    }
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
    */
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
    */
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
    */
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
    */
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>
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>
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
    */
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>
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>
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
    */
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>
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>
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
    */
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>
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>
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
    */
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>
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>
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
    */
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>
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>
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
    */
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
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
18859
    static basic_json parse(detail::input_adapter&& i,
18860
                            const parser_callback_t cb = nullptr,
18861
                            const bool allow_exceptions = true)
18862
0
    {
18863
0
        basic_json result;
18864
0
        parser(i, cb, allow_exceptions).parse(true, result);
18865
0
        return result;
18866
0
    }
18867
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>
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>
18990
    static basic_json parse(IteratorType first, IteratorType last,
18991
                            const parser_callback_t cb = nullptr,
18992
                            const bool allow_exceptions = true)
18993
0
    {
18994
0
        basic_json result;
18995
0
        parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
18996
0
        return result;
18997
0
    }
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>
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>
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
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
    */
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
    */
19098
    const char* type_name() const noexcept
19099
0
    {
19100
0
        {
19101
0
            switch (m_type)
19102
0
            {
19103
0
                case value_t::null:
19104
0
                    return "null";
19105
0
                case value_t::object:
19106
0
                    return "object";
19107
0
                case value_t::array:
19108
0
                    return "array";
19109
0
                case value_t::string:
19110
0
                    return "string";
19111
0
                case value_t::boolean:
19112
0
                    return "boolean";
19113
0
                case value_t::discarded:
19114
0
                    return "discarded";
19115
0
                default:
19116
0
                    return "number";
19117
0
            }
19118
0
        }
19119
0
    }
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
    */
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
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
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
    */
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
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
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
    */
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
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
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
    */
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
    */
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
    */
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
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
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
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
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
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
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
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
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
    */
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
    */
20010
    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
    */
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
    */
20096
    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
    */
20123
    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
    */
20160
    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
    */
20221
    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
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
    */
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
    */
20739
    std::size_t operator()(const nlohmann::json& j) const
20740
0
    {
20741
0
        // a naive hashing via the string representation
20742
0
        const auto& h = hash<nlohmann::json::string_t>();
20743
0
        return h(j.dump());
20744
0
    }
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
    */
20757
    bool operator()(nlohmann::detail::value_t lhs,
20758
                    nlohmann::detail::value_t rhs) const noexcept
20759
0
    {
20760
0
        return nlohmann::detail::operator<(lhs, rhs);
20761
0
    }
20762
};
20763
20764
/*!
20765
@brief exchanges the values of two JSON objects
20766
20767
@since version 1.0.0
20768
*/
20769
template<>
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
0
{
20775
0
    j1.swap(j2);
20776
0
}
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
*/
20793
inline nlohmann::json operator "" _json(const char* s, std::size_t n)
20794
0
{
20795
0
    return nlohmann::json::parse(s, s + n);
20796
0
}
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
*/
20811
inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
20812
0
{
20813
0
    return nlohmann::json::json_pointer(std::string(s, n));
20814
0
}
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_