Coverage Report

Created: 2024-02-11 07:19

/src/tinygltf/json.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
    __ _____ _____ _____
3
 __|  |   __|     |   | |  JSON for Modern C++
4
|  |  |__   |  |  | | | |  version 3.10.4
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 10
35
#define NLOHMANN_JSON_VERSION_PATCH 4
36
37
#include <algorithm> // all_of, find, for_each
38
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
39
#include <functional> // hash, less
40
#include <initializer_list> // initializer_list
41
#ifndef JSON_NO_IO
42
    #include <iosfwd> // istream, ostream
43
#endif  // JSON_NO_IO
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 <type_traits>
55
#include <utility>
56
57
// #include <nlohmann/detail/conversions/from_json.hpp>
58
59
60
#include <algorithm> // transform
61
#include <array> // array
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
#include <vector> // vector
79
80
// #include <nlohmann/detail/value_t.hpp>
81
82
83
#include <array> // array
84
#include <cstddef> // size_t
85
#include <cstdint> // uint8_t
86
#include <string> // string
87
88
namespace nlohmann
89
{
90
namespace detail
91
{
92
///////////////////////////
93
// JSON type enumeration //
94
///////////////////////////
95
96
/*!
97
@brief the JSON type enumeration
98
99
This enumeration collects the different JSON types. It is internally used to
100
distinguish the stored values, and the functions @ref basic_json::is_null(),
101
@ref basic_json::is_object(), @ref basic_json::is_array(),
102
@ref basic_json::is_string(), @ref basic_json::is_boolean(),
103
@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
104
@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
105
@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
106
@ref basic_json::is_structured() rely on it.
107
108
@note There are three enumeration entries (number_integer, number_unsigned, and
109
number_float), because the library distinguishes these three types for numbers:
110
@ref basic_json::number_unsigned_t is used for unsigned integers,
111
@ref basic_json::number_integer_t is used for signed integers, and
112
@ref basic_json::number_float_t is used for floating-point numbers or to
113
approximate integers which do not fit in the limits of their respective type.
114
115
@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON
116
value with the default value for a given type
117
118
@since version 1.0.0
119
*/
120
enum class value_t : std::uint8_t
121
{
122
    null,             ///< null value
123
    object,           ///< object (unordered set of name/value pairs)
124
    array,            ///< array (ordered collection of values)
125
    string,           ///< string value
126
    boolean,          ///< boolean value
127
    number_integer,   ///< number value (signed integer)
128
    number_unsigned,  ///< number value (unsigned integer)
129
    number_float,     ///< number value (floating-point)
130
    binary,           ///< binary array (ordered collection of bytes)
131
    discarded         ///< discarded by the parser callback function
132
};
133
134
/*!
135
@brief comparison operator for JSON types
136
137
Returns an ordering that is similar to Python:
138
- order: null < boolean < number < object < array < string < binary
139
- furthermore, each type is not smaller than itself
140
- discarded values are not comparable
141
- binary is represented as a b"" string in python and directly comparable to a
142
  string; however, making a binary array directly comparable with a string would
143
  be surprising behavior in a JSON file.
144
145
@since version 1.0.0
146
*/
147
inline bool operator<(const value_t lhs, const value_t rhs) noexcept
148
0
{
149
0
    static constexpr std::array<std::uint8_t, 9> order = {{
150
0
            0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
151
0
            1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
152
0
            6 /* binary */
153
0
        }
154
0
    };
155
0
156
0
    const auto l_index = static_cast<std::size_t>(lhs);
157
0
    const auto r_index = static_cast<std::size_t>(rhs);
158
0
    return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
159
0
}
160
}  // namespace detail
161
}  // namespace nlohmann
162
163
// #include <nlohmann/detail/string_escape.hpp>
164
165
166
#include <string>
167
// #include <nlohmann/detail/macro_scope.hpp>
168
169
170
#include <utility> // declval, pair
171
// #include <nlohmann/thirdparty/hedley/hedley.hpp>
172
173
174
/* Hedley - https://nemequ.github.io/hedley
175
 * Created by Evan Nemerson <evan@nemerson.com>
176
 *
177
 * To the extent possible under law, the author(s) have dedicated all
178
 * copyright and related and neighboring rights to this software to
179
 * the public domain worldwide. This software is distributed without
180
 * any warranty.
181
 *
182
 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
183
 * SPDX-License-Identifier: CC0-1.0
184
 */
185
186
#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
187
#if defined(JSON_HEDLEY_VERSION)
188
    #undef JSON_HEDLEY_VERSION
189
#endif
190
#define JSON_HEDLEY_VERSION 15
191
192
#if defined(JSON_HEDLEY_STRINGIFY_EX)
193
    #undef JSON_HEDLEY_STRINGIFY_EX
194
#endif
195
#define JSON_HEDLEY_STRINGIFY_EX(x) #x
196
197
#if defined(JSON_HEDLEY_STRINGIFY)
198
    #undef JSON_HEDLEY_STRINGIFY
199
#endif
200
#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
201
202
#if defined(JSON_HEDLEY_CONCAT_EX)
203
    #undef JSON_HEDLEY_CONCAT_EX
204
#endif
205
#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
206
207
#if defined(JSON_HEDLEY_CONCAT)
208
    #undef JSON_HEDLEY_CONCAT
209
#endif
210
#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
211
212
#if defined(JSON_HEDLEY_CONCAT3_EX)
213
    #undef JSON_HEDLEY_CONCAT3_EX
214
#endif
215
#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
216
217
#if defined(JSON_HEDLEY_CONCAT3)
218
    #undef JSON_HEDLEY_CONCAT3
219
#endif
220
#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
221
222
#if defined(JSON_HEDLEY_VERSION_ENCODE)
223
    #undef JSON_HEDLEY_VERSION_ENCODE
224
#endif
225
#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
226
227
#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
228
    #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
229
#endif
230
#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
231
232
#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
233
    #undef JSON_HEDLEY_VERSION_DECODE_MINOR
234
#endif
235
#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
236
237
#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
238
    #undef JSON_HEDLEY_VERSION_DECODE_REVISION
239
#endif
240
#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
241
242
#if defined(JSON_HEDLEY_GNUC_VERSION)
243
    #undef JSON_HEDLEY_GNUC_VERSION
244
#endif
245
#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
246
    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
247
#elif defined(__GNUC__)
248
    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
249
#endif
250
251
#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
252
    #undef JSON_HEDLEY_GNUC_VERSION_CHECK
253
#endif
254
#if defined(JSON_HEDLEY_GNUC_VERSION)
255
    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
256
#else
257
    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
258
#endif
259
260
#if defined(JSON_HEDLEY_MSVC_VERSION)
261
    #undef JSON_HEDLEY_MSVC_VERSION
262
#endif
263
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
264
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
265
#elif defined(_MSC_FULL_VER) && !defined(__ICL)
266
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
267
#elif defined(_MSC_VER) && !defined(__ICL)
268
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
269
#endif
270
271
#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
272
    #undef JSON_HEDLEY_MSVC_VERSION_CHECK
273
#endif
274
#if !defined(JSON_HEDLEY_MSVC_VERSION)
275
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
276
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
277
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
278
#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
279
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
280
#else
281
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
282
#endif
283
284
#if defined(JSON_HEDLEY_INTEL_VERSION)
285
    #undef JSON_HEDLEY_INTEL_VERSION
286
#endif
287
#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
288
    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
289
#elif defined(__INTEL_COMPILER) && !defined(__ICL)
290
    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
291
#endif
292
293
#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
294
    #undef JSON_HEDLEY_INTEL_VERSION_CHECK
295
#endif
296
#if defined(JSON_HEDLEY_INTEL_VERSION)
297
    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
298
#else
299
    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
300
#endif
301
302
#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
303
    #undef JSON_HEDLEY_INTEL_CL_VERSION
304
#endif
305
#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
306
    #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
307
#endif
308
309
#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
310
    #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
311
#endif
312
#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
313
    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
314
#else
315
    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
316
#endif
317
318
#if defined(JSON_HEDLEY_PGI_VERSION)
319
    #undef JSON_HEDLEY_PGI_VERSION
320
#endif
321
#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
322
    #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
323
#endif
324
325
#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
326
    #undef JSON_HEDLEY_PGI_VERSION_CHECK
327
#endif
328
#if defined(JSON_HEDLEY_PGI_VERSION)
329
    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
330
#else
331
    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
332
#endif
333
334
#if defined(JSON_HEDLEY_SUNPRO_VERSION)
335
    #undef JSON_HEDLEY_SUNPRO_VERSION
336
#endif
337
#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
338
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
339
#elif defined(__SUNPRO_C)
340
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
341
#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
342
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
343
#elif defined(__SUNPRO_CC)
344
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
345
#endif
346
347
#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
348
    #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
349
#endif
350
#if defined(JSON_HEDLEY_SUNPRO_VERSION)
351
    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
352
#else
353
    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
354
#endif
355
356
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
357
    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
358
#endif
359
#if defined(__EMSCRIPTEN__)
360
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
361
#endif
362
363
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
364
    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
365
#endif
366
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
367
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
368
#else
369
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
370
#endif
371
372
#if defined(JSON_HEDLEY_ARM_VERSION)
373
    #undef JSON_HEDLEY_ARM_VERSION
374
#endif
375
#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
376
    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
377
#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
378
    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
379
#endif
380
381
#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
382
    #undef JSON_HEDLEY_ARM_VERSION_CHECK
383
#endif
384
#if defined(JSON_HEDLEY_ARM_VERSION)
385
    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
386
#else
387
    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
388
#endif
389
390
#if defined(JSON_HEDLEY_IBM_VERSION)
391
    #undef JSON_HEDLEY_IBM_VERSION
392
#endif
393
#if defined(__ibmxl__)
394
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
395
#elif defined(__xlC__) && defined(__xlC_ver__)
396
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
397
#elif defined(__xlC__)
398
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
399
#endif
400
401
#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
402
    #undef JSON_HEDLEY_IBM_VERSION_CHECK
403
#endif
404
#if defined(JSON_HEDLEY_IBM_VERSION)
405
    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
406
#else
407
    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
408
#endif
409
410
#if defined(JSON_HEDLEY_TI_VERSION)
411
    #undef JSON_HEDLEY_TI_VERSION
412
#endif
413
#if \
414
    defined(__TI_COMPILER_VERSION__) && \
415
    ( \
416
      defined(__TMS470__) || defined(__TI_ARM__) || \
417
      defined(__MSP430__) || \
418
      defined(__TMS320C2000__) \
419
    )
420
#if (__TI_COMPILER_VERSION__ >= 16000000)
421
    #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
422
#endif
423
#endif
424
425
#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
426
    #undef JSON_HEDLEY_TI_VERSION_CHECK
427
#endif
428
#if defined(JSON_HEDLEY_TI_VERSION)
429
    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430
#else
431
    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
432
#endif
433
434
#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
435
    #undef JSON_HEDLEY_TI_CL2000_VERSION
436
#endif
437
#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
438
    #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439
#endif
440
441
#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
442
    #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
443
#endif
444
#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
445
    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446
#else
447
    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
448
#endif
449
450
#if defined(JSON_HEDLEY_TI_CL430_VERSION)
451
    #undef JSON_HEDLEY_TI_CL430_VERSION
452
#endif
453
#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
454
    #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
455
#endif
456
457
#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
458
    #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
459
#endif
460
#if defined(JSON_HEDLEY_TI_CL430_VERSION)
461
    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462
#else
463
    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
464
#endif
465
466
#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
467
    #undef JSON_HEDLEY_TI_ARMCL_VERSION
468
#endif
469
#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
470
    #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
471
#endif
472
473
#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
474
    #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
475
#endif
476
#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
477
    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478
#else
479
    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
480
#endif
481
482
#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
483
    #undef JSON_HEDLEY_TI_CL6X_VERSION
484
#endif
485
#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
486
    #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
487
#endif
488
489
#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
490
    #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
491
#endif
492
#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
493
    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
494
#else
495
    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
496
#endif
497
498
#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
499
    #undef JSON_HEDLEY_TI_CL7X_VERSION
500
#endif
501
#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
502
    #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
503
#endif
504
505
#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
506
    #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
507
#endif
508
#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
509
    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
510
#else
511
    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
512
#endif
513
514
#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
515
    #undef JSON_HEDLEY_TI_CLPRU_VERSION
516
#endif
517
#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
518
    #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
519
#endif
520
521
#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
522
    #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
523
#endif
524
#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
525
    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
526
#else
527
    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
528
#endif
529
530
#if defined(JSON_HEDLEY_CRAY_VERSION)
531
    #undef JSON_HEDLEY_CRAY_VERSION
532
#endif
533
#if defined(_CRAYC)
534
    #if defined(_RELEASE_PATCHLEVEL)
535
        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
536
    #else
537
        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
538
    #endif
539
#endif
540
541
#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
542
    #undef JSON_HEDLEY_CRAY_VERSION_CHECK
543
#endif
544
#if defined(JSON_HEDLEY_CRAY_VERSION)
545
    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
546
#else
547
    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
548
#endif
549
550
#if defined(JSON_HEDLEY_IAR_VERSION)
551
    #undef JSON_HEDLEY_IAR_VERSION
552
#endif
553
#if defined(__IAR_SYSTEMS_ICC__)
554
    #if __VER__ > 1000
555
        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
556
    #else
557
        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
558
    #endif
559
#endif
560
561
#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
562
    #undef JSON_HEDLEY_IAR_VERSION_CHECK
563
#endif
564
#if defined(JSON_HEDLEY_IAR_VERSION)
565
    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
566
#else
567
    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
568
#endif
569
570
#if defined(JSON_HEDLEY_TINYC_VERSION)
571
    #undef JSON_HEDLEY_TINYC_VERSION
572
#endif
573
#if defined(__TINYC__)
574
    #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
575
#endif
576
577
#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
578
    #undef JSON_HEDLEY_TINYC_VERSION_CHECK
579
#endif
580
#if defined(JSON_HEDLEY_TINYC_VERSION)
581
    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
582
#else
583
    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
584
#endif
585
586
#if defined(JSON_HEDLEY_DMC_VERSION)
587
    #undef JSON_HEDLEY_DMC_VERSION
588
#endif
589
#if defined(__DMC__)
590
    #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
591
#endif
592
593
#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
594
    #undef JSON_HEDLEY_DMC_VERSION_CHECK
595
#endif
596
#if defined(JSON_HEDLEY_DMC_VERSION)
597
    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
598
#else
599
    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
600
#endif
601
602
#if defined(JSON_HEDLEY_COMPCERT_VERSION)
603
    #undef JSON_HEDLEY_COMPCERT_VERSION
604
#endif
605
#if defined(__COMPCERT_VERSION__)
606
    #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
607
#endif
608
609
#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
610
    #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
611
#endif
612
#if defined(JSON_HEDLEY_COMPCERT_VERSION)
613
    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
614
#else
615
    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
616
#endif
617
618
#if defined(JSON_HEDLEY_PELLES_VERSION)
619
    #undef JSON_HEDLEY_PELLES_VERSION
620
#endif
621
#if defined(__POCC__)
622
    #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
623
#endif
624
625
#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
626
    #undef JSON_HEDLEY_PELLES_VERSION_CHECK
627
#endif
628
#if defined(JSON_HEDLEY_PELLES_VERSION)
629
    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
630
#else
631
    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
632
#endif
633
634
#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
635
    #undef JSON_HEDLEY_MCST_LCC_VERSION
636
#endif
637
#if defined(__LCC__) && defined(__LCC_MINOR__)
638
    #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
639
#endif
640
641
#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
642
    #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
643
#endif
644
#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
645
    #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
646
#else
647
    #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
648
#endif
649
650
#if defined(JSON_HEDLEY_GCC_VERSION)
651
    #undef JSON_HEDLEY_GCC_VERSION
652
#endif
653
#if \
654
    defined(JSON_HEDLEY_GNUC_VERSION) && \
655
    !defined(__clang__) && \
656
    !defined(JSON_HEDLEY_INTEL_VERSION) && \
657
    !defined(JSON_HEDLEY_PGI_VERSION) && \
658
    !defined(JSON_HEDLEY_ARM_VERSION) && \
659
    !defined(JSON_HEDLEY_CRAY_VERSION) && \
660
    !defined(JSON_HEDLEY_TI_VERSION) && \
661
    !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
662
    !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
663
    !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
664
    !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
665
    !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
666
    !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
667
    !defined(__COMPCERT__) && \
668
    !defined(JSON_HEDLEY_MCST_LCC_VERSION)
669
    #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
670
#endif
671
672
#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
673
    #undef JSON_HEDLEY_GCC_VERSION_CHECK
674
#endif
675
#if defined(JSON_HEDLEY_GCC_VERSION)
676
    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
677
#else
678
    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
679
#endif
680
681
#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
682
    #undef JSON_HEDLEY_HAS_ATTRIBUTE
683
#endif
684
#if \
685
  defined(__has_attribute) && \
686
  ( \
687
    (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
688
  )
689
#  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
690
#else
691
#  define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
692
#endif
693
694
#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
695
    #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
696
#endif
697
#if defined(__has_attribute)
698
    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
699
#else
700
    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
701
#endif
702
703
#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
704
    #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
705
#endif
706
#if defined(__has_attribute)
707
    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
708
#else
709
    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
710
#endif
711
712
#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
713
    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
714
#endif
715
#if \
716
    defined(__has_cpp_attribute) && \
717
    defined(__cplusplus) && \
718
    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
719
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
720
#else
721
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
722
#endif
723
724
#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
725
    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
726
#endif
727
#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
728
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
729
#elif \
730
    !defined(JSON_HEDLEY_PGI_VERSION) && \
731
    !defined(JSON_HEDLEY_IAR_VERSION) && \
732
    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
733
    (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
734
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
735
#else
736
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
737
#endif
738
739
#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
740
    #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
741
#endif
742
#if defined(__has_cpp_attribute) && defined(__cplusplus)
743
    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
744
#else
745
    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
746
#endif
747
748
#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
749
    #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
750
#endif
751
#if defined(__has_cpp_attribute) && defined(__cplusplus)
752
    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
753
#else
754
    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
755
#endif
756
757
#if defined(JSON_HEDLEY_HAS_BUILTIN)
758
    #undef JSON_HEDLEY_HAS_BUILTIN
759
#endif
760
#if defined(__has_builtin)
761
    #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
762
#else
763
    #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
764
#endif
765
766
#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
767
    #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
768
#endif
769
#if defined(__has_builtin)
770
    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
771
#else
772
    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
773
#endif
774
775
#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
776
    #undef JSON_HEDLEY_GCC_HAS_BUILTIN
777
#endif
778
#if defined(__has_builtin)
779
    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
780
#else
781
    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
782
#endif
783
784
#if defined(JSON_HEDLEY_HAS_FEATURE)
785
    #undef JSON_HEDLEY_HAS_FEATURE
786
#endif
787
#if defined(__has_feature)
788
    #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
789
#else
790
    #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
791
#endif
792
793
#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
794
    #undef JSON_HEDLEY_GNUC_HAS_FEATURE
795
#endif
796
#if defined(__has_feature)
797
    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
798
#else
799
    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
800
#endif
801
802
#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
803
    #undef JSON_HEDLEY_GCC_HAS_FEATURE
804
#endif
805
#if defined(__has_feature)
806
    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
807
#else
808
    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
809
#endif
810
811
#if defined(JSON_HEDLEY_HAS_EXTENSION)
812
    #undef JSON_HEDLEY_HAS_EXTENSION
813
#endif
814
#if defined(__has_extension)
815
    #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
816
#else
817
    #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
818
#endif
819
820
#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
821
    #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
822
#endif
823
#if defined(__has_extension)
824
    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
825
#else
826
    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
827
#endif
828
829
#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
830
    #undef JSON_HEDLEY_GCC_HAS_EXTENSION
831
#endif
832
#if defined(__has_extension)
833
    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
834
#else
835
    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
836
#endif
837
838
#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
839
    #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
840
#endif
841
#if defined(__has_declspec_attribute)
842
    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
843
#else
844
    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
845
#endif
846
847
#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
848
    #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
849
#endif
850
#if defined(__has_declspec_attribute)
851
    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
852
#else
853
    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
854
#endif
855
856
#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
857
    #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
858
#endif
859
#if defined(__has_declspec_attribute)
860
    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
861
#else
862
    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
863
#endif
864
865
#if defined(JSON_HEDLEY_HAS_WARNING)
866
    #undef JSON_HEDLEY_HAS_WARNING
867
#endif
868
#if defined(__has_warning)
869
    #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
870
#else
871
    #define JSON_HEDLEY_HAS_WARNING(warning) (0)
872
#endif
873
874
#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
875
    #undef JSON_HEDLEY_GNUC_HAS_WARNING
876
#endif
877
#if defined(__has_warning)
878
    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
879
#else
880
    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
881
#endif
882
883
#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
884
    #undef JSON_HEDLEY_GCC_HAS_WARNING
885
#endif
886
#if defined(__has_warning)
887
    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
888
#else
889
    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
890
#endif
891
892
#if \
893
    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
894
    defined(__clang__) || \
895
    JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
896
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
897
    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
898
    JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
899
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
900
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
901
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
902
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
903
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
904
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
905
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
906
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
907
    JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
908
    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
909
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
910
    (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
911
    #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
912
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
913
    #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
914
#else
915
    #define JSON_HEDLEY_PRAGMA(value)
916
#endif
917
918
#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
919
    #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
920
#endif
921
#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
922
    #undef JSON_HEDLEY_DIAGNOSTIC_POP
923
#endif
924
#if defined(__clang__)
925
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
926
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
927
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
928
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
929
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
930
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
931
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
932
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
933
#elif \
934
    JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
935
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
936
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
937
    #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
938
#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
939
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
940
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
941
#elif \
942
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
943
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
944
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
945
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
946
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
947
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
948
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
949
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
950
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
951
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
952
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
953
#else
954
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH
955
    #define JSON_HEDLEY_DIAGNOSTIC_POP
956
#endif
957
958
/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
959
   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
960
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
961
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
962
#endif
963
#if defined(__cplusplus)
964
#  if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
965
#    if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
966
#      if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
967
#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
968
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
969
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
970
    _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
971
    _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
972
    xpr \
973
    JSON_HEDLEY_DIAGNOSTIC_POP
974
#      else
975
#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
976
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
977
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
978
    _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
979
    xpr \
980
    JSON_HEDLEY_DIAGNOSTIC_POP
981
#      endif
982
#    else
983
#      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
984
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
985
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
986
    xpr \
987
    JSON_HEDLEY_DIAGNOSTIC_POP
988
#    endif
989
#  endif
990
#endif
991
#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
992
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
993
#endif
994
995
#if defined(JSON_HEDLEY_CONST_CAST)
996
    #undef JSON_HEDLEY_CONST_CAST
997
#endif
998
#if defined(__cplusplus)
999
#  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1000
#elif \
1001
  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1002
  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1003
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1004
#  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1005
        JSON_HEDLEY_DIAGNOSTIC_PUSH \
1006
        JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1007
        ((T) (expr)); \
1008
        JSON_HEDLEY_DIAGNOSTIC_POP \
1009
    }))
1010
#else
1011
#  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1012
#endif
1013
1014
#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1015
    #undef JSON_HEDLEY_REINTERPRET_CAST
1016
#endif
1017
#if defined(__cplusplus)
1018
    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1019
#else
1020
    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1021
#endif
1022
1023
#if defined(JSON_HEDLEY_STATIC_CAST)
1024
    #undef JSON_HEDLEY_STATIC_CAST
1025
#endif
1026
#if defined(__cplusplus)
1027
    #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1028
#else
1029
    #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1030
#endif
1031
1032
#if defined(JSON_HEDLEY_CPP_CAST)
1033
    #undef JSON_HEDLEY_CPP_CAST
1034
#endif
1035
#if defined(__cplusplus)
1036
#  if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1037
#    define JSON_HEDLEY_CPP_CAST(T, expr) \
1038
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
1039
    _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1040
    ((T) (expr)) \
1041
    JSON_HEDLEY_DIAGNOSTIC_POP
1042
#  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1043
#    define JSON_HEDLEY_CPP_CAST(T, expr) \
1044
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
1045
    _Pragma("diag_suppress=Pe137") \
1046
    JSON_HEDLEY_DIAGNOSTIC_POP
1047
#  else
1048
#    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1049
#  endif
1050
#else
1051
#  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1052
#endif
1053
1054
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1055
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1056
#endif
1057
#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1058
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1059
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1060
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1061
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1062
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1063
#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1064
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1065
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1066
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1067
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1068
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1069
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1070
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1071
#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1072
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1073
#elif \
1074
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1086
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1087
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1088
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1089
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1090
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1091
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1092
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1093
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1094
#else
1095
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1096
#endif
1097
1098
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1099
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1100
#endif
1101
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1102
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1103
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1104
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1105
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1106
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1107
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1108
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1109
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1110
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1111
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1112
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1113
#elif \
1114
    JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1115
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1116
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1117
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1118
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1119
#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1120
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1121
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1122
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1123
#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1124
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1125
#else
1126
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1127
#endif
1128
1129
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1130
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1131
#endif
1132
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1133
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1134
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1135
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1136
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1137
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1138
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1139
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1140
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1141
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1142
#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1143
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1144
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1145
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1146
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1147
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1148
#elif \
1149
    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1150
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1151
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1152
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1153
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1154
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1155
#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1156
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1157
#else
1158
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1159
#endif
1160
1161
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1162
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1163
#endif
1164
#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1165
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1166
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1167
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1168
#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1169
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1170
#else
1171
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1172
#endif
1173
1174
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1175
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1176
#endif
1177
#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1178
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1179
#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1180
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1181
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1182
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1183
#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1184
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1185
#else
1186
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1187
#endif
1188
1189
#if defined(JSON_HEDLEY_DEPRECATED)
1190
    #undef JSON_HEDLEY_DEPRECATED
1191
#endif
1192
#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1193
    #undef JSON_HEDLEY_DEPRECATED_FOR
1194
#endif
1195
#if \
1196
    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1197
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1198
    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1199
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1200
#elif \
1201
    (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1202
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1203
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1204
    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1205
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1206
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1207
    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1208
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1209
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1210
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1211
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1212
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1213
    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1214
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1215
#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1216
    #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1217
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1218
#elif \
1219
    JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1220
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1221
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1222
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1233
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1234
    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1235
    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1236
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1237
#elif \
1238
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1239
    JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1240
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1241
    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1242
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1243
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1244
    #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1245
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1246
#else
1247
    #define JSON_HEDLEY_DEPRECATED(since)
1248
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1249
#endif
1250
1251
#if defined(JSON_HEDLEY_UNAVAILABLE)
1252
    #undef JSON_HEDLEY_UNAVAILABLE
1253
#endif
1254
#if \
1255
    JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1256
    JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1257
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1258
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1259
    #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1260
#else
1261
    #define JSON_HEDLEY_UNAVAILABLE(available_since)
1262
#endif
1263
1264
#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1265
    #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1266
#endif
1267
#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1268
    #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1269
#endif
1270
#if \
1271
    JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1272
    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1273
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1274
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1275
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1276
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1277
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1279
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1281
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1283
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1284
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1285
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1286
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1287
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1288
    #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1289
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1290
#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1291
    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1292
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1293
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1294
    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1296
#elif defined(_Check_return_) /* SAL */
1297
    #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1298
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1299
#else
1300
    #define JSON_HEDLEY_WARN_UNUSED_RESULT
1301
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1302
#endif
1303
1304
#if defined(JSON_HEDLEY_SENTINEL)
1305
    #undef JSON_HEDLEY_SENTINEL
1306
#endif
1307
#if \
1308
    JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1309
    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1310
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311
    JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1312
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1313
    #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1314
#else
1315
    #define JSON_HEDLEY_SENTINEL(position)
1316
#endif
1317
1318
#if defined(JSON_HEDLEY_NO_RETURN)
1319
    #undef JSON_HEDLEY_NO_RETURN
1320
#endif
1321
#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1322
    #define JSON_HEDLEY_NO_RETURN __noreturn
1323
#elif \
1324
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1325
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1326
    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1327
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1328
    #define JSON_HEDLEY_NO_RETURN _Noreturn
1329
#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1330
    #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1331
#elif \
1332
    JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1333
    JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1334
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1335
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1336
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1337
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1338
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1339
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1340
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1341
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1342
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1343
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1344
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1345
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1346
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1347
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1348
    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1349
    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1350
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1351
    #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1352
#elif \
1353
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1354
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1355
    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1356
#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1357
    #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1358
#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1359
    #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1360
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1361
    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1362
#else
1363
    #define JSON_HEDLEY_NO_RETURN
1364
#endif
1365
1366
#if defined(JSON_HEDLEY_NO_ESCAPE)
1367
    #undef JSON_HEDLEY_NO_ESCAPE
1368
#endif
1369
#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1370
    #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1371
#else
1372
    #define JSON_HEDLEY_NO_ESCAPE
1373
#endif
1374
1375
#if defined(JSON_HEDLEY_UNREACHABLE)
1376
    #undef JSON_HEDLEY_UNREACHABLE
1377
#endif
1378
#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1379
    #undef JSON_HEDLEY_UNREACHABLE_RETURN
1380
#endif
1381
#if defined(JSON_HEDLEY_ASSUME)
1382
    #undef JSON_HEDLEY_ASSUME
1383
#endif
1384
#if \
1385
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1386
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1387
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1388
    #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1389
#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1390
    #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1391
#elif \
1392
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1393
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1394
    #if defined(__cplusplus)
1395
        #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1396
    #else
1397
        #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1398
    #endif
1399
#endif
1400
#if \
1401
    (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1402
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1403
    JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1404
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1405
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1406
    JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1407
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1408
    #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1409
#elif defined(JSON_HEDLEY_ASSUME)
1410
    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1411
#endif
1412
#if !defined(JSON_HEDLEY_ASSUME)
1413
    #if defined(JSON_HEDLEY_UNREACHABLE)
1414
        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1415
    #else
1416
        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1417
    #endif
1418
#endif
1419
#if defined(JSON_HEDLEY_UNREACHABLE)
1420
    #if  \
1421
        JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1422
        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1423
        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1424
    #else
1425
        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1426
    #endif
1427
#else
1428
    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1429
#endif
1430
#if !defined(JSON_HEDLEY_UNREACHABLE)
1431
    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1432
#endif
1433
1434
JSON_HEDLEY_DIAGNOSTIC_PUSH
1435
#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1436
    #pragma clang diagnostic ignored "-Wpedantic"
1437
#endif
1438
#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1439
    #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1440
#endif
1441
#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1442
    #if defined(__clang__)
1443
        #pragma clang diagnostic ignored "-Wvariadic-macros"
1444
    #elif defined(JSON_HEDLEY_GCC_VERSION)
1445
        #pragma GCC diagnostic ignored "-Wvariadic-macros"
1446
    #endif
1447
#endif
1448
#if defined(JSON_HEDLEY_NON_NULL)
1449
    #undef JSON_HEDLEY_NON_NULL
1450
#endif
1451
#if \
1452
    JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1453
    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1454
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1456
    #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1457
#else
1458
    #define JSON_HEDLEY_NON_NULL(...)
1459
#endif
1460
JSON_HEDLEY_DIAGNOSTIC_POP
1461
1462
#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1463
    #undef JSON_HEDLEY_PRINTF_FORMAT
1464
#endif
1465
#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1466
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1467
#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1468
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1469
#elif \
1470
    JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1471
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1472
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473
    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1474
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1475
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1476
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1477
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1478
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1479
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1480
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1481
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1482
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1483
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1484
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1485
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1486
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1487
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1488
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1489
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1490
#else
1491
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1492
#endif
1493
1494
#if defined(JSON_HEDLEY_CONSTEXPR)
1495
    #undef JSON_HEDLEY_CONSTEXPR
1496
#endif
1497
#if defined(__cplusplus)
1498
    #if __cplusplus >= 201103L
1499
        #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1500
    #endif
1501
#endif
1502
#if !defined(JSON_HEDLEY_CONSTEXPR)
1503
    #define JSON_HEDLEY_CONSTEXPR
1504
#endif
1505
1506
#if defined(JSON_HEDLEY_PREDICT)
1507
    #undef JSON_HEDLEY_PREDICT
1508
#endif
1509
#if defined(JSON_HEDLEY_LIKELY)
1510
    #undef JSON_HEDLEY_LIKELY
1511
#endif
1512
#if defined(JSON_HEDLEY_UNLIKELY)
1513
    #undef JSON_HEDLEY_UNLIKELY
1514
#endif
1515
#if defined(JSON_HEDLEY_UNPREDICTABLE)
1516
    #undef JSON_HEDLEY_UNPREDICTABLE
1517
#endif
1518
#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1519
    #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1520
#endif
1521
#if \
1522
  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1523
  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1524
  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1525
#  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))
1526
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))
1527
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))
1528
206M
#  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )
1529
43.0M
#  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )
1530
#elif \
1531
  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1532
  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1533
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1534
  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1535
  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1536
  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1537
  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1538
  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1539
  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1540
  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1541
  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1542
  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1543
  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1544
  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1545
  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1546
  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1547
#  define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1548
    (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1549
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1550
    (__extension__ ({ \
1551
        double hedley_probability_ = (probability); \
1552
        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1553
    }))
1554
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1555
    (__extension__ ({ \
1556
        double hedley_probability_ = (probability); \
1557
        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1558
    }))
1559
#  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)
1560
#  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1561
#else
1562
#  define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1563
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1564
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1565
#  define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1566
#  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1567
#endif
1568
#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1569
    #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1570
#endif
1571
1572
#if defined(JSON_HEDLEY_MALLOC)
1573
    #undef JSON_HEDLEY_MALLOC
1574
#endif
1575
#if \
1576
    JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1577
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1578
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1579
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1580
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1581
    JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1582
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1583
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1584
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1585
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1586
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1587
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1588
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1589
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1590
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1591
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1592
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1593
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1594
    #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1595
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1596
    #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1597
#elif \
1598
    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1599
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1600
    #define JSON_HEDLEY_MALLOC __declspec(restrict)
1601
#else
1602
    #define JSON_HEDLEY_MALLOC
1603
#endif
1604
1605
#if defined(JSON_HEDLEY_PURE)
1606
    #undef JSON_HEDLEY_PURE
1607
#endif
1608
#if \
1609
  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1610
  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1611
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612
  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613
  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614
  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615
  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616
  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617
  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618
  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619
  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620
  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621
  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622
  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623
  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624
  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625
  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1626
  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1627
  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1628
#  define JSON_HEDLEY_PURE __attribute__((__pure__))
1629
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1630
#  define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1631
#elif defined(__cplusplus) && \
1632
    ( \
1633
      JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1634
      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1635
      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1636
    )
1637
#  define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1638
#else
1639
#  define JSON_HEDLEY_PURE
1640
#endif
1641
1642
#if defined(JSON_HEDLEY_CONST)
1643
    #undef JSON_HEDLEY_CONST
1644
#endif
1645
#if \
1646
    JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1647
    JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1648
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1649
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1651
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1652
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1653
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1654
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1655
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1657
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1659
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1661
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1662
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1663
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1664
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1665
    #define JSON_HEDLEY_CONST __attribute__((__const__))
1666
#elif \
1667
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1668
    #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1669
#else
1670
    #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1671
#endif
1672
1673
#if defined(JSON_HEDLEY_RESTRICT)
1674
    #undef JSON_HEDLEY_RESTRICT
1675
#endif
1676
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1677
    #define JSON_HEDLEY_RESTRICT restrict
1678
#elif \
1679
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1680
    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1681
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1683
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1686
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1687
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1688
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1689
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1690
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1691
    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1692
    defined(__clang__) || \
1693
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1694
    #define JSON_HEDLEY_RESTRICT __restrict
1695
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1696
    #define JSON_HEDLEY_RESTRICT _Restrict
1697
#else
1698
    #define JSON_HEDLEY_RESTRICT
1699
#endif
1700
1701
#if defined(JSON_HEDLEY_INLINE)
1702
    #undef JSON_HEDLEY_INLINE
1703
#endif
1704
#if \
1705
    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1706
    (defined(__cplusplus) && (__cplusplus >= 199711L))
1707
    #define JSON_HEDLEY_INLINE inline
1708
#elif \
1709
    defined(JSON_HEDLEY_GCC_VERSION) || \
1710
    JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1711
    #define JSON_HEDLEY_INLINE __inline__
1712
#elif \
1713
    JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1714
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1715
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1716
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1717
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1718
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1719
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1720
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1721
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1722
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1723
    #define JSON_HEDLEY_INLINE __inline
1724
#else
1725
    #define JSON_HEDLEY_INLINE
1726
#endif
1727
1728
#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1729
    #undef JSON_HEDLEY_ALWAYS_INLINE
1730
#endif
1731
#if \
1732
  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1733
  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1734
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1735
  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1736
  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1737
  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1738
  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1739
  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1740
  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1741
  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742
  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1743
  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744
  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1745
  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746
  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1747
  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1748
  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1749
  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1750
  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1751
#  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1752
#elif \
1753
  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1754
  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1755
#  define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1756
#elif defined(__cplusplus) && \
1757
    ( \
1758
      JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1759
      JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1760
      JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1761
      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1762
      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1763
      JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1764
    )
1765
#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1766
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1767
#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1768
#else
1769
#  define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1770
#endif
1771
1772
#if defined(JSON_HEDLEY_NEVER_INLINE)
1773
    #undef JSON_HEDLEY_NEVER_INLINE
1774
#endif
1775
#if \
1776
    JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1777
    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1778
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1779
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1780
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1781
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1782
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1783
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1784
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1785
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1786
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1787
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1788
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1789
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1790
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1791
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1792
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1793
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1794
    JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1795
    #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1796
#elif \
1797
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1798
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1799
    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1800
#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1801
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1802
#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1803
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1804
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1805
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1806
#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1807
    #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1808
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1809
    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1810
#else
1811
    #define JSON_HEDLEY_NEVER_INLINE
1812
#endif
1813
1814
#if defined(JSON_HEDLEY_PRIVATE)
1815
    #undef JSON_HEDLEY_PRIVATE
1816
#endif
1817
#if defined(JSON_HEDLEY_PUBLIC)
1818
    #undef JSON_HEDLEY_PUBLIC
1819
#endif
1820
#if defined(JSON_HEDLEY_IMPORT)
1821
    #undef JSON_HEDLEY_IMPORT
1822
#endif
1823
#if defined(_WIN32) || defined(__CYGWIN__)
1824
#  define JSON_HEDLEY_PRIVATE
1825
#  define JSON_HEDLEY_PUBLIC   __declspec(dllexport)
1826
#  define JSON_HEDLEY_IMPORT   __declspec(dllimport)
1827
#else
1828
#  if \
1829
    JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1830
    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1831
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1832
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1833
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1834
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1835
    ( \
1836
      defined(__TI_EABI__) && \
1837
      ( \
1838
        (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1839
        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1840
      ) \
1841
    ) || \
1842
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1843
#    define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1844
#    define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__("default")))
1845
#  else
1846
#    define JSON_HEDLEY_PRIVATE
1847
#    define JSON_HEDLEY_PUBLIC
1848
#  endif
1849
#  define JSON_HEDLEY_IMPORT    extern
1850
#endif
1851
1852
#if defined(JSON_HEDLEY_NO_THROW)
1853
    #undef JSON_HEDLEY_NO_THROW
1854
#endif
1855
#if \
1856
    JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1857
    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1858
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1859
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860
    #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1861
#elif \
1862
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1863
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1864
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1865
    #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1866
#else
1867
    #define JSON_HEDLEY_NO_THROW
1868
#endif
1869
1870
#if defined(JSON_HEDLEY_FALL_THROUGH)
1871
    #undef JSON_HEDLEY_FALL_THROUGH
1872
#endif
1873
#if \
1874
    JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1875
    JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1876
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877
    #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1878
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1879
    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1880
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1881
    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1882
#elif defined(__fallthrough) /* SAL */
1883
    #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1884
#else
1885
    #define JSON_HEDLEY_FALL_THROUGH
1886
#endif
1887
1888
#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1889
    #undef JSON_HEDLEY_RETURNS_NON_NULL
1890
#endif
1891
#if \
1892
    JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1893
    JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1894
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1895
    #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1896
#elif defined(_Ret_notnull_) /* SAL */
1897
    #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1898
#else
1899
    #define JSON_HEDLEY_RETURNS_NON_NULL
1900
#endif
1901
1902
#if defined(JSON_HEDLEY_ARRAY_PARAM)
1903
    #undef JSON_HEDLEY_ARRAY_PARAM
1904
#endif
1905
#if \
1906
    defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1907
    !defined(__STDC_NO_VLA__) && \
1908
    !defined(__cplusplus) && \
1909
    !defined(JSON_HEDLEY_PGI_VERSION) && \
1910
    !defined(JSON_HEDLEY_TINYC_VERSION)
1911
    #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1912
#else
1913
    #define JSON_HEDLEY_ARRAY_PARAM(name)
1914
#endif
1915
1916
#if defined(JSON_HEDLEY_IS_CONSTANT)
1917
    #undef JSON_HEDLEY_IS_CONSTANT
1918
#endif
1919
#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1920
    #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1921
#endif
1922
/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1923
   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
1924
#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1925
    #undef JSON_HEDLEY_IS_CONSTEXPR_
1926
#endif
1927
#if \
1928
    JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1929
    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1930
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1931
    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1932
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1933
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1934
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1935
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1936
    JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1937
    JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1938
    #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1939
#endif
1940
#if !defined(__cplusplus)
1941
#  if \
1942
       JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1943
       JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1944
       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1945
       JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1946
       JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1947
       JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1948
       JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1949
#if defined(__INTPTR_TYPE__)
1950
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1951
#else
1952
    #include <stdint.h>
1953
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1954
#endif
1955
#  elif \
1956
       ( \
1957
          defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1958
          !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1959
          !defined(JSON_HEDLEY_PGI_VERSION) && \
1960
          !defined(JSON_HEDLEY_IAR_VERSION)) || \
1961
       (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1962
       JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1963
       JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1964
       JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1965
       JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1966
#if defined(__INTPTR_TYPE__)
1967
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1968
#else
1969
    #include <stdint.h>
1970
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1971
#endif
1972
#  elif \
1973
       defined(JSON_HEDLEY_GCC_VERSION) || \
1974
       defined(JSON_HEDLEY_INTEL_VERSION) || \
1975
       defined(JSON_HEDLEY_TINYC_VERSION) || \
1976
       defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1977
       JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1978
       defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1979
       defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1980
       defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1981
       defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1982
       defined(__clang__)
1983
#    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1984
        sizeof(void) != \
1985
        sizeof(*( \
1986
                  1 ? \
1987
                  ((void*) ((expr) * 0L) ) : \
1988
((struct { char v[sizeof(void) * 2]; } *) 1) \
1989
                ) \
1990
              ) \
1991
                                            )
1992
#  endif
1993
#endif
1994
#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1995
    #if !defined(JSON_HEDLEY_IS_CONSTANT)
1996
        #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1997
    #endif
1998
    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1999
#else
2000
    #if !defined(JSON_HEDLEY_IS_CONSTANT)
2001
        #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2002
    #endif
2003
    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2004
#endif
2005
2006
#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2007
    #undef JSON_HEDLEY_BEGIN_C_DECLS
2008
#endif
2009
#if defined(JSON_HEDLEY_END_C_DECLS)
2010
    #undef JSON_HEDLEY_END_C_DECLS
2011
#endif
2012
#if defined(JSON_HEDLEY_C_DECL)
2013
    #undef JSON_HEDLEY_C_DECL
2014
#endif
2015
#if defined(__cplusplus)
2016
    #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2017
    #define JSON_HEDLEY_END_C_DECLS }
2018
    #define JSON_HEDLEY_C_DECL extern "C"
2019
#else
2020
    #define JSON_HEDLEY_BEGIN_C_DECLS
2021
    #define JSON_HEDLEY_END_C_DECLS
2022
    #define JSON_HEDLEY_C_DECL
2023
#endif
2024
2025
#if defined(JSON_HEDLEY_STATIC_ASSERT)
2026
    #undef JSON_HEDLEY_STATIC_ASSERT
2027
#endif
2028
#if \
2029
  !defined(__cplusplus) && ( \
2030
      (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2031
      (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2032
      JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2033
      JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2034
      defined(_Static_assert) \
2035
    )
2036
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2037
#elif \
2038
  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2039
  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2040
  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2041
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2042
#else
2043
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2044
#endif
2045
2046
#if defined(JSON_HEDLEY_NULL)
2047
    #undef JSON_HEDLEY_NULL
2048
#endif
2049
#if defined(__cplusplus)
2050
    #if __cplusplus >= 201103L
2051
        #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2052
    #elif defined(NULL)
2053
        #define JSON_HEDLEY_NULL NULL
2054
    #else
2055
        #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2056
    #endif
2057
#elif defined(NULL)
2058
    #define JSON_HEDLEY_NULL NULL
2059
#else
2060
    #define JSON_HEDLEY_NULL ((void*) 0)
2061
#endif
2062
2063
#if defined(JSON_HEDLEY_MESSAGE)
2064
    #undef JSON_HEDLEY_MESSAGE
2065
#endif
2066
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2067
#  define JSON_HEDLEY_MESSAGE(msg) \
2068
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2069
    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2070
    JSON_HEDLEY_PRAGMA(message msg) \
2071
    JSON_HEDLEY_DIAGNOSTIC_POP
2072
#elif \
2073
  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2074
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2075
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2076
#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2077
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2078
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2079
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2080
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2081
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2082
#else
2083
#  define JSON_HEDLEY_MESSAGE(msg)
2084
#endif
2085
2086
#if defined(JSON_HEDLEY_WARNING)
2087
    #undef JSON_HEDLEY_WARNING
2088
#endif
2089
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2090
#  define JSON_HEDLEY_WARNING(msg) \
2091
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2092
    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2093
    JSON_HEDLEY_PRAGMA(clang warning msg) \
2094
    JSON_HEDLEY_DIAGNOSTIC_POP
2095
#elif \
2096
  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2097
  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2098
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2099
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2100
#elif \
2101
  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2102
  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2103
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2104
#else
2105
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2106
#endif
2107
2108
#if defined(JSON_HEDLEY_REQUIRE)
2109
    #undef JSON_HEDLEY_REQUIRE
2110
#endif
2111
#if defined(JSON_HEDLEY_REQUIRE_MSG)
2112
    #undef JSON_HEDLEY_REQUIRE_MSG
2113
#endif
2114
#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2115
#  if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2116
#    define JSON_HEDLEY_REQUIRE(expr) \
2117
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2118
    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2119
    __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2120
    JSON_HEDLEY_DIAGNOSTIC_POP
2121
#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2122
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
2123
    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2124
    __attribute__((diagnose_if(!(expr), msg, "error"))) \
2125
    JSON_HEDLEY_DIAGNOSTIC_POP
2126
#  else
2127
#    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2128
#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2129
#  endif
2130
#else
2131
#  define JSON_HEDLEY_REQUIRE(expr)
2132
#  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2133
#endif
2134
2135
#if defined(JSON_HEDLEY_FLAGS)
2136
    #undef JSON_HEDLEY_FLAGS
2137
#endif
2138
#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2139
    #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2140
#else
2141
    #define JSON_HEDLEY_FLAGS
2142
#endif
2143
2144
#if defined(JSON_HEDLEY_FLAGS_CAST)
2145
    #undef JSON_HEDLEY_FLAGS_CAST
2146
#endif
2147
#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2148
#  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2149
        JSON_HEDLEY_DIAGNOSTIC_PUSH \
2150
        _Pragma("warning(disable:188)") \
2151
        ((T) (expr)); \
2152
        JSON_HEDLEY_DIAGNOSTIC_POP \
2153
    }))
2154
#else
2155
#  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2156
#endif
2157
2158
#if defined(JSON_HEDLEY_EMPTY_BASES)
2159
    #undef JSON_HEDLEY_EMPTY_BASES
2160
#endif
2161
#if \
2162
    (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2163
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2164
    #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2165
#else
2166
    #define JSON_HEDLEY_EMPTY_BASES
2167
#endif
2168
2169
/* Remaining macros are deprecated. */
2170
2171
#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2172
    #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2173
#endif
2174
#if defined(__clang__)
2175
    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2176
#else
2177
    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2178
#endif
2179
2180
#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2181
    #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2182
#endif
2183
#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2184
2185
#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2186
    #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2187
#endif
2188
#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2189
2190
#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2191
    #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2192
#endif
2193
#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2194
2195
#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2196
    #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2197
#endif
2198
#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2199
2200
#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2201
    #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2202
#endif
2203
#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2204
2205
#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2206
    #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2207
#endif
2208
#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2209
2210
#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2211
    #undef JSON_HEDLEY_CLANG_HAS_WARNING
2212
#endif
2213
#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2214
2215
#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2216
2217
// #include <nlohmann/detail/meta/detected.hpp>
2218
2219
2220
#include <type_traits>
2221
2222
// #include <nlohmann/detail/meta/void_t.hpp>
2223
2224
2225
namespace nlohmann
2226
{
2227
namespace detail
2228
{
2229
template<typename ...Ts> struct make_void
2230
{
2231
    using type = void;
2232
};
2233
template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2234
} // namespace detail
2235
}  // namespace nlohmann
2236
2237
2238
// https://en.cppreference.com/w/cpp/experimental/is_detected
2239
namespace nlohmann
2240
{
2241
namespace detail
2242
{
2243
struct nonesuch
2244
{
2245
    nonesuch() = delete;
2246
    ~nonesuch() = delete;
2247
    nonesuch(nonesuch const&) = delete;
2248
    nonesuch(nonesuch const&&) = delete;
2249
    void operator=(nonesuch const&) = delete;
2250
    void operator=(nonesuch&&) = delete;
2251
};
2252
2253
template<class Default,
2254
         class AlwaysVoid,
2255
         template<class...> class Op,
2256
         class... Args>
2257
struct detector
2258
{
2259
    using value_t = std::false_type;
2260
    using type = Default;
2261
};
2262
2263
template<class Default, template<class...> class Op, class... Args>
2264
struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2265
{
2266
    using value_t = std::true_type;
2267
    using type = Op<Args...>;
2268
};
2269
2270
template<template<class...> class Op, class... Args>
2271
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2272
2273
template<template<class...> class Op, class... Args>
2274
struct is_detected_lazy : is_detected<Op, Args...> { };
2275
2276
template<template<class...> class Op, class... Args>
2277
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2278
2279
template<class Default, template<class...> class Op, class... Args>
2280
using detected_or = detector<Default, void, Op, Args...>;
2281
2282
template<class Default, template<class...> class Op, class... Args>
2283
using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2284
2285
template<class Expected, template<class...> class Op, class... Args>
2286
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2287
2288
template<class To, template<class...> class Op, class... Args>
2289
using is_detected_convertible =
2290
    std::is_convertible<detected_t<Op, Args...>, To>;
2291
}  // namespace detail
2292
}  // namespace nlohmann
2293
2294
2295
// This file contains all internal macro definitions
2296
// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2297
2298
// exclude unsupported compilers
2299
#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2300
    #if defined(__clang__)
2301
        #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2302
            #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2303
        #endif
2304
    #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2305
        #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2306
            #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2307
        #endif
2308
    #endif
2309
#endif
2310
2311
// C++ language standard detection
2312
// if the user manually specified the used c++ version this is skipped
2313
#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2314
    #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2315
        #define JSON_HAS_CPP_20
2316
        #define JSON_HAS_CPP_17
2317
        #define JSON_HAS_CPP_14
2318
    #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2319
        #define JSON_HAS_CPP_17
2320
        #define JSON_HAS_CPP_14
2321
    #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2322
        #define JSON_HAS_CPP_14
2323
    #endif
2324
    // the cpp 11 flag is always specified because it is the minimal required version
2325
    #define JSON_HAS_CPP_11
2326
#endif
2327
2328
// disable documentation warnings on clang
2329
#if defined(__clang__)
2330
    #pragma clang diagnostic push
2331
    #pragma clang diagnostic ignored "-Wdocumentation"
2332
    #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2333
#endif
2334
2335
// allow to disable exceptions
2336
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2337
214
    #define JSON_THROW(exception) throw exception
2338
    #define JSON_TRY try
2339
    #define JSON_CATCH(exception) catch(exception)
2340
    #define JSON_INTERNAL_CATCH(exception) catch(exception)
2341
#else
2342
    #include <cstdlib>
2343
    #define JSON_THROW(exception) std::abort()
2344
    #define JSON_TRY if(true)
2345
    #define JSON_CATCH(exception) if(false)
2346
    #define JSON_INTERNAL_CATCH(exception) if(false)
2347
#endif
2348
2349
// override exception macros
2350
#if defined(JSON_THROW_USER)
2351
    #undef JSON_THROW
2352
    #define JSON_THROW JSON_THROW_USER
2353
#endif
2354
#if defined(JSON_TRY_USER)
2355
    #undef JSON_TRY
2356
    #define JSON_TRY JSON_TRY_USER
2357
#endif
2358
#if defined(JSON_CATCH_USER)
2359
    #undef JSON_CATCH
2360
    #define JSON_CATCH JSON_CATCH_USER
2361
    #undef JSON_INTERNAL_CATCH
2362
    #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2363
#endif
2364
#if defined(JSON_INTERNAL_CATCH_USER)
2365
    #undef JSON_INTERNAL_CATCH
2366
    #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2367
#endif
2368
2369
// allow to override assert
2370
#if !defined(JSON_ASSERT)
2371
    #include <cassert> // assert
2372
0
    #define JSON_ASSERT(x) assert(x)
2373
#endif
2374
2375
// allow to access some private functions (needed by the test suite)
2376
#if defined(JSON_TESTS_PRIVATE)
2377
    #define JSON_PRIVATE_UNLESS_TESTED public
2378
#else
2379
    #define JSON_PRIVATE_UNLESS_TESTED private
2380
#endif
2381
2382
/*!
2383
@brief macro to briefly define a mapping between an enum and JSON
2384
@def NLOHMANN_JSON_SERIALIZE_ENUM
2385
@since version 3.4.0
2386
*/
2387
#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \
2388
    template<typename BasicJsonType>                                                            \
2389
    inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
2390
    {                                                                                           \
2391
        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2392
        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2393
        auto it = std::find_if(std::begin(m), std::end(m),                                      \
2394
                               [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
2395
        {                                                                                       \
2396
            return ej_pair.first == e;                                                          \
2397
        });                                                                                     \
2398
        j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
2399
    }                                                                                           \
2400
    template<typename BasicJsonType>                                                            \
2401
    inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
2402
    {                                                                                           \
2403
        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2404
        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2405
        auto it = std::find_if(std::begin(m), std::end(m),                                      \
2406
                               [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2407
        {                                                                                       \
2408
            return ej_pair.second == j;                                                         \
2409
        });                                                                                     \
2410
        e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
2411
    }
2412
2413
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2414
// may be removed in the future once the class is split.
2415
2416
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
2417
    template<template<typename, typename, typename...> class ObjectType,   \
2418
             template<typename, typename...> class ArrayType,              \
2419
             class StringType, class BooleanType, class NumberIntegerType, \
2420
             class NumberUnsignedType, class NumberFloatType,              \
2421
             template<typename> class AllocatorType,                       \
2422
             template<typename, typename = void> class JSONSerializer,     \
2423
             class BinaryType>
2424
2425
#define NLOHMANN_BASIC_JSON_TPL                                            \
2426
    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
2427
    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
2428
    AllocatorType, JSONSerializer, BinaryType>
2429
2430
// Macros to simplify conversion from/to types
2431
2432
#define NLOHMANN_JSON_EXPAND( x ) x
2433
#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2434
#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2435
        NLOHMANN_JSON_PASTE64, \
2436
        NLOHMANN_JSON_PASTE63, \
2437
        NLOHMANN_JSON_PASTE62, \
2438
        NLOHMANN_JSON_PASTE61, \
2439
        NLOHMANN_JSON_PASTE60, \
2440
        NLOHMANN_JSON_PASTE59, \
2441
        NLOHMANN_JSON_PASTE58, \
2442
        NLOHMANN_JSON_PASTE57, \
2443
        NLOHMANN_JSON_PASTE56, \
2444
        NLOHMANN_JSON_PASTE55, \
2445
        NLOHMANN_JSON_PASTE54, \
2446
        NLOHMANN_JSON_PASTE53, \
2447
        NLOHMANN_JSON_PASTE52, \
2448
        NLOHMANN_JSON_PASTE51, \
2449
        NLOHMANN_JSON_PASTE50, \
2450
        NLOHMANN_JSON_PASTE49, \
2451
        NLOHMANN_JSON_PASTE48, \
2452
        NLOHMANN_JSON_PASTE47, \
2453
        NLOHMANN_JSON_PASTE46, \
2454
        NLOHMANN_JSON_PASTE45, \
2455
        NLOHMANN_JSON_PASTE44, \
2456
        NLOHMANN_JSON_PASTE43, \
2457
        NLOHMANN_JSON_PASTE42, \
2458
        NLOHMANN_JSON_PASTE41, \
2459
        NLOHMANN_JSON_PASTE40, \
2460
        NLOHMANN_JSON_PASTE39, \
2461
        NLOHMANN_JSON_PASTE38, \
2462
        NLOHMANN_JSON_PASTE37, \
2463
        NLOHMANN_JSON_PASTE36, \
2464
        NLOHMANN_JSON_PASTE35, \
2465
        NLOHMANN_JSON_PASTE34, \
2466
        NLOHMANN_JSON_PASTE33, \
2467
        NLOHMANN_JSON_PASTE32, \
2468
        NLOHMANN_JSON_PASTE31, \
2469
        NLOHMANN_JSON_PASTE30, \
2470
        NLOHMANN_JSON_PASTE29, \
2471
        NLOHMANN_JSON_PASTE28, \
2472
        NLOHMANN_JSON_PASTE27, \
2473
        NLOHMANN_JSON_PASTE26, \
2474
        NLOHMANN_JSON_PASTE25, \
2475
        NLOHMANN_JSON_PASTE24, \
2476
        NLOHMANN_JSON_PASTE23, \
2477
        NLOHMANN_JSON_PASTE22, \
2478
        NLOHMANN_JSON_PASTE21, \
2479
        NLOHMANN_JSON_PASTE20, \
2480
        NLOHMANN_JSON_PASTE19, \
2481
        NLOHMANN_JSON_PASTE18, \
2482
        NLOHMANN_JSON_PASTE17, \
2483
        NLOHMANN_JSON_PASTE16, \
2484
        NLOHMANN_JSON_PASTE15, \
2485
        NLOHMANN_JSON_PASTE14, \
2486
        NLOHMANN_JSON_PASTE13, \
2487
        NLOHMANN_JSON_PASTE12, \
2488
        NLOHMANN_JSON_PASTE11, \
2489
        NLOHMANN_JSON_PASTE10, \
2490
        NLOHMANN_JSON_PASTE9, \
2491
        NLOHMANN_JSON_PASTE8, \
2492
        NLOHMANN_JSON_PASTE7, \
2493
        NLOHMANN_JSON_PASTE6, \
2494
        NLOHMANN_JSON_PASTE5, \
2495
        NLOHMANN_JSON_PASTE4, \
2496
        NLOHMANN_JSON_PASTE3, \
2497
        NLOHMANN_JSON_PASTE2, \
2498
        NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2499
#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2500
#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2501
#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2502
#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2503
#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2504
#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2505
#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2506
#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2507
#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2508
#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2509
#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2510
#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2511
#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2512
#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2513
#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2514
#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2515
#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2516
#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2517
#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2518
#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2519
#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2520
#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2521
#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2522
#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2523
#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2524
#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2525
#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2526
#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2527
#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2528
#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2529
#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2530
#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2531
#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2532
#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2533
#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2534
#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2535
#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2536
#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2537
#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2538
#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2539
#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2540
#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2541
#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2542
#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2543
#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2544
#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2545
#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2546
#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2547
#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2548
#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2549
#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2550
#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2551
#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2552
#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2553
#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2554
#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2555
#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2556
#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2557
#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2558
#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2559
#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2560
#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2561
#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2562
2563
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2564
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2565
2566
/*!
2567
@brief macro
2568
@def NLOHMANN_DEFINE_TYPE_INTRUSIVE
2569
@since version 3.9.0
2570
*/
2571
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \
2572
    friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2573
    friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2574
2575
/*!
2576
@brief macro
2577
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
2578
@since version 3.9.0
2579
*/
2580
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \
2581
    inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2582
    inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2583
2584
2585
// inspired from https://stackoverflow.com/a/26745591
2586
// allows to call any std function as if (e.g. with begin):
2587
// using std::begin; begin(x);
2588
//
2589
// it allows using the detected idiom to retrieve the return type
2590
// of such an expression
2591
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)                                 \
2592
    namespace detail {                                                            \
2593
    using std::std_name;                                                          \
2594
    \
2595
    template<typename... T>                                                       \
2596
    using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \
2597
    }                                                                             \
2598
    \
2599
    namespace detail2 {                                                           \
2600
    struct std_name##_tag                                                         \
2601
    {                                                                             \
2602
    };                                                                            \
2603
    \
2604
    template<typename... T>                                                       \
2605
    std_name##_tag std_name(T&&...);                                              \
2606
    \
2607
    template<typename... T>                                                       \
2608
    using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \
2609
    \
2610
    template<typename... T>                                                       \
2611
    struct would_call_std_##std_name                                              \
2612
    {                                                                             \
2613
        static constexpr auto const value = ::nlohmann::detail::                  \
2614
                                            is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2615
    };                                                                            \
2616
    } /* namespace detail2 */ \
2617
    \
2618
    template<typename... T>                                                       \
2619
    struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...>   \
2620
    {                                                                             \
2621
    }
2622
2623
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2624
    #define JSON_USE_IMPLICIT_CONVERSIONS 1
2625
#endif
2626
2627
#if JSON_USE_IMPLICIT_CONVERSIONS
2628
    #define JSON_EXPLICIT
2629
#else
2630
    #define JSON_EXPLICIT explicit
2631
#endif
2632
2633
#ifndef JSON_DIAGNOSTICS
2634
    #define JSON_DIAGNOSTICS 0
2635
#endif
2636
2637
2638
namespace nlohmann
2639
{
2640
namespace detail
2641
{
2642
2643
/*!
2644
@brief replace all occurrences of a substring by another string
2645
2646
@param[in,out] s  the string to manipulate; changed so that all
2647
               occurrences of @a f are replaced with @a t
2648
@param[in]     f  the substring to replace with @a t
2649
@param[in]     t  the string to replace @a f
2650
2651
@pre The search string @a f must not be empty. **This precondition is
2652
enforced with an assertion.**
2653
2654
@since version 2.0.0
2655
*/
2656
inline void replace_substring(std::string& s, const std::string& f,
2657
                              const std::string& t)
2658
0
{
2659
0
    JSON_ASSERT(!f.empty());
2660
0
    for (auto pos = s.find(f);                // find first occurrence of f
2661
0
            pos != std::string::npos;         // make sure f was found
2662
0
            s.replace(pos, f.size(), t),      // replace with t, and
2663
0
            pos = s.find(f, pos + t.size()))  // find next occurrence of f
2664
0
    {}
2665
0
}
2666
2667
/*!
2668
 * @brief string escaping as described in RFC 6901 (Sect. 4)
2669
 * @param[in] s string to escape
2670
 * @return    escaped string
2671
 *
2672
 * Note the order of escaping "~" to "~0" and "/" to "~1" is important.
2673
 */
2674
inline std::string escape(std::string s)
2675
0
{
2676
0
    replace_substring(s, "~", "~0");
2677
0
    replace_substring(s, "/", "~1");
2678
0
    return s;
2679
0
}
2680
2681
/*!
2682
 * @brief string unescaping as described in RFC 6901 (Sect. 4)
2683
 * @param[in] s string to unescape
2684
 * @return    unescaped string
2685
 *
2686
 * Note the order of escaping "~1" to "/" and "~0" to "~" is important.
2687
 */
2688
static void unescape(std::string& s)
2689
0
{
2690
0
    replace_substring(s, "~1", "/");
2691
0
    replace_substring(s, "~0", "~");
2692
0
}
2693
2694
} // namespace detail
2695
} // namespace nlohmann
2696
2697
// #include <nlohmann/detail/input/position_t.hpp>
2698
2699
2700
#include <cstddef> // size_t
2701
2702
namespace nlohmann
2703
{
2704
namespace detail
2705
{
2706
/// struct to capture the start position of the current token
2707
struct position_t
2708
{
2709
    /// the total number of characters read
2710
    std::size_t chars_read_total = 0;
2711
    /// the number of characters read in the current line
2712
    std::size_t chars_read_current_line = 0;
2713
    /// the number of lines read
2714
    std::size_t lines_read = 0;
2715
2716
    /// conversion to size_t to preserve SAX interface
2717
    constexpr operator size_t() const
2718
214
    {
2719
214
        return chars_read_total;
2720
214
    }
2721
};
2722
2723
} // namespace detail
2724
} // namespace nlohmann
2725
2726
// #include <nlohmann/detail/macro_scope.hpp>
2727
2728
2729
namespace nlohmann
2730
{
2731
namespace detail
2732
{
2733
////////////////
2734
// exceptions //
2735
////////////////
2736
2737
/*!
2738
@brief general exception of the @ref basic_json class
2739
2740
This class is an extension of `std::exception` objects with a member @a id for
2741
exception ids. It is used as the base class for all exceptions thrown by the
2742
@ref basic_json class. This class can hence be used as "wildcard" to catch
2743
exceptions.
2744
2745
Subclasses:
2746
- @ref parse_error for exceptions indicating a parse error
2747
- @ref invalid_iterator for exceptions indicating errors with iterators
2748
- @ref type_error for exceptions indicating executing a member function with
2749
                  a wrong type
2750
- @ref out_of_range for exceptions indicating access out of the defined range
2751
- @ref other_error for exceptions indicating other library errors
2752
2753
@internal
2754
@note To have nothrow-copy-constructible exceptions, we internally use
2755
      `std::runtime_error` which can cope with arbitrary-length error messages.
2756
      Intermediate strings are built with static functions and then passed to
2757
      the actual constructor.
2758
@endinternal
2759
2760
@liveexample{The following code shows how arbitrary library exceptions can be
2761
caught.,exception}
2762
2763
@since version 3.0.0
2764
*/
2765
class exception : public std::exception
2766
{
2767
  public:
2768
    /// returns the explanatory string
2769
    const char* what() const noexcept override
2770
214
    {
2771
214
        return m.what();
2772
214
    }
2773
2774
    /// the id of the exception
2775
    const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2776
2777
  protected:
2778
    JSON_HEDLEY_NON_NULL(3)
2779
214
    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2780
2781
    static std::string name(const std::string& ename, int id_)
2782
214
    {
2783
214
        return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2784
214
    }
2785
2786
    template<typename BasicJsonType>
2787
    static std::string diagnostics(const BasicJsonType& leaf_element)
2788
214
    {
2789
#if JSON_DIAGNOSTICS
2790
        std::vector<std::string> tokens;
2791
        for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2792
        {
2793
            switch (current->m_parent->type())
2794
            {
2795
                case value_t::array:
2796
                {
2797
                    for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2798
                    {
2799
                        if (&current->m_parent->m_value.array->operator[](i) == current)
2800
                        {
2801
                            tokens.emplace_back(std::to_string(i));
2802
                            break;
2803
                        }
2804
                    }
2805
                    break;
2806
                }
2807
2808
                case value_t::object:
2809
                {
2810
                    for (const auto& element : *current->m_parent->m_value.object)
2811
                    {
2812
                        if (&element.second == current)
2813
                        {
2814
                            tokens.emplace_back(element.first.c_str());
2815
                            break;
2816
                        }
2817
                    }
2818
                    break;
2819
                }
2820
2821
                case value_t::null: // LCOV_EXCL_LINE
2822
                case value_t::string: // LCOV_EXCL_LINE
2823
                case value_t::boolean: // LCOV_EXCL_LINE
2824
                case value_t::number_integer: // LCOV_EXCL_LINE
2825
                case value_t::number_unsigned: // LCOV_EXCL_LINE
2826
                case value_t::number_float: // LCOV_EXCL_LINE
2827
                case value_t::binary: // LCOV_EXCL_LINE
2828
                case value_t::discarded: // LCOV_EXCL_LINE
2829
                default:   // LCOV_EXCL_LINE
2830
                    break; // LCOV_EXCL_LINE
2831
            }
2832
        }
2833
2834
        if (tokens.empty())
2835
        {
2836
            return "";
2837
        }
2838
2839
        return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2840
                                     [](const std::string & a, const std::string & b)
2841
        {
2842
            return a + "/" + detail::escape(b);
2843
        }) + ") ";
2844
#else
2845
214
        static_cast<void>(leaf_element);
2846
214
        return "";
2847
214
#endif
2848
214
    }
2849
2850
  private:
2851
    /// an exception object as storage for error messages
2852
    std::runtime_error m;
2853
};
2854
2855
/*!
2856
@brief exception indicating a parse error
2857
2858
This exception is thrown by the library when a parse error occurs. Parse errors
2859
can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2860
as when using JSON Patch.
2861
2862
Member @a byte holds the byte index of the last read character in the input
2863
file.
2864
2865
Exceptions have ids 1xx.
2866
2867
name / id                      | example message | description
2868
------------------------------ | --------------- | -------------------------
2869
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.
2870
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.
2871
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.
2872
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.
2873
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.
2874
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`.
2875
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.
2876
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.
2877
json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2878
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.
2879
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.
2880
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.
2881
json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2882
json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed.
2883
2884
@note For an input with n bytes, 1 is the index of the first character and n+1
2885
      is the index of the terminating null byte or the end of file. This also
2886
      holds true when reading a byte vector (CBOR or MessagePack).
2887
2888
@liveexample{The following code shows how a `parse_error` exception can be
2889
caught.,parse_error}
2890
2891
@sa - @ref exception for the base class of the library exceptions
2892
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2893
@sa - @ref type_error for exceptions indicating executing a member function with
2894
                    a wrong type
2895
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2896
@sa - @ref other_error for exceptions indicating other library errors
2897
2898
@since version 3.0.0
2899
*/
2900
class parse_error : public exception
2901
{
2902
  public:
2903
    /*!
2904
    @brief create a parse error exception
2905
    @param[in] id_       the id of the exception
2906
    @param[in] pos       the position where the error occurred (or with
2907
                         chars_read_total=0 if the position cannot be
2908
                         determined)
2909
    @param[in] what_arg  the explanatory string
2910
    @return parse_error object
2911
    */
2912
    template<typename BasicJsonType>
2913
    static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2914
210
    {
2915
210
        std::string w = exception::name("parse_error", id_) + "parse error" +
2916
210
                        position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2917
210
        return parse_error(id_, pos.chars_read_total, w.c_str());
2918
210
    }
2919
2920
    template<typename BasicJsonType>
2921
    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2922
0
    {
2923
0
        std::string w = exception::name("parse_error", id_) + "parse error" +
2924
0
                        (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2925
0
                        ": " + exception::diagnostics(context) + what_arg;
2926
0
        return parse_error(id_, byte_, w.c_str());
2927
0
    }
2928
2929
    /*!
2930
    @brief byte index of the parse error
2931
2932
    The byte index of the last read character in the input file.
2933
2934
    @note For an input with n bytes, 1 is the index of the first character and
2935
          n+1 is the index of the terminating null byte or the end of file.
2936
          This also holds true when reading a byte vector (CBOR or MessagePack).
2937
    */
2938
    const std::size_t byte;
2939
2940
  private:
2941
    parse_error(int id_, std::size_t byte_, const char* what_arg)
2942
210
        : exception(id_, what_arg), byte(byte_) {}
2943
2944
    static std::string position_string(const position_t& pos)
2945
210
    {
2946
210
        return " at line " + std::to_string(pos.lines_read + 1) +
2947
210
               ", column " + std::to_string(pos.chars_read_current_line);
2948
210
    }
2949
};
2950
2951
/*!
2952
@brief exception indicating errors with iterators
2953
2954
This exception is thrown if iterators passed to a library function do not match
2955
the expected semantics.
2956
2957
Exceptions have ids 2xx.
2958
2959
name / id                           | example message | description
2960
----------------------------------- | --------------- | -------------------------
2961
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.
2962
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.
2963
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.
2964
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.
2965
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.
2966
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.
2967
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.
2968
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.
2969
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.
2970
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.
2971
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.
2972
json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2973
json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2974
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().
2975
2976
@liveexample{The following code shows how an `invalid_iterator` exception can be
2977
caught.,invalid_iterator}
2978
2979
@sa - @ref exception for the base class of the library exceptions
2980
@sa - @ref parse_error for exceptions indicating a parse error
2981
@sa - @ref type_error for exceptions indicating executing a member function with
2982
                    a wrong type
2983
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2984
@sa - @ref other_error for exceptions indicating other library errors
2985
2986
@since version 3.0.0
2987
*/
2988
class invalid_iterator : public exception
2989
{
2990
  public:
2991
    template<typename BasicJsonType>
2992
    static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2993
0
    {
2994
0
        std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2995
0
        return invalid_iterator(id_, w.c_str());
2996
0
    }
2997
2998
  private:
2999
    JSON_HEDLEY_NON_NULL(3)
3000
    invalid_iterator(int id_, const char* what_arg)
3001
0
        : exception(id_, what_arg) {}
3002
};
3003
3004
/*!
3005
@brief exception indicating executing a member function with a wrong type
3006
3007
This exception is thrown in case of a type error; that is, a library function is
3008
executed on a JSON value whose type does not match the expected semantics.
3009
3010
Exceptions have ids 3xx.
3011
3012
name / id                     | example message | description
3013
----------------------------- | --------------- | -------------------------
3014
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.
3015
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.
3016
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 &.
3017
json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
3018
json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
3019
json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
3020
json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
3021
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.
3022
json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
3023
json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
3024
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.
3025
json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
3026
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.
3027
json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
3028
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.
3029
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. |
3030
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) |
3031
3032
@liveexample{The following code shows how a `type_error` exception can be
3033
caught.,type_error}
3034
3035
@sa - @ref exception for the base class of the library exceptions
3036
@sa - @ref parse_error for exceptions indicating a parse error
3037
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
3038
@sa - @ref out_of_range for exceptions indicating access out of the defined range
3039
@sa - @ref other_error for exceptions indicating other library errors
3040
3041
@since version 3.0.0
3042
*/
3043
class type_error : public exception
3044
{
3045
  public:
3046
    template<typename BasicJsonType>
3047
    static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3048
0
    {
3049
0
        std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
3050
0
        return type_error(id_, w.c_str());
3051
0
    }
3052
3053
  private:
3054
    JSON_HEDLEY_NON_NULL(3)
3055
0
    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3056
};
3057
3058
/*!
3059
@brief exception indicating access out of the defined range
3060
3061
This exception is thrown in case a library function is called on an input
3062
parameter that exceeds the expected range, for instance in case of array
3063
indices or nonexisting object keys.
3064
3065
Exceptions have ids 4xx.
3066
3067
name / id                       | example message | description
3068
------------------------------- | --------------- | -------------------------
3069
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.
3070
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.
3071
json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
3072
json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
3073
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.
3074
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.
3075
json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) |
3076
json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
3077
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 |
3078
3079
@liveexample{The following code shows how an `out_of_range` exception can be
3080
caught.,out_of_range}
3081
3082
@sa - @ref exception for the base class of the library exceptions
3083
@sa - @ref parse_error for exceptions indicating a parse error
3084
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
3085
@sa - @ref type_error for exceptions indicating executing a member function with
3086
                    a wrong type
3087
@sa - @ref other_error for exceptions indicating other library errors
3088
3089
@since version 3.0.0
3090
*/
3091
class out_of_range : public exception
3092
{
3093
  public:
3094
    template<typename BasicJsonType>
3095
    static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
3096
4
    {
3097
4
        std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
3098
4
        return out_of_range(id_, w.c_str());
3099
4
    }
3100
3101
  private:
3102
    JSON_HEDLEY_NON_NULL(3)
3103
4
    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
3104
};
3105
3106
/*!
3107
@brief exception indicating other library errors
3108
3109
This exception is thrown in case of errors that cannot be classified with the
3110
other exception types.
3111
3112
Exceptions have ids 5xx.
3113
3114
name / id                      | example message | description
3115
------------------------------ | --------------- | -------------------------
3116
json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
3117
3118
@sa - @ref exception for the base class of the library exceptions
3119
@sa - @ref parse_error for exceptions indicating a parse error
3120
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
3121
@sa - @ref type_error for exceptions indicating executing a member function with
3122
                    a wrong type
3123
@sa - @ref out_of_range for exceptions indicating access out of the defined range
3124
3125
@liveexample{The following code shows how an `other_error` exception can be
3126
caught.,other_error}
3127
3128
@since version 3.0.0
3129
*/
3130
class other_error : public exception
3131
{
3132
  public:
3133
    template<typename BasicJsonType>
3134
    static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3135
0
    {
3136
0
        std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3137
0
        return other_error(id_, w.c_str());
3138
0
    }
3139
3140
  private:
3141
    JSON_HEDLEY_NON_NULL(3)
3142
0
    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3143
};
3144
}  // namespace detail
3145
}  // namespace nlohmann
3146
3147
// #include <nlohmann/detail/macro_scope.hpp>
3148
3149
// #include <nlohmann/detail/meta/cpp_future.hpp>
3150
3151
3152
#include <cstddef> // size_t
3153
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3154
#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3155
3156
// #include <nlohmann/detail/macro_scope.hpp>
3157
3158
3159
namespace nlohmann
3160
{
3161
namespace detail
3162
{
3163
3164
template<typename T>
3165
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3166
3167
#ifdef JSON_HAS_CPP_14
3168
3169
// the following utilities are natively available in C++14
3170
using std::enable_if_t;
3171
using std::index_sequence;
3172
using std::make_index_sequence;
3173
using std::index_sequence_for;
3174
3175
#else
3176
3177
// alias templates to reduce boilerplate
3178
template<bool B, typename T = void>
3179
using enable_if_t = typename std::enable_if<B, T>::type;
3180
3181
// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3182
// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3183
3184
//// START OF CODE FROM GOOGLE ABSEIL
3185
3186
// integer_sequence
3187
//
3188
// Class template representing a compile-time integer sequence. An instantiation
3189
// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3190
// type through its template arguments (which is a common need when
3191
// working with C++11 variadic templates). `absl::integer_sequence` is designed
3192
// to be a drop-in replacement for C++14's `std::integer_sequence`.
3193
//
3194
// Example:
3195
//
3196
//   template< class T, T... Ints >
3197
//   void user_function(integer_sequence<T, Ints...>);
3198
//
3199
//   int main()
3200
//   {
3201
//     // user_function's `T` will be deduced to `int` and `Ints...`
3202
//     // will be deduced to `0, 1, 2, 3, 4`.
3203
//     user_function(make_integer_sequence<int, 5>());
3204
//   }
3205
template <typename T, T... Ints>
3206
struct integer_sequence
3207
{
3208
    using value_type = T;
3209
    static constexpr std::size_t size() noexcept
3210
    {
3211
        return sizeof...(Ints);
3212
    }
3213
};
3214
3215
// index_sequence
3216
//
3217
// A helper template for an `integer_sequence` of `size_t`,
3218
// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3219
// `std::index_sequence`.
3220
template <size_t... Ints>
3221
using index_sequence = integer_sequence<size_t, Ints...>;
3222
3223
namespace utility_internal
3224
{
3225
3226
template <typename Seq, size_t SeqSize, size_t Rem>
3227
struct Extend;
3228
3229
// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3230
template <typename T, T... Ints, size_t SeqSize>
3231
struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3232
{
3233
    using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3234
};
3235
3236
template <typename T, T... Ints, size_t SeqSize>
3237
struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3238
{
3239
    using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3240
};
3241
3242
// Recursion helper for 'make_integer_sequence<T, N>'.
3243
// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3244
template <typename T, size_t N>
3245
struct Gen
3246
{
3247
    using type =
3248
        typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3249
};
3250
3251
template <typename T>
3252
struct Gen<T, 0>
3253
{
3254
    using type = integer_sequence<T>;
3255
};
3256
3257
}  // namespace utility_internal
3258
3259
// Compile-time sequences of integers
3260
3261
// make_integer_sequence
3262
//
3263
// This template alias is equivalent to
3264
// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3265
// replacement for C++14's `std::make_integer_sequence`.
3266
template <typename T, T N>
3267
using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3268
3269
// make_index_sequence
3270
//
3271
// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3272
// and is designed to be a drop-in replacement for C++14's
3273
// `std::make_index_sequence`.
3274
template <size_t N>
3275
using make_index_sequence = make_integer_sequence<size_t, N>;
3276
3277
// index_sequence_for
3278
//
3279
// Converts a typename pack into an index sequence of the same length, and
3280
// is designed to be a drop-in replacement for C++14's
3281
// `std::index_sequence_for()`
3282
template <typename... Ts>
3283
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3284
3285
//// END OF CODE FROM GOOGLE ABSEIL
3286
3287
#endif
3288
3289
// dispatch utility (taken from ranges-v3)
3290
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3291
template<> struct priority_tag<0> {};
3292
3293
// taken from ranges-v3
3294
template<typename T>
3295
struct static_const
3296
{
3297
    static constexpr T value{};
3298
};
3299
3300
template<typename T>
3301
constexpr T static_const<T>::value;
3302
3303
}  // namespace detail
3304
}  // namespace nlohmann
3305
3306
// #include <nlohmann/detail/meta/identity_tag.hpp>
3307
3308
3309
namespace nlohmann
3310
{
3311
namespace detail
3312
{
3313
// dispatching helper struct
3314
template <class T> struct identity_tag {};
3315
}  // namespace detail
3316
}  // namespace nlohmann
3317
3318
// #include <nlohmann/detail/meta/type_traits.hpp>
3319
3320
3321
#include <limits> // numeric_limits
3322
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3323
#include <utility> // declval
3324
#include <tuple> // tuple
3325
3326
// #include <nlohmann/detail/macro_scope.hpp>
3327
3328
3329
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3330
3331
3332
#include <iterator> // random_access_iterator_tag
3333
3334
// #include <nlohmann/detail/meta/void_t.hpp>
3335
3336
// #include <nlohmann/detail/meta/cpp_future.hpp>
3337
3338
3339
namespace nlohmann
3340
{
3341
namespace detail
3342
{
3343
template<typename It, typename = void>
3344
struct iterator_types {};
3345
3346
template<typename It>
3347
struct iterator_types <
3348
    It,
3349
    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3350
    typename It::reference, typename It::iterator_category >>
3351
{
3352
    using difference_type = typename It::difference_type;
3353
    using value_type = typename It::value_type;
3354
    using pointer = typename It::pointer;
3355
    using reference = typename It::reference;
3356
    using iterator_category = typename It::iterator_category;
3357
};
3358
3359
// This is required as some compilers implement std::iterator_traits in a way that
3360
// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3361
template<typename T, typename = void>
3362
struct iterator_traits
3363
{
3364
};
3365
3366
template<typename T>
3367
struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3368
            : iterator_types<T>
3369
{
3370
};
3371
3372
template<typename T>
3373
struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
3374
{
3375
    using iterator_category = std::random_access_iterator_tag;
3376
    using value_type = T;
3377
    using difference_type = ptrdiff_t;
3378
    using pointer = T*;
3379
    using reference = T&;
3380
};
3381
} // namespace detail
3382
} // namespace nlohmann
3383
3384
// #include <nlohmann/detail/meta/call_std/begin.hpp>
3385
3386
3387
// #include <nlohmann/detail/macro_scope.hpp>
3388
3389
3390
namespace nlohmann
3391
{
3392
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);
3393
} // namespace nlohmann
3394
3395
// #include <nlohmann/detail/meta/call_std/end.hpp>
3396
3397
3398
// #include <nlohmann/detail/macro_scope.hpp>
3399
3400
3401
namespace nlohmann
3402
{
3403
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);
3404
}  // namespace nlohmann
3405
3406
// #include <nlohmann/detail/meta/cpp_future.hpp>
3407
3408
// #include <nlohmann/detail/meta/detected.hpp>
3409
3410
// #include <nlohmann/json_fwd.hpp>
3411
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3412
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3413
3414
#include <cstdint> // int64_t, uint64_t
3415
#include <map> // map
3416
#include <memory> // allocator
3417
#include <string> // string
3418
#include <vector> // vector
3419
3420
/*!
3421
@brief namespace for Niels Lohmann
3422
@see https://github.com/nlohmann
3423
@since version 1.0.0
3424
*/
3425
namespace nlohmann
3426
{
3427
/*!
3428
@brief default JSONSerializer template argument
3429
3430
This serializer ignores the template arguments and uses ADL
3431
([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
3432
for serialization.
3433
*/
3434
template<typename T = void, typename SFINAE = void>
3435
struct adl_serializer;
3436
3437
template<template<typename U, typename V, typename... Args> class ObjectType =
3438
         std::map,
3439
         template<typename U, typename... Args> class ArrayType = std::vector,
3440
         class StringType = std::string, class BooleanType = bool,
3441
         class NumberIntegerType = std::int64_t,
3442
         class NumberUnsignedType = std::uint64_t,
3443
         class NumberFloatType = double,
3444
         template<typename U> class AllocatorType = std::allocator,
3445
         template<typename T, typename SFINAE = void> class JSONSerializer =
3446
         adl_serializer,
3447
         class BinaryType = std::vector<std::uint8_t>>
3448
class basic_json;
3449
3450
/*!
3451
@brief JSON Pointer
3452
3453
A JSON pointer defines a string syntax for identifying a specific value
3454
within a JSON document. It can be used with functions `at` and
3455
`operator[]`. Furthermore, JSON pointers are the base for JSON patches.
3456
3457
@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
3458
3459
@since version 2.0.0
3460
*/
3461
template<typename BasicJsonType>
3462
class json_pointer;
3463
3464
/*!
3465
@brief default JSON class
3466
3467
This type is the default specialization of the @ref basic_json class which
3468
uses the standard template types.
3469
3470
@since version 1.0.0
3471
*/
3472
using json = basic_json<>;
3473
3474
template<class Key, class T, class IgnoredLess, class Allocator>
3475
struct ordered_map;
3476
3477
/*!
3478
@brief ordered JSON class
3479
3480
This type preserves the insertion order of object keys.
3481
3482
@since version 3.9.0
3483
*/
3484
using ordered_json = basic_json<nlohmann::ordered_map>;
3485
3486
}  // namespace nlohmann
3487
3488
#endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3489
3490
3491
namespace nlohmann
3492
{
3493
/*!
3494
@brief detail namespace with internal helper functions
3495
3496
This namespace collects functions that should not be exposed,
3497
implementations of some @ref basic_json methods, and meta-programming helpers.
3498
3499
@since version 2.1.0
3500
*/
3501
namespace detail
3502
{
3503
/////////////
3504
// helpers //
3505
/////////////
3506
3507
// Note to maintainers:
3508
//
3509
// Every trait in this file expects a non CV-qualified type.
3510
// The only exceptions are in the 'aliases for detected' section
3511
// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3512
//
3513
// In this case, T has to be properly CV-qualified to constraint the function arguments
3514
// (e.g. to_json(BasicJsonType&, const T&))
3515
3516
template<typename> struct is_basic_json : std::false_type {};
3517
3518
NLOHMANN_BASIC_JSON_TPL_DECLARATION
3519
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3520
3521
//////////////////////
3522
// json_ref helpers //
3523
//////////////////////
3524
3525
template<typename>
3526
class json_ref;
3527
3528
template<typename>
3529
struct is_json_ref : std::false_type {};
3530
3531
template<typename T>
3532
struct is_json_ref<json_ref<T>> : std::true_type {};
3533
3534
//////////////////////////
3535
// aliases for detected //
3536
//////////////////////////
3537
3538
template<typename T>
3539
using mapped_type_t = typename T::mapped_type;
3540
3541
template<typename T>
3542
using key_type_t = typename T::key_type;
3543
3544
template<typename T>
3545
using value_type_t = typename T::value_type;
3546
3547
template<typename T>
3548
using difference_type_t = typename T::difference_type;
3549
3550
template<typename T>
3551
using pointer_t = typename T::pointer;
3552
3553
template<typename T>
3554
using reference_t = typename T::reference;
3555
3556
template<typename T>
3557
using iterator_category_t = typename T::iterator_category;
3558
3559
template<typename T, typename... Args>
3560
using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3561
3562
template<typename T, typename... Args>
3563
using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3564
3565
template<typename T, typename U>
3566
using get_template_function = decltype(std::declval<T>().template get<U>());
3567
3568
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3569
template<typename BasicJsonType, typename T, typename = void>
3570
struct has_from_json : std::false_type {};
3571
3572
// trait checking if j.get<T> is valid
3573
// use this trait instead of std::is_constructible or std::is_convertible,
3574
// both rely on, or make use of implicit conversions, and thus fail when T
3575
// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3576
template <typename BasicJsonType, typename T>
3577
struct is_getable
3578
{
3579
    static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3580
};
3581
3582
template<typename BasicJsonType, typename T>
3583
struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3584
{
3585
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
3586
3587
    static constexpr bool value =
3588
        is_detected_exact<void, from_json_function, serializer,
3589
        const BasicJsonType&, T&>::value;
3590
};
3591
3592
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3593
// this overload is used for non-default-constructible user-defined-types
3594
template<typename BasicJsonType, typename T, typename = void>
3595
struct has_non_default_from_json : std::false_type {};
3596
3597
template<typename BasicJsonType, typename T>
3598
struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3599
{
3600
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
3601
3602
    static constexpr bool value =
3603
        is_detected_exact<T, from_json_function, serializer,
3604
        const BasicJsonType&>::value;
3605
};
3606
3607
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3608
// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3609
template<typename BasicJsonType, typename T, typename = void>
3610
struct has_to_json : std::false_type {};
3611
3612
template<typename BasicJsonType, typename T>
3613
struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3614
{
3615
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
3616
3617
    static constexpr bool value =
3618
        is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3619
        T>::value;
3620
};
3621
3622
3623
///////////////////
3624
// is_ functions //
3625
///////////////////
3626
3627
// https://en.cppreference.com/w/cpp/types/conjunction
3628
template<class...> struct conjunction : std::true_type { };
3629
template<class B1> struct conjunction<B1> : B1 { };
3630
template<class B1, class... Bn>
3631
struct conjunction<B1, Bn...>
3632
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3633
3634
// https://en.cppreference.com/w/cpp/types/negation
3635
template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3636
3637
// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3638
// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3639
// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3640
template <typename T>
3641
struct is_default_constructible : std::is_default_constructible<T> {};
3642
3643
template <typename T1, typename T2>
3644
struct is_default_constructible<std::pair<T1, T2>>
3645
            : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3646
3647
template <typename T1, typename T2>
3648
struct is_default_constructible<const std::pair<T1, T2>>
3649
            : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3650
3651
template <typename... Ts>
3652
struct is_default_constructible<std::tuple<Ts...>>
3653
            : conjunction<is_default_constructible<Ts>...> {};
3654
3655
template <typename... Ts>
3656
struct is_default_constructible<const std::tuple<Ts...>>
3657
            : conjunction<is_default_constructible<Ts>...> {};
3658
3659
3660
template <typename T, typename... Args>
3661
struct is_constructible : std::is_constructible<T, Args...> {};
3662
3663
template <typename T1, typename T2>
3664
struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3665
3666
template <typename T1, typename T2>
3667
struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3668
3669
template <typename... Ts>
3670
struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3671
3672
template <typename... Ts>
3673
struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3674
3675
3676
template<typename T, typename = void>
3677
struct is_iterator_traits : std::false_type {};
3678
3679
template<typename T>
3680
struct is_iterator_traits<iterator_traits<T>>
3681
{
3682
  private:
3683
    using traits = iterator_traits<T>;
3684
3685
  public:
3686
    static constexpr auto value =
3687
        is_detected<value_type_t, traits>::value &&
3688
        is_detected<difference_type_t, traits>::value &&
3689
        is_detected<pointer_t, traits>::value &&
3690
        is_detected<iterator_category_t, traits>::value &&
3691
        is_detected<reference_t, traits>::value;
3692
};
3693
3694
template<typename T>
3695
struct is_range
3696
{
3697
  private:
3698
    using t_ref = typename std::add_lvalue_reference<T>::type;
3699
3700
    using iterator = detected_t<result_of_begin, t_ref>;
3701
    using sentinel = detected_t<result_of_end, t_ref>;
3702
3703
    // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3704
    // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3705
    // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3706
    static constexpr auto is_iterator_begin =
3707
        is_iterator_traits<iterator_traits<iterator>>::value;
3708
3709
  public:
3710
    static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3711
};
3712
3713
template<typename R>
3714
using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3715
3716
template<typename T>
3717
using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
3718
3719
// The following implementation of is_complete_type is taken from
3720
// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3721
// and is written by Xiang Fan who agreed to using it in this library.
3722
3723
template<typename T, typename = void>
3724
struct is_complete_type : std::false_type {};
3725
3726
template<typename T>
3727
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3728
3729
template<typename BasicJsonType, typename CompatibleObjectType,
3730
         typename = void>
3731
struct is_compatible_object_type_impl : std::false_type {};
3732
3733
template<typename BasicJsonType, typename CompatibleObjectType>
3734
struct is_compatible_object_type_impl <
3735
    BasicJsonType, CompatibleObjectType,
3736
    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3737
    is_detected<key_type_t, CompatibleObjectType>::value >>
3738
{
3739
    using object_t = typename BasicJsonType::object_t;
3740
3741
    // macOS's is_constructible does not play well with nonesuch...
3742
    static constexpr bool value =
3743
        is_constructible<typename object_t::key_type,
3744
        typename CompatibleObjectType::key_type>::value &&
3745
        is_constructible<typename object_t::mapped_type,
3746
        typename CompatibleObjectType::mapped_type>::value;
3747
};
3748
3749
template<typename BasicJsonType, typename CompatibleObjectType>
3750
struct is_compatible_object_type
3751
    : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3752
3753
template<typename BasicJsonType, typename ConstructibleObjectType,
3754
         typename = void>
3755
struct is_constructible_object_type_impl : std::false_type {};
3756
3757
template<typename BasicJsonType, typename ConstructibleObjectType>
3758
struct is_constructible_object_type_impl <
3759
    BasicJsonType, ConstructibleObjectType,
3760
    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3761
    is_detected<key_type_t, ConstructibleObjectType>::value >>
3762
{
3763
    using object_t = typename BasicJsonType::object_t;
3764
3765
    static constexpr bool value =
3766
        (is_default_constructible<ConstructibleObjectType>::value &&
3767
         (std::is_move_assignable<ConstructibleObjectType>::value ||
3768
          std::is_copy_assignable<ConstructibleObjectType>::value) &&
3769
         (is_constructible<typename ConstructibleObjectType::key_type,
3770
          typename object_t::key_type>::value &&
3771
          std::is_same <
3772
          typename object_t::mapped_type,
3773
          typename ConstructibleObjectType::mapped_type >::value)) ||
3774
        (has_from_json<BasicJsonType,
3775
         typename ConstructibleObjectType::mapped_type>::value ||
3776
         has_non_default_from_json <
3777
         BasicJsonType,
3778
         typename ConstructibleObjectType::mapped_type >::value);
3779
};
3780
3781
template<typename BasicJsonType, typename ConstructibleObjectType>
3782
struct is_constructible_object_type
3783
    : is_constructible_object_type_impl<BasicJsonType,
3784
      ConstructibleObjectType> {};
3785
3786
template<typename BasicJsonType, typename CompatibleStringType>
3787
struct is_compatible_string_type
3788
{
3789
    static constexpr auto value =
3790
        is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3791
};
3792
3793
template<typename BasicJsonType, typename ConstructibleStringType>
3794
struct is_constructible_string_type
3795
{
3796
    static constexpr auto value =
3797
        is_constructible<ConstructibleStringType,
3798
        typename BasicJsonType::string_t>::value;
3799
};
3800
3801
template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3802
struct is_compatible_array_type_impl : std::false_type {};
3803
3804
template<typename BasicJsonType, typename CompatibleArrayType>
3805
struct is_compatible_array_type_impl <
3806
    BasicJsonType, CompatibleArrayType,
3807
    enable_if_t <
3808
    is_detected<iterator_t, CompatibleArrayType>::value&&
3809
    is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3810
// special case for types like std::filesystem::path whose iterator's value_type are themselves
3811
// c.f. https://github.com/nlohmann/json/pull/3073
3812
    !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3813
{
3814
    static constexpr bool value =
3815
        is_constructible<BasicJsonType,
3816
        range_value_t<CompatibleArrayType>>::value;
3817
};
3818
3819
template<typename BasicJsonType, typename CompatibleArrayType>
3820
struct is_compatible_array_type
3821
    : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3822
3823
template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3824
struct is_constructible_array_type_impl : std::false_type {};
3825
3826
template<typename BasicJsonType, typename ConstructibleArrayType>
3827
struct is_constructible_array_type_impl <
3828
    BasicJsonType, ConstructibleArrayType,
3829
    enable_if_t<std::is_same<ConstructibleArrayType,
3830
    typename BasicJsonType::value_type>::value >>
3831
            : std::true_type {};
3832
3833
template<typename BasicJsonType, typename ConstructibleArrayType>
3834
struct is_constructible_array_type_impl <
3835
    BasicJsonType, ConstructibleArrayType,
3836
    enable_if_t < !std::is_same<ConstructibleArrayType,
3837
    typename BasicJsonType::value_type>::value&&
3838
    !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3839
    is_default_constructible<ConstructibleArrayType>::value&&
3840
(std::is_move_assignable<ConstructibleArrayType>::value ||
3841
 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3842
is_detected<iterator_t, ConstructibleArrayType>::value&&
3843
is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3844
is_detected<range_value_t, ConstructibleArrayType>::value&&
3845
// special case for types like std::filesystem::path whose iterator's value_type are themselves
3846
// c.f. https://github.com/nlohmann/json/pull/3073
3847
!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3848
        is_complete_type <
3849
        detected_t<range_value_t, ConstructibleArrayType >>::value >>
3850
{
3851
    using value_type = range_value_t<ConstructibleArrayType>;
3852
3853
    static constexpr bool value =
3854
        std::is_same<value_type,
3855
        typename BasicJsonType::array_t::value_type>::value ||
3856
        has_from_json<BasicJsonType,
3857
        value_type>::value ||
3858
        has_non_default_from_json <
3859
        BasicJsonType,
3860
        value_type >::value;
3861
};
3862
3863
template<typename BasicJsonType, typename ConstructibleArrayType>
3864
struct is_constructible_array_type
3865
    : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3866
3867
template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3868
         typename = void>
3869
struct is_compatible_integer_type_impl : std::false_type {};
3870
3871
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3872
struct is_compatible_integer_type_impl <
3873
    RealIntegerType, CompatibleNumberIntegerType,
3874
    enable_if_t < std::is_integral<RealIntegerType>::value&&
3875
    std::is_integral<CompatibleNumberIntegerType>::value&&
3876
    !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3877
{
3878
    // is there an assert somewhere on overflows?
3879
    using RealLimits = std::numeric_limits<RealIntegerType>;
3880
    using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3881
3882
    static constexpr auto value =
3883
        is_constructible<RealIntegerType,
3884
        CompatibleNumberIntegerType>::value &&
3885
        CompatibleLimits::is_integer &&
3886
        RealLimits::is_signed == CompatibleLimits::is_signed;
3887
};
3888
3889
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3890
struct is_compatible_integer_type
3891
    : is_compatible_integer_type_impl<RealIntegerType,
3892
      CompatibleNumberIntegerType> {};
3893
3894
template<typename BasicJsonType, typename CompatibleType, typename = void>
3895
struct is_compatible_type_impl: std::false_type {};
3896
3897
template<typename BasicJsonType, typename CompatibleType>
3898
struct is_compatible_type_impl <
3899
    BasicJsonType, CompatibleType,
3900
    enable_if_t<is_complete_type<CompatibleType>::value >>
3901
{
3902
    static constexpr bool value =
3903
        has_to_json<BasicJsonType, CompatibleType>::value;
3904
};
3905
3906
template<typename BasicJsonType, typename CompatibleType>
3907
struct is_compatible_type
3908
    : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3909
3910
template<typename T1, typename T2>
3911
struct is_constructible_tuple : std::false_type {};
3912
3913
template<typename T1, typename... Args>
3914
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3915
3916
// a naive helper to check if a type is an ordered_map (exploits the fact that
3917
// ordered_map inherits capacity() from std::vector)
3918
template <typename T>
3919
struct is_ordered_map
3920
{
3921
    using one = char;
3922
3923
    struct two
3924
    {
3925
        char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3926
    };
3927
3928
    template <typename C> static one test( decltype(&C::capacity) ) ;
3929
    template <typename C> static two test(...);
3930
3931
    enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3932
};
3933
3934
// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3935
template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3936
T conditional_static_cast(U value)
3937
{
3938
    return static_cast<T>(value);
3939
}
3940
3941
template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3942
T conditional_static_cast(U value)
3943
{
3944
    return value;
3945
}
3946
3947
}  // namespace detail
3948
}  // namespace nlohmann
3949
3950
// #include <nlohmann/detail/value_t.hpp>
3951
3952
3953
#ifdef JSON_HAS_CPP_17
3954
    #include <filesystem>
3955
#endif
3956
3957
namespace nlohmann
3958
{
3959
namespace detail
3960
{
3961
template<typename BasicJsonType>
3962
void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3963
{
3964
    if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3965
    {
3966
        JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3967
    }
3968
    n = nullptr;
3969
}
3970
3971
// overloads for basic_json template parameters
3972
template < typename BasicJsonType, typename ArithmeticType,
3973
           enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3974
                         !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3975
                         int > = 0 >
3976
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3977
2.10M
{
3978
2.10M
    switch (static_cast<value_t>(j))
3979
2.10M
    {
3980
2.09M
        case value_t::number_unsigned:
3981
2.09M
        {
3982
2.09M
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3983
2.09M
            break;
3984
0
        }
3985
6.84k
        case value_t::number_integer:
3986
6.84k
        {
3987
6.84k
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3988
6.84k
            break;
3989
0
        }
3990
4.88k
        case value_t::number_float:
3991
4.88k
        {
3992
4.88k
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3993
4.88k
            break;
3994
0
        }
3995
3996
0
        case value_t::null:
3997
0
        case value_t::object:
3998
0
        case value_t::array:
3999
0
        case value_t::string:
4000
0
        case value_t::boolean:
4001
0
        case value_t::binary:
4002
0
        case value_t::discarded:
4003
0
        default:
4004
0
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4005
2.10M
    }
4006
2.10M
}
void nlohmann::detail::get_arithmetic_value<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<unsigned char, std::__1::allocator<unsigned char> > >, long, 0>(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<unsigned char, std::__1::allocator<unsigned char> > > const&, long&)
Line
Count
Source
3977
1.36M
{
3978
1.36M
    switch (static_cast<value_t>(j))
3979
1.36M
    {
3980
1.35M
        case value_t::number_unsigned:
3981
1.35M
        {
3982
1.35M
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3983
1.35M
            break;
3984
0
        }
3985
5.86k
        case value_t::number_integer:
3986
5.86k
        {
3987
5.86k
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3988
5.86k
            break;
3989
0
        }
3990
0
        case value_t::number_float:
3991
0
        {
3992
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3993
0
            break;
3994
0
        }
3995
3996
0
        case value_t::null:
3997
0
        case value_t::object:
3998
0
        case value_t::array:
3999
0
        case value_t::string:
4000
0
        case value_t::boolean:
4001
0
        case value_t::binary:
4002
0
        case value_t::discarded:
4003
0
        default:
4004
0
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4005
1.36M
    }
4006
1.36M
}
void nlohmann::detail::get_arithmetic_value<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<unsigned char, std::__1::allocator<unsigned char> > >, double, 0>(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<unsigned char, std::__1::allocator<unsigned char> > > const&, double&)
Line
Count
Source
3977
743k
{
3978
743k
    switch (static_cast<value_t>(j))
3979
743k
    {
3980
738k
        case value_t::number_unsigned:
3981
738k
        {
3982
738k
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3983
738k
            break;
3984
0
        }
3985
983
        case value_t::number_integer:
3986
983
        {
3987
983
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3988
983
            break;
3989
0
        }
3990
4.88k
        case value_t::number_float:
3991
4.88k
        {
3992
4.88k
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3993
4.88k
            break;
3994
0
        }
3995
3996
0
        case value_t::null:
3997
0
        case value_t::object:
3998
0
        case value_t::array:
3999
0
        case value_t::string:
4000
0
        case value_t::boolean:
4001
0
        case value_t::binary:
4002
0
        case value_t::discarded:
4003
0
        default:
4004
0
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4005
743k
    }
4006
743k
}
Unexecuted instantiation: void nlohmann::detail::get_arithmetic_value<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<unsigned char, std::__1::allocator<unsigned char> > >, unsigned long, 0>(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<unsigned char, std::__1::allocator<unsigned char> > > const&, unsigned long&)
4007
4008
template<typename BasicJsonType>
4009
void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4010
485
{
4011
485
    if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4012
0
    {
4013
0
        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
4014
0
    }
4015
485
    b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4016
485
}
4017
4018
template<typename BasicJsonType>
4019
void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4020
73.0k
{
4021
73.0k
    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4022
0
    {
4023
0
        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4024
0
    }
4025
73.0k
    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4026
73.0k
}
4027
4028
template <
4029
    typename BasicJsonType, typename ConstructibleStringType,
4030
    enable_if_t <
4031
        is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
4032
        !std::is_same<typename BasicJsonType::string_t,
4033
                      ConstructibleStringType>::value,
4034
        int > = 0 >
4035
void from_json(const BasicJsonType& j, ConstructibleStringType& s)
4036
{
4037
    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4038
    {
4039
        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4040
    }
4041
4042
    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4043
}
4044
4045
template<typename BasicJsonType>
4046
void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4047
743k
{
4048
743k
    get_arithmetic_value(j, val);
4049
743k
}
4050
4051
template<typename BasicJsonType>
4052
void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4053
0
{
4054
0
    get_arithmetic_value(j, val);
4055
0
}
4056
4057
template<typename BasicJsonType>
4058
void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4059
1.36M
{
4060
1.36M
    get_arithmetic_value(j, val);
4061
1.36M
}
4062
4063
template<typename BasicJsonType, typename EnumType,
4064
         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4065
void from_json(const BasicJsonType& j, EnumType& e)
4066
{
4067
    typename std::underlying_type<EnumType>::type val;
4068
    get_arithmetic_value(j, val);
4069
    e = static_cast<EnumType>(val);
4070
}
4071
4072
// forward_list doesn't have an insert method
4073
template<typename BasicJsonType, typename T, typename Allocator,
4074
         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4075
void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4076
{
4077
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4078
    {
4079
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4080
    }
4081
    l.clear();
4082
    std::transform(j.rbegin(), j.rend(),
4083
                   std::front_inserter(l), [](const BasicJsonType & i)
4084
    {
4085
        return i.template get<T>();
4086
    });
4087
}
4088
4089
// valarray doesn't have an insert method
4090
template<typename BasicJsonType, typename T,
4091
         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4092
void from_json(const BasicJsonType& j, std::valarray<T>& l)
4093
{
4094
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4095
    {
4096
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4097
    }
4098
    l.resize(j.size());
4099
    std::transform(j.begin(), j.end(), std::begin(l),
4100
                   [](const BasicJsonType & elem)
4101
    {
4102
        return elem.template get<T>();
4103
    });
4104
}
4105
4106
template<typename BasicJsonType, typename T, std::size_t N>
4107
auto from_json(const BasicJsonType& j, T (&arr)[N])  // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4108
-> decltype(j.template get<T>(), void())
4109
{
4110
    for (std::size_t i = 0; i < N; ++i)
4111
    {
4112
        arr[i] = j.at(i).template get<T>();
4113
    }
4114
}
4115
4116
template<typename BasicJsonType>
4117
void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4118
{
4119
    arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4120
}
4121
4122
template<typename BasicJsonType, typename T, std::size_t N>
4123
auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4124
                          priority_tag<2> /*unused*/)
4125
-> decltype(j.template get<T>(), void())
4126
{
4127
    for (std::size_t i = 0; i < N; ++i)
4128
    {
4129
        arr[i] = j.at(i).template get<T>();
4130
    }
4131
}
4132
4133
template<typename BasicJsonType, typename ConstructibleArrayType,
4134
         enable_if_t<
4135
             std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4136
             int> = 0>
4137
auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4138
-> decltype(
4139
    arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4140
    j.template get<typename ConstructibleArrayType::value_type>(),
4141
    void())
4142
{
4143
    using std::end;
4144
4145
    ConstructibleArrayType ret;
4146
    ret.reserve(j.size());
4147
    std::transform(j.begin(), j.end(),
4148
                   std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4149
    {
4150
        // get<BasicJsonType>() returns *this, this won't call a from_json
4151
        // method when value_type is BasicJsonType
4152
        return i.template get<typename ConstructibleArrayType::value_type>();
4153
    });
4154
    arr = std::move(ret);
4155
}
4156
4157
template<typename BasicJsonType, typename ConstructibleArrayType,
4158
         enable_if_t<
4159
             std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4160
             int> = 0>
4161
void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4162
                          priority_tag<0> /*unused*/)
4163
{
4164
    using std::end;
4165
4166
    ConstructibleArrayType ret;
4167
    std::transform(
4168
        j.begin(), j.end(), std::inserter(ret, end(ret)),
4169
        [](const BasicJsonType & i)
4170
    {
4171
        // get<BasicJsonType>() returns *this, this won't call a from_json
4172
        // method when value_type is BasicJsonType
4173
        return i.template get<typename ConstructibleArrayType::value_type>();
4174
    });
4175
    arr = std::move(ret);
4176
}
4177
4178
template < typename BasicJsonType, typename ConstructibleArrayType,
4179
           enable_if_t <
4180
               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4181
               !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4182
               !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4183
               !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4184
               !is_basic_json<ConstructibleArrayType>::value,
4185
               int > = 0 >
4186
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4187
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4188
j.template get<typename ConstructibleArrayType::value_type>(),
4189
void())
4190
{
4191
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4192
    {
4193
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4194
    }
4195
4196
    from_json_array_impl(j, arr, priority_tag<3> {});
4197
}
4198
4199
template < typename BasicJsonType, typename T, std::size_t... Idx >
4200
std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4201
        identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4202
{
4203
    return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4204
}
4205
4206
template < typename BasicJsonType, typename T, std::size_t N >
4207
auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4208
-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4209
{
4210
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4211
    {
4212
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4213
    }
4214
4215
    return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4216
}
4217
4218
template<typename BasicJsonType>
4219
void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4220
{
4221
    if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4222
    {
4223
        JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4224
    }
4225
4226
    bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4227
}
4228
4229
template<typename BasicJsonType, typename ConstructibleObjectType,
4230
         enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4231
void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4232
{
4233
    if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4234
    {
4235
        JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4236
    }
4237
4238
    ConstructibleObjectType ret;
4239
    const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4240
    using value_type = typename ConstructibleObjectType::value_type;
4241
    std::transform(
4242
        inner_object->begin(), inner_object->end(),
4243
        std::inserter(ret, ret.begin()),
4244
        [](typename BasicJsonType::object_t::value_type const & p)
4245
    {
4246
        return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4247
    });
4248
    obj = std::move(ret);
4249
}
4250
4251
// overload for arithmetic types, not chosen for basic_json template arguments
4252
// (BooleanType, etc..); note: Is it really necessary to provide explicit
4253
// overloads for boolean_t etc. in case of a custom BooleanType which is not
4254
// an arithmetic type?
4255
template < typename BasicJsonType, typename ArithmeticType,
4256
           enable_if_t <
4257
               std::is_arithmetic<ArithmeticType>::value&&
4258
               !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4259
               !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4260
               !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4261
               !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4262
               int > = 0 >
4263
void from_json(const BasicJsonType& j, ArithmeticType& val)
4264
{
4265
    switch (static_cast<value_t>(j))
4266
    {
4267
        case value_t::number_unsigned:
4268
        {
4269
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4270
            break;
4271
        }
4272
        case value_t::number_integer:
4273
        {
4274
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4275
            break;
4276
        }
4277
        case value_t::number_float:
4278
        {
4279
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4280
            break;
4281
        }
4282
        case value_t::boolean:
4283
        {
4284
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4285
            break;
4286
        }
4287
4288
        case value_t::null:
4289
        case value_t::object:
4290
        case value_t::array:
4291
        case value_t::string:
4292
        case value_t::binary:
4293
        case value_t::discarded:
4294
        default:
4295
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4296
    }
4297
}
4298
4299
template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4300
std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4301
{
4302
    return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4303
}
4304
4305
template < typename BasicJsonType, class A1, class A2 >
4306
std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4307
{
4308
    return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4309
            std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4310
}
4311
4312
template<typename BasicJsonType, typename A1, typename A2>
4313
void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4314
{
4315
    p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4316
}
4317
4318
template<typename BasicJsonType, typename... Args>
4319
std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4320
{
4321
    return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4322
}
4323
4324
template<typename BasicJsonType, typename... Args>
4325
void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4326
{
4327
    t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4328
}
4329
4330
template<typename BasicJsonType, typename TupleRelated>
4331
auto from_json(BasicJsonType&& j, TupleRelated&& t)
4332
-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4333
{
4334
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4335
    {
4336
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4337
    }
4338
4339
    return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4340
}
4341
4342
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4343
           typename = enable_if_t < !std::is_constructible <
4344
                                        typename BasicJsonType::string_t, Key >::value >>
4345
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4346
{
4347
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4348
    {
4349
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4350
    }
4351
    m.clear();
4352
    for (const auto& p : j)
4353
    {
4354
        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4355
        {
4356
            JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4357
        }
4358
        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4359
    }
4360
}
4361
4362
template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4363
           typename = enable_if_t < !std::is_constructible <
4364
                                        typename BasicJsonType::string_t, Key >::value >>
4365
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4366
{
4367
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4368
    {
4369
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4370
    }
4371
    m.clear();
4372
    for (const auto& p : j)
4373
    {
4374
        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4375
        {
4376
            JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4377
        }
4378
        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4379
    }
4380
}
4381
4382
#ifdef JSON_HAS_CPP_17
4383
template<typename BasicJsonType>
4384
void from_json(const BasicJsonType& j, std::filesystem::path& p)
4385
{
4386
    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4387
    {
4388
        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4389
    }
4390
    p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4391
}
4392
#endif
4393
4394
struct from_json_fn
4395
{
4396
    template<typename BasicJsonType, typename T>
4397
    auto operator()(const BasicJsonType& j, T&& val) const
4398
    noexcept(noexcept(from_json(j, std::forward<T>(val))))
4399
    -> decltype(from_json(j, std::forward<T>(val)))
4400
2.18M
    {
4401
2.18M
        return from_json(j, std::forward<T>(val));
4402
2.18M
    }
_ZNK8nlohmann6detail12from_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERbEEDTcl9from_jsonfp_clsr3stdE7forwardIT0_Efp0_EEERKT_OSI_
Line
Count
Source
4400
485
    {
4401
485
        return from_json(j, std::forward<T>(val));
4402
485
    }
_ZNK8nlohmann6detail12from_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERlEEDTcl9from_jsonfp_clsr3stdE7forwardIT0_Efp0_EEERKT_OSI_
Line
Count
Source
4400
1.36M
    {
4401
1.36M
        return from_json(j, std::forward<T>(val));
4402
1.36M
    }
_ZNK8nlohmann6detail12from_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERdEEDTcl9from_jsonfp_clsr3stdE7forwardIT0_Efp0_EEERKT_OSI_
Line
Count
Source
4400
743k
    {
4401
743k
        return from_json(j, std::forward<T>(val));
4402
743k
    }
_ZNK8nlohmann6detail12from_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERSC_EEDTcl9from_jsonfp_clsr3stdE7forwardIT0_Efp0_EEERKT_OSI_
Line
Count
Source
4400
73.0k
    {
4401
73.0k
        return from_json(j, std::forward<T>(val));
4402
73.0k
    }
Unexecuted instantiation: _ZNK8nlohmann6detail12from_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERmEEDTcl9from_jsonfp_clsr3stdE7forwardIT0_Efp0_EEERKT_OSI_
4403
};
4404
}  // namespace detail
4405
4406
/// namespace to hold default `from_json` function
4407
/// to see why this is required:
4408
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
4409
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4410
{
4411
constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4412
} // namespace
4413
} // namespace nlohmann
4414
4415
// #include <nlohmann/detail/conversions/to_json.hpp>
4416
4417
4418
#include <algorithm> // copy
4419
#include <iterator> // begin, end
4420
#include <string> // string
4421
#include <tuple> // tuple, get
4422
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4423
#include <utility> // move, forward, declval, pair
4424
#include <valarray> // valarray
4425
#include <vector> // vector
4426
4427
// #include <nlohmann/detail/macro_scope.hpp>
4428
4429
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4430
4431
4432
#include <cstddef> // size_t
4433
#include <iterator> // input_iterator_tag
4434
#include <string> // string, to_string
4435
#include <tuple> // tuple_size, get, tuple_element
4436
#include <utility> // move
4437
4438
// #include <nlohmann/detail/meta/type_traits.hpp>
4439
4440
// #include <nlohmann/detail/value_t.hpp>
4441
4442
4443
namespace nlohmann
4444
{
4445
namespace detail
4446
{
4447
template<typename string_type>
4448
void int_to_string( string_type& target, std::size_t value )
4449
0
{
4450
0
    // For ADL
4451
0
    using std::to_string;
4452
0
    target = to_string(value);
4453
0
}
4454
template<typename IteratorType> class iteration_proxy_value
4455
{
4456
  public:
4457
    using difference_type = std::ptrdiff_t;
4458
    using value_type = iteration_proxy_value;
4459
    using pointer = value_type * ;
4460
    using reference = value_type & ;
4461
    using iterator_category = std::input_iterator_tag;
4462
    using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4463
4464
  private:
4465
    /// the iterator
4466
    IteratorType anchor;
4467
    /// an index for arrays (used to create key names)
4468
    std::size_t array_index = 0;
4469
    /// last stringified array index
4470
    mutable std::size_t array_index_last = 0;
4471
    /// a string representation of the array index
4472
    mutable string_type array_index_str = "0";
4473
    /// an empty string (to return a reference for primitive values)
4474
    const string_type empty_str{};
4475
4476
  public:
4477
    explicit iteration_proxy_value(IteratorType it) noexcept
4478
        : anchor(std::move(it))
4479
    {}
4480
4481
    /// dereference operator (needed for range-based for)
4482
    iteration_proxy_value& operator*()
4483
0
    {
4484
0
        return *this;
4485
0
    }
4486
4487
    /// increment operator (needed for range-based for)
4488
    iteration_proxy_value& operator++()
4489
0
    {
4490
0
        ++anchor;
4491
0
        ++array_index;
4492
0
4493
0
        return *this;
4494
0
    }
4495
4496
    /// equality operator (needed for InputIterator)
4497
    bool operator==(const iteration_proxy_value& o) const
4498
    {
4499
        return anchor == o.anchor;
4500
    }
4501
4502
    /// inequality operator (needed for range-based for)
4503
    bool operator!=(const iteration_proxy_value& o) const
4504
0
    {
4505
0
        return anchor != o.anchor;
4506
0
    }
4507
4508
    /// return key of the iterator
4509
    const string_type& key() const
4510
0
    {
4511
0
        JSON_ASSERT(anchor.m_object != nullptr);
4512
0
4513
0
        switch (anchor.m_object->type())
4514
0
        {
4515
0
            // use integer array index as key
4516
0
            case value_t::array:
4517
0
            {
4518
0
                if (array_index != array_index_last)
4519
0
                {
4520
0
                    int_to_string( array_index_str, array_index );
4521
0
                    array_index_last = array_index;
4522
0
                }
4523
0
                return array_index_str;
4524
0
            }
4525
0
4526
0
            // use key from the object
4527
0
            case value_t::object:
4528
0
                return anchor.key();
4529
0
4530
0
            // use an empty key for all primitive types
4531
0
            case value_t::null:
4532
0
            case value_t::string:
4533
0
            case value_t::boolean:
4534
0
            case value_t::number_integer:
4535
0
            case value_t::number_unsigned:
4536
0
            case value_t::number_float:
4537
0
            case value_t::binary:
4538
0
            case value_t::discarded:
4539
0
            default:
4540
0
                return empty_str;
4541
0
        }
4542
0
    }
4543
4544
    /// return value of the iterator
4545
    typename IteratorType::reference value() const
4546
0
    {
4547
0
        return anchor.value();
4548
0
    }
4549
};
4550
4551
/// proxy class for the items() function
4552
template<typename IteratorType> class iteration_proxy
4553
{
4554
  private:
4555
    /// the container to iterate
4556
    typename IteratorType::reference container;
4557
4558
  public:
4559
    /// construct iteration proxy from a container
4560
    explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4561
        : container(cont) {}
4562
4563
    /// return iterator begin (needed for range-based for)
4564
    iteration_proxy_value<IteratorType> begin() noexcept
4565
0
    {
4566
0
        return iteration_proxy_value<IteratorType>(container.begin());
4567
0
    }
4568
4569
    /// return iterator end (needed for range-based for)
4570
    iteration_proxy_value<IteratorType> end() noexcept
4571
0
    {
4572
0
        return iteration_proxy_value<IteratorType>(container.end());
4573
0
    }
4574
};
4575
// Structured Bindings Support
4576
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4577
// And see https://github.com/nlohmann/json/pull/1391
4578
template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4579
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4580
{
4581
    return i.key();
4582
}
4583
// Structured Bindings Support
4584
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4585
// And see https://github.com/nlohmann/json/pull/1391
4586
template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4587
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4588
{
4589
    return i.value();
4590
}
4591
}  // namespace detail
4592
}  // namespace nlohmann
4593
4594
// The Addition to the STD Namespace is required to add
4595
// Structured Bindings Support to the iteration_proxy_value class
4596
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4597
// And see https://github.com/nlohmann/json/pull/1391
4598
namespace std
4599
{
4600
#if defined(__clang__)
4601
    // Fix: https://github.com/nlohmann/json/issues/1401
4602
    #pragma clang diagnostic push
4603
    #pragma clang diagnostic ignored "-Wmismatched-tags"
4604
#endif
4605
template<typename IteratorType>
4606
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4607
            : public std::integral_constant<std::size_t, 2> {};
4608
4609
template<std::size_t N, typename IteratorType>
4610
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4611
{
4612
  public:
4613
    using type = decltype(
4614
                     get<N>(std::declval <
4615
                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4616
};
4617
#if defined(__clang__)
4618
    #pragma clang diagnostic pop
4619
#endif
4620
} // namespace std
4621
4622
// #include <nlohmann/detail/meta/cpp_future.hpp>
4623
4624
// #include <nlohmann/detail/meta/type_traits.hpp>
4625
4626
// #include <nlohmann/detail/value_t.hpp>
4627
4628
4629
#ifdef JSON_HAS_CPP_17
4630
    #include <filesystem>
4631
#endif
4632
4633
namespace nlohmann
4634
{
4635
namespace detail
4636
{
4637
//////////////////
4638
// constructors //
4639
//////////////////
4640
4641
/*
4642
 * Note all external_constructor<>::construct functions need to call
4643
 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4644
 * allocated value (e.g., a string). See bug issue
4645
 * https://github.com/nlohmann/json/issues/2865 for more information.
4646
 */
4647
4648
template<value_t> struct external_constructor;
4649
4650
template<>
4651
struct external_constructor<value_t::boolean>
4652
{
4653
    template<typename BasicJsonType>
4654
    static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4655
22.8k
    {
4656
22.8k
        j.m_value.destroy(j.m_type);
4657
22.8k
        j.m_type = value_t::boolean;
4658
22.8k
        j.m_value = b;
4659
22.8k
        j.assert_invariant();
4660
22.8k
    }
4661
};
4662
4663
template<>
4664
struct external_constructor<value_t::string>
4665
{
4666
    template<typename BasicJsonType>
4667
    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4668
71.5k
    {
4669
71.5k
        j.m_value.destroy(j.m_type);
4670
71.5k
        j.m_type = value_t::string;
4671
71.5k
        j.m_value = s;
4672
71.5k
        j.assert_invariant();
4673
71.5k
    }
4674
4675
    template<typename BasicJsonType>
4676
    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4677
    {
4678
        j.m_value.destroy(j.m_type);
4679
        j.m_type = value_t::string;
4680
        j.m_value = std::move(s);
4681
        j.assert_invariant();
4682
    }
4683
4684
    template < typename BasicJsonType, typename CompatibleStringType,
4685
               enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4686
                             int > = 0 >
4687
    static void construct(BasicJsonType& j, const CompatibleStringType& str)
4688
0
    {
4689
0
        j.m_value.destroy(j.m_type);
4690
0
        j.m_type = value_t::string;
4691
0
        j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4692
0
        j.assert_invariant();
4693
0
    }
4694
};
4695
4696
template<>
4697
struct external_constructor<value_t::binary>
4698
{
4699
    template<typename BasicJsonType>
4700
    static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4701
    {
4702
        j.m_value.destroy(j.m_type);
4703
        j.m_type = value_t::binary;
4704
        j.m_value = typename BasicJsonType::binary_t(b);
4705
        j.assert_invariant();
4706
    }
4707
4708
    template<typename BasicJsonType>
4709
    static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4710
    {
4711
        j.m_value.destroy(j.m_type);
4712
        j.m_type = value_t::binary;
4713
        j.m_value = typename BasicJsonType::binary_t(std::move(b));
4714
        j.assert_invariant();
4715
    }
4716
};
4717
4718
template<>
4719
struct external_constructor<value_t::number_float>
4720
{
4721
    template<typename BasicJsonType>
4722
    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4723
50.0k
    {
4724
50.0k
        j.m_value.destroy(j.m_type);
4725
50.0k
        j.m_type = value_t::number_float;
4726
50.0k
        j.m_value = val;
4727
50.0k
        j.assert_invariant();
4728
50.0k
    }
4729
};
4730
4731
template<>
4732
struct external_constructor<value_t::number_unsigned>
4733
{
4734
    template<typename BasicJsonType>
4735
    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4736
6.13M
    {
4737
6.13M
        j.m_value.destroy(j.m_type);
4738
6.13M
        j.m_type = value_t::number_unsigned;
4739
6.13M
        j.m_value = val;
4740
6.13M
        j.assert_invariant();
4741
6.13M
    }
4742
};
4743
4744
template<>
4745
struct external_constructor<value_t::number_integer>
4746
{
4747
    template<typename BasicJsonType>
4748
    static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4749
20.4k
    {
4750
20.4k
        j.m_value.destroy(j.m_type);
4751
20.4k
        j.m_type = value_t::number_integer;
4752
20.4k
        j.m_value = val;
4753
20.4k
        j.assert_invariant();
4754
20.4k
    }
4755
};
4756
4757
template<>
4758
struct external_constructor<value_t::array>
4759
{
4760
    template<typename BasicJsonType>
4761
    static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4762
    {
4763
        j.m_value.destroy(j.m_type);
4764
        j.m_type = value_t::array;
4765
        j.m_value = arr;
4766
        j.set_parents();
4767
        j.assert_invariant();
4768
    }
4769
4770
    template<typename BasicJsonType>
4771
    static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4772
    {
4773
        j.m_value.destroy(j.m_type);
4774
        j.m_type = value_t::array;
4775
        j.m_value = std::move(arr);
4776
        j.set_parents();
4777
        j.assert_invariant();
4778
    }
4779
4780
    template < typename BasicJsonType, typename CompatibleArrayType,
4781
               enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4782
                             int > = 0 >
4783
    static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4784
    {
4785
        using std::begin;
4786
        using std::end;
4787
4788
        j.m_value.destroy(j.m_type);
4789
        j.m_type = value_t::array;
4790
        j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4791
        j.set_parents();
4792
        j.assert_invariant();
4793
    }
4794
4795
    template<typename BasicJsonType>
4796
    static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4797
    {
4798
        j.m_value.destroy(j.m_type);
4799
        j.m_type = value_t::array;
4800
        j.m_value = value_t::array;
4801
        j.m_value.array->reserve(arr.size());
4802
        for (const bool x : arr)
4803
        {
4804
            j.m_value.array->push_back(x);
4805
            j.set_parent(j.m_value.array->back());
4806
        }
4807
        j.assert_invariant();
4808
    }
4809
4810
    template<typename BasicJsonType, typename T,
4811
             enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4812
    static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4813
    {
4814
        j.m_value.destroy(j.m_type);
4815
        j.m_type = value_t::array;
4816
        j.m_value = value_t::array;
4817
        j.m_value.array->resize(arr.size());
4818
        if (arr.size() > 0)
4819
        {
4820
            std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4821
        }
4822
        j.set_parents();
4823
        j.assert_invariant();
4824
    }
4825
};
4826
4827
template<>
4828
struct external_constructor<value_t::object>
4829
{
4830
    template<typename BasicJsonType>
4831
    static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4832
    {
4833
        j.m_value.destroy(j.m_type);
4834
        j.m_type = value_t::object;
4835
        j.m_value = obj;
4836
        j.set_parents();
4837
        j.assert_invariant();
4838
    }
4839
4840
    template<typename BasicJsonType>
4841
    static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4842
    {
4843
        j.m_value.destroy(j.m_type);
4844
        j.m_type = value_t::object;
4845
        j.m_value = std::move(obj);
4846
        j.set_parents();
4847
        j.assert_invariant();
4848
    }
4849
4850
    template < typename BasicJsonType, typename CompatibleObjectType,
4851
               enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4852
    static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4853
    {
4854
        using std::begin;
4855
        using std::end;
4856
4857
        j.m_value.destroy(j.m_type);
4858
        j.m_type = value_t::object;
4859
        j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4860
        j.set_parents();
4861
        j.assert_invariant();
4862
    }
4863
};
4864
4865
/////////////
4866
// to_json //
4867
/////////////
4868
4869
template<typename BasicJsonType, typename T,
4870
         enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4871
void to_json(BasicJsonType& j, T b) noexcept
4872
22.8k
{
4873
22.8k
    external_constructor<value_t::boolean>::construct(j, b);
4874
22.8k
}
4875
4876
template<typename BasicJsonType, typename CompatibleString,
4877
         enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4878
void to_json(BasicJsonType& j, const CompatibleString& s)
4879
71.5k
{
4880
71.5k
    external_constructor<value_t::string>::construct(j, s);
4881
71.5k
}
void nlohmann::detail::to_json<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<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, 0>(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<unsigned char, std::__1::allocator<unsigned char> > >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
4879
71.5k
{
4880
71.5k
    external_constructor<value_t::string>::construct(j, s);
4881
71.5k
}
Unexecuted instantiation: void nlohmann::detail::to_json<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<unsigned char, std::__1::allocator<unsigned char> > >, char const*, 0>(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<unsigned char, std::__1::allocator<unsigned char> > >&, char const* const&)
4882
4883
template<typename BasicJsonType>
4884
void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4885
{
4886
    external_constructor<value_t::string>::construct(j, std::move(s));
4887
}
4888
4889
template<typename BasicJsonType, typename FloatType,
4890
         enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4891
void to_json(BasicJsonType& j, FloatType val) noexcept
4892
50.0k
{
4893
50.0k
    external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4894
50.0k
}
4895
4896
template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4897
         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4898
void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4899
6.13M
{
4900
6.13M
    external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4901
6.13M
}
4902
4903
template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4904
         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4905
void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4906
20.4k
{
4907
20.4k
    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4908
20.4k
}
Unexecuted instantiation: void nlohmann::detail::to_json<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<unsigned char, std::__1::allocator<unsigned char> > >, int, 0>(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<unsigned char, std::__1::allocator<unsigned char> > >&, int)
void nlohmann::detail::to_json<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<unsigned char, std::__1::allocator<unsigned char> > >, long, 0>(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<unsigned char, std::__1::allocator<unsigned char> > >&, long)
Line
Count
Source
4906
20.4k
{
4907
20.4k
    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4908
20.4k
}
4909
4910
template<typename BasicJsonType, typename EnumType,
4911
         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4912
void to_json(BasicJsonType& j, EnumType e) noexcept
4913
{
4914
    using underlying_type = typename std::underlying_type<EnumType>::type;
4915
    external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4916
}
4917
4918
template<typename BasicJsonType>
4919
void to_json(BasicJsonType& j, const std::vector<bool>& e)
4920
{
4921
    external_constructor<value_t::array>::construct(j, e);
4922
}
4923
4924
template < typename BasicJsonType, typename CompatibleArrayType,
4925
           enable_if_t < is_compatible_array_type<BasicJsonType,
4926
                         CompatibleArrayType>::value&&
4927
                         !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4928
                         !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4929
                         !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4930
                         !is_basic_json<CompatibleArrayType>::value,
4931
                         int > = 0 >
4932
void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4933
{
4934
    external_constructor<value_t::array>::construct(j, arr);
4935
}
4936
4937
template<typename BasicJsonType>
4938
void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4939
{
4940
    external_constructor<value_t::binary>::construct(j, bin);
4941
}
4942
4943
template<typename BasicJsonType, typename T,
4944
         enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4945
void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4946
{
4947
    external_constructor<value_t::array>::construct(j, std::move(arr));
4948
}
4949
4950
template<typename BasicJsonType>
4951
void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4952
{
4953
    external_constructor<value_t::array>::construct(j, std::move(arr));
4954
}
4955
4956
template < typename BasicJsonType, typename CompatibleObjectType,
4957
           enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4958
void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4959
{
4960
    external_constructor<value_t::object>::construct(j, obj);
4961
}
4962
4963
template<typename BasicJsonType>
4964
void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4965
{
4966
    external_constructor<value_t::object>::construct(j, std::move(obj));
4967
}
4968
4969
template <
4970
    typename BasicJsonType, typename T, std::size_t N,
4971
    enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4972
                  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4973
                  int > = 0 >
4974
void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4975
{
4976
    external_constructor<value_t::array>::construct(j, arr);
4977
}
4978
4979
template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4980
void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4981
{
4982
    j = { p.first, p.second };
4983
}
4984
4985
// for https://github.com/nlohmann/json/pull/1134
4986
template<typename BasicJsonType, typename T,
4987
         enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4988
void to_json(BasicJsonType& j, const T& b)
4989
{
4990
    j = { {b.key(), b.value()} };
4991
}
4992
4993
template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4994
void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4995
{
4996
    j = { std::get<Idx>(t)... };
4997
}
4998
4999
template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5000
void to_json(BasicJsonType& j, const T& t)
5001
{
5002
    to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5003
}
5004
5005
#ifdef JSON_HAS_CPP_17
5006
template<typename BasicJsonType>
5007
void to_json(BasicJsonType& j, const std::filesystem::path& p)
5008
{
5009
    j = p.string();
5010
}
5011
#endif
5012
5013
struct to_json_fn
5014
{
5015
    template<typename BasicJsonType, typename T>
5016
    auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5017
    -> decltype(to_json(j, std::forward<T>(val)), void())
5018
6.29M
    {
5019
6.29M
        return to_json(j, std::forward<T>(val));
5020
6.29M
    }
_ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERmEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5018
6.13M
    {
5019
6.13M
        return to_json(j, std::forward<T>(val));
5020
6.13M
    }
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERKdEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERKiEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERKbEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERKSC_EEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
_ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERdEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5018
50.0k
    {
5019
50.0k
        return to_json(j, std::forward<T>(val));
5020
50.0k
    }
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERiEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
_ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERbEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5018
22.8k
    {
5019
22.8k
        return to_json(j, std::forward<T>(val));
5020
22.8k
    }
_ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERSC_EEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5018
71.5k
    {
5019
71.5k
        return to_json(j, std::forward<T>(val));
5020
71.5k
    }
_ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERlEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5018
20.4k
    {
5019
20.4k
        return to_json(j, std::forward<T>(val));
5020
20.4k
    }
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERPKcEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSK_
5021
};
5022
}  // namespace detail
5023
5024
/// namespace to hold default `to_json` function
5025
/// to see why this is required:
5026
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
5027
namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5028
{
5029
constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
5030
} // namespace
5031
} // namespace nlohmann
5032
5033
// #include <nlohmann/detail/meta/identity_tag.hpp>
5034
5035
// #include <nlohmann/detail/meta/type_traits.hpp>
5036
5037
5038
namespace nlohmann
5039
{
5040
5041
template<typename ValueType, typename>
5042
struct adl_serializer
5043
{
5044
    /*!
5045
    @brief convert a JSON value to any value type
5046
5047
    This function is usually called by the `get()` function of the
5048
    @ref basic_json class (either explicit or via conversion operators).
5049
5050
    @note This function is chosen for default-constructible value types.
5051
5052
    @param[in] j        JSON value to read from
5053
    @param[in,out] val  value to write to
5054
    */
5055
    template<typename BasicJsonType, typename TargetType = ValueType>
5056
    static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5057
        noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5058
    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5059
2.18M
    {
5060
2.18M
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5061
2.18M
    }
_ZN8nlohmann14adl_serializerIbvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEEbEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSJ_RT0_
Line
Count
Source
5059
485
    {
5060
485
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5061
485
    }
_ZN8nlohmann14adl_serializerIlvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEElEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSJ_RT0_
Line
Count
Source
5059
1.36M
    {
5060
1.36M
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5061
1.36M
    }
_ZN8nlohmann14adl_serializerIdvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEEdEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSJ_RT0_
Line
Count
Source
5059
743k
    {
5060
743k
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5061
743k
    }
_ZN8nlohmann14adl_serializerINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEvE9from_jsonIRKNS_10basic_jsonINS1_3mapENS1_6vectorES7_blmdS5_S0_NSC_IhNS5_IhEEEEEES7_EEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSJ_RT0_
Line
Count
Source
5059
73.0k
    {
5060
73.0k
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5061
73.0k
    }
Unexecuted instantiation: _ZN8nlohmann14adl_serializerImvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEEmEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSJ_RT0_
5062
5063
    /*!
5064
    @brief convert a JSON value to any value type
5065
5066
    This function is usually called by the `get()` function of the
5067
    @ref basic_json class (either explicit or via conversion operators).
5068
5069
    @note This function is chosen for value types which are not default-constructible.
5070
5071
    @param[in] j  JSON value to read from
5072
5073
    @return copy of the JSON value, converted to @a ValueType
5074
    */
5075
    template<typename BasicJsonType, typename TargetType = ValueType>
5076
    static auto from_json(BasicJsonType && j) noexcept(
5077
    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5078
    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5079
    {
5080
        return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5081
    }
5082
5083
    /*!
5084
    @brief convert any value type to a JSON value
5085
5086
    This function is usually called by the constructors of the @ref basic_json
5087
    class.
5088
5089
    @param[in,out] j  JSON value to write to
5090
    @param[in] val    value to read from
5091
    */
5092
    template<typename BasicJsonType, typename TargetType = ValueType>
5093
    static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5094
        noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5095
    -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5096
6.29M
    {
5097
6.29M
        ::nlohmann::to_json(j, std::forward<TargetType>(val));
5098
6.29M
    }
_ZN8nlohmann14adl_serializerImvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERmEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5096
6.13M
    {
5097
6.13M
        ::nlohmann::to_json(j, std::forward<TargetType>(val));
5098
6.13M
    }
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIdvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERKdEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIivE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERKiEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIbvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERKbEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEvE7to_jsonINS_10basic_jsonINS1_3mapENS1_6vectorES7_blmdS5_S0_NSC_IhNS5_IhEEEEEERKS7_EEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
_ZN8nlohmann14adl_serializerIdvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERdEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5096
50.0k
    {
5097
50.0k
        ::nlohmann::to_json(j, std::forward<TargetType>(val));
5098
50.0k
    }
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIivE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERiEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
_ZN8nlohmann14adl_serializerIbvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERbEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5096
22.8k
    {
5097
22.8k
        ::nlohmann::to_json(j, std::forward<TargetType>(val));
5098
22.8k
    }
_ZN8nlohmann14adl_serializerINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEvE7to_jsonINS_10basic_jsonINS1_3mapENS1_6vectorES7_blmdS5_S0_NSC_IhNS5_IhEEEEEERS7_EEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5096
71.5k
    {
5097
71.5k
        ::nlohmann::to_json(j, std::forward<TargetType>(val));
5098
71.5k
    }
_ZN8nlohmann14adl_serializerIlvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERlEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Line
Count
Source
5096
20.4k
    {
5097
20.4k
        ::nlohmann::to_json(j, std::forward<TargetType>(val));
5098
20.4k
    }
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIPKcvE7to_jsonINS_10basic_jsonINSt3__13mapENS6_6vectorENS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEblmdSC_S0_NS8_IhNSC_IhEEEEEERS2_EEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSK_
5099
};
5100
}  // namespace nlohmann
5101
5102
// #include <nlohmann/byte_container_with_subtype.hpp>
5103
5104
5105
#include <cstdint> // uint8_t, uint64_t
5106
#include <tuple> // tie
5107
#include <utility> // move
5108
5109
namespace nlohmann
5110
{
5111
5112
/*!
5113
@brief an internal type for a backed binary type
5114
5115
This type extends the template parameter @a BinaryType provided to `basic_json`
5116
with a subtype used by BSON and MessagePack. This type exists so that the user
5117
does not have to specify a type themselves with a specific naming scheme in
5118
order to override the binary type.
5119
5120
@tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
5121
                   default)
5122
5123
@since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0.
5124
*/
5125
template<typename BinaryType>
5126
class byte_container_with_subtype : public BinaryType
5127
{
5128
  public:
5129
    /// the type of the underlying container
5130
    using container_type = BinaryType;
5131
    /// the type of the subtype
5132
    using subtype_type = std::uint64_t;
5133
5134
    byte_container_with_subtype() noexcept(noexcept(container_type()))
5135
        : container_type()
5136
0
    {}
5137
5138
    byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
5139
        : container_type(b)
5140
    {}
5141
5142
    byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5143
        : container_type(std::move(b))
5144
    {}
5145
5146
    byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5147
        : container_type(b)
5148
        , m_subtype(subtype_)
5149
        , m_has_subtype(true)
5150
    {}
5151
5152
    byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5153
        : container_type(std::move(b))
5154
        , m_subtype(subtype_)
5155
        , m_has_subtype(true)
5156
    {}
5157
5158
    bool operator==(const byte_container_with_subtype& rhs) const
5159
    {
5160
        return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5161
               std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5162
    }
5163
5164
    bool operator!=(const byte_container_with_subtype& rhs) const
5165
    {
5166
        return !(rhs == *this);
5167
    }
5168
5169
    /*!
5170
    @brief sets the binary subtype
5171
5172
    Sets the binary subtype of the value, also flags a binary JSON value as
5173
    having a subtype, which has implications for serialization.
5174
5175
    @complexity Constant.
5176
5177
    @exceptionsafety No-throw guarantee: this member function never throws
5178
    exceptions.
5179
5180
    @sa see @ref subtype() -- return the binary subtype
5181
    @sa see @ref clear_subtype() -- clears the binary subtype
5182
    @sa see @ref has_subtype() -- returns whether or not the binary value has a
5183
    subtype
5184
5185
    @since version 3.8.0
5186
    */
5187
    void set_subtype(subtype_type subtype_) noexcept
5188
    {
5189
        m_subtype = subtype_;
5190
        m_has_subtype = true;
5191
    }
5192
5193
    /*!
5194
    @brief return the binary subtype
5195
5196
    Returns the numerical subtype of the value if it has a subtype. If it does
5197
    not have a subtype, this function will return subtype_type(-1) as a sentinel
5198
    value.
5199
5200
    @return the numerical subtype of the binary value
5201
5202
    @complexity Constant.
5203
5204
    @exceptionsafety No-throw guarantee: this member function never throws
5205
    exceptions.
5206
5207
    @sa see @ref set_subtype() -- sets the binary subtype
5208
    @sa see @ref clear_subtype() -- clears the binary subtype
5209
    @sa see @ref has_subtype() -- returns whether or not the binary value has a
5210
    subtype
5211
5212
    @since version 3.8.0; fixed return value to properly return
5213
           subtype_type(-1) as documented in version 3.10.0
5214
    */
5215
    constexpr subtype_type subtype() const noexcept
5216
0
    {
5217
0
        return m_has_subtype ? m_subtype : subtype_type(-1);
5218
0
    }
5219
5220
    /*!
5221
    @brief return whether the value has a subtype
5222
5223
    @return whether the value has a subtype
5224
5225
    @complexity Constant.
5226
5227
    @exceptionsafety No-throw guarantee: this member function never throws
5228
    exceptions.
5229
5230
    @sa see @ref subtype() -- return the binary subtype
5231
    @sa see @ref set_subtype() -- sets the binary subtype
5232
    @sa see @ref clear_subtype() -- clears the binary subtype
5233
5234
    @since version 3.8.0
5235
    */
5236
    constexpr bool has_subtype() const noexcept
5237
0
    {
5238
0
        return m_has_subtype;
5239
0
    }
5240
5241
    /*!
5242
    @brief clears the binary subtype
5243
5244
    Clears the binary subtype and flags the value as not having a subtype, which
5245
    has implications for serialization; for instance MessagePack will prefer the
5246
    bin family over the ext family.
5247
5248
    @complexity Constant.
5249
5250
    @exceptionsafety No-throw guarantee: this member function never throws
5251
    exceptions.
5252
5253
    @sa see @ref subtype() -- return the binary subtype
5254
    @sa see @ref set_subtype() -- sets the binary subtype
5255
    @sa see @ref has_subtype() -- returns whether or not the binary value has a
5256
    subtype
5257
5258
    @since version 3.8.0
5259
    */
5260
    void clear_subtype() noexcept
5261
    {
5262
        m_subtype = 0;
5263
        m_has_subtype = false;
5264
    }
5265
5266
  private:
5267
    subtype_type m_subtype = 0;
5268
    bool m_has_subtype = false;
5269
};
5270
5271
}  // namespace nlohmann
5272
5273
// #include <nlohmann/detail/conversions/from_json.hpp>
5274
5275
// #include <nlohmann/detail/conversions/to_json.hpp>
5276
5277
// #include <nlohmann/detail/exceptions.hpp>
5278
5279
// #include <nlohmann/detail/hash.hpp>
5280
5281
5282
#include <cstdint> // uint8_t
5283
#include <cstddef> // size_t
5284
#include <functional> // hash
5285
5286
// #include <nlohmann/detail/macro_scope.hpp>
5287
5288
// #include <nlohmann/detail/value_t.hpp>
5289
5290
5291
namespace nlohmann
5292
{
5293
namespace detail
5294
{
5295
5296
// boost::hash_combine
5297
inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5298
0
{
5299
0
    seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5300
0
    return seed;
5301
0
}
5302
5303
/*!
5304
@brief hash a JSON value
5305
5306
The hash function tries to rely on std::hash where possible. Furthermore, the
5307
type of the JSON value is taken into account to have different hash values for
5308
null, 0, 0U, and false, etc.
5309
5310
@tparam BasicJsonType basic_json specialization
5311
@param j JSON value to hash
5312
@return hash value of j
5313
*/
5314
template<typename BasicJsonType>
5315
std::size_t hash(const BasicJsonType& j)
5316
0
{
5317
0
    using string_t = typename BasicJsonType::string_t;
5318
0
    using number_integer_t = typename BasicJsonType::number_integer_t;
5319
0
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5320
0
    using number_float_t = typename BasicJsonType::number_float_t;
5321
0
5322
0
    const auto type = static_cast<std::size_t>(j.type());
5323
0
    switch (j.type())
5324
0
    {
5325
0
        case BasicJsonType::value_t::null:
5326
0
        case BasicJsonType::value_t::discarded:
5327
0
        {
5328
0
            return combine(type, 0);
5329
0
        }
5330
0
5331
0
        case BasicJsonType::value_t::object:
5332
0
        {
5333
0
            auto seed = combine(type, j.size());
5334
0
            for (const auto& element : j.items())
5335
0
            {
5336
0
                const auto h = std::hash<string_t> {}(element.key());
5337
0
                seed = combine(seed, h);
5338
0
                seed = combine(seed, hash(element.value()));
5339
0
            }
5340
0
            return seed;
5341
0
        }
5342
0
5343
0
        case BasicJsonType::value_t::array:
5344
0
        {
5345
0
            auto seed = combine(type, j.size());
5346
0
            for (const auto& element : j)
5347
0
            {
5348
0
                seed = combine(seed, hash(element));
5349
0
            }
5350
0
            return seed;
5351
0
        }
5352
0
5353
0
        case BasicJsonType::value_t::string:
5354
0
        {
5355
0
            const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5356
0
            return combine(type, h);
5357
0
        }
5358
0
5359
0
        case BasicJsonType::value_t::boolean:
5360
0
        {
5361
0
            const auto h = std::hash<bool> {}(j.template get<bool>());
5362
0
            return combine(type, h);
5363
0
        }
5364
0
5365
0
        case BasicJsonType::value_t::number_integer:
5366
0
        {
5367
0
            const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5368
0
            return combine(type, h);
5369
0
        }
5370
0
5371
0
        case BasicJsonType::value_t::number_unsigned:
5372
0
        {
5373
0
            const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5374
0
            return combine(type, h);
5375
0
        }
5376
0
5377
0
        case BasicJsonType::value_t::number_float:
5378
0
        {
5379
0
            const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5380
0
            return combine(type, h);
5381
0
        }
5382
0
5383
0
        case BasicJsonType::value_t::binary:
5384
0
        {
5385
0
            auto seed = combine(type, j.get_binary().size());
5386
0
            const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5387
0
            seed = combine(seed, h);
5388
0
            seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5389
0
            for (const auto byte : j.get_binary())
5390
0
            {
5391
0
                seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5392
0
            }
5393
0
            return seed;
5394
0
        }
5395
0
5396
0
        default:                   // LCOV_EXCL_LINE
5397
0
            JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5398
0
            return 0;              // LCOV_EXCL_LINE
5399
0
    }
5400
0
}
5401
5402
}  // namespace detail
5403
}  // namespace nlohmann
5404
5405
// #include <nlohmann/detail/input/binary_reader.hpp>
5406
5407
5408
#include <algorithm> // generate_n
5409
#include <array> // array
5410
#include <cmath> // ldexp
5411
#include <cstddef> // size_t
5412
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5413
#include <cstdio> // snprintf
5414
#include <cstring> // memcpy
5415
#include <iterator> // back_inserter
5416
#include <limits> // numeric_limits
5417
#include <string> // char_traits, string
5418
#include <utility> // make_pair, move
5419
#include <vector> // vector
5420
5421
// #include <nlohmann/detail/exceptions.hpp>
5422
5423
// #include <nlohmann/detail/input/input_adapters.hpp>
5424
5425
5426
#include <array> // array
5427
#include <cstddef> // size_t
5428
#include <cstring> // strlen
5429
#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5430
#include <memory> // shared_ptr, make_shared, addressof
5431
#include <numeric> // accumulate
5432
#include <string> // string, char_traits
5433
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5434
#include <utility> // pair, declval
5435
5436
#ifndef JSON_NO_IO
5437
    #include <cstdio>   // FILE *
5438
    #include <istream>  // istream
5439
#endif                  // JSON_NO_IO
5440
5441
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5442
5443
// #include <nlohmann/detail/macro_scope.hpp>
5444
5445
5446
namespace nlohmann
5447
{
5448
namespace detail
5449
{
5450
/// the supported input formats
5451
enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5452
5453
////////////////////
5454
// input adapters //
5455
////////////////////
5456
5457
#ifndef JSON_NO_IO
5458
/*!
5459
Input adapter for stdio file access. This adapter read only 1 byte and do not use any
5460
 buffer. This adapter is a very low level adapter.
5461
*/
5462
class file_input_adapter
5463
{
5464
  public:
5465
    using char_type = char;
5466
5467
    JSON_HEDLEY_NON_NULL(2)
5468
    explicit file_input_adapter(std::FILE* f) noexcept
5469
        : m_file(f)
5470
0
    {}
5471
5472
    // make class move-only
5473
    file_input_adapter(const file_input_adapter&) = delete;
5474
    file_input_adapter(file_input_adapter&&) noexcept = default;
5475
    file_input_adapter& operator=(const file_input_adapter&) = delete;
5476
    file_input_adapter& operator=(file_input_adapter&&) = delete;
5477
    ~file_input_adapter() = default;
5478
5479
    std::char_traits<char>::int_type get_character() noexcept
5480
0
    {
5481
0
        return std::fgetc(m_file);
5482
0
    }
5483
5484
  private:
5485
    /// the file pointer to read from
5486
    std::FILE* m_file;
5487
};
5488
5489
5490
/*!
5491
Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
5492
beginning of input. Does not support changing the underlying std::streambuf
5493
in mid-input. Maintains underlying std::istream and std::streambuf to support
5494
subsequent use of standard std::istream operations to process any input
5495
characters following those used in parsing the JSON input.  Clears the
5496
std::istream flags; any input errors (e.g., EOF) will be detected by the first
5497
subsequent call for input from the std::istream.
5498
*/
5499
class input_stream_adapter
5500
{
5501
  public:
5502
    using char_type = char;
5503
5504
    ~input_stream_adapter()
5505
0
    {
5506
0
        // clear stream flags; we use underlying streambuf I/O, do not
5507
0
        // maintain ifstream flags, except eof
5508
0
        if (is != nullptr)
5509
0
        {
5510
0
            is->clear(is->rdstate() & std::ios::eofbit);
5511
0
        }
5512
0
    }
5513
5514
    explicit input_stream_adapter(std::istream& i)
5515
        : is(&i), sb(i.rdbuf())
5516
0
    {}
5517
5518
    // delete because of pointer members
5519
    input_stream_adapter(const input_stream_adapter&) = delete;
5520
    input_stream_adapter& operator=(input_stream_adapter&) = delete;
5521
    input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5522
5523
    input_stream_adapter(input_stream_adapter&& rhs) noexcept
5524
        : is(rhs.is), sb(rhs.sb)
5525
0
    {
5526
0
        rhs.is = nullptr;
5527
0
        rhs.sb = nullptr;
5528
0
    }
5529
5530
    // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5531
    // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5532
    // end up as the same value, eg. 0xFFFFFFFF.
5533
    std::char_traits<char>::int_type get_character()
5534
0
    {
5535
0
        auto res = sb->sbumpc();
5536
0
        // set eof manually, as we don't use the istream interface.
5537
0
        if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5538
0
        {
5539
0
            is->clear(is->rdstate() | std::ios::eofbit);
5540
0
        }
5541
0
        return res;
5542
0
    }
5543
5544
  private:
5545
    /// the associated input stream
5546
    std::istream* is = nullptr;
5547
    std::streambuf* sb = nullptr;
5548
};
5549
#endif  // JSON_NO_IO
5550
5551
// General-purpose iterator-based adapter. It might not be as fast as
5552
// theoretically possible for some containers, but it is extremely versatile.
5553
template<typename IteratorType>
5554
class iterator_input_adapter
5555
{
5556
  public:
5557
    using char_type = typename std::iterator_traits<IteratorType>::value_type;
5558
5559
    iterator_input_adapter(IteratorType first, IteratorType last)
5560
        : current(std::move(first)), end(std::move(last))
5561
1.82k
    {}
5562
5563
    typename std::char_traits<char_type>::int_type get_character()
5564
96.9M
    {
5565
96.9M
        if (JSON_HEDLEY_LIKELY(current != end))
5566
96.9M
        {
5567
96.9M
            auto result = std::char_traits<char_type>::to_int_type(*current);
5568
96.9M
            std::advance(current, 1);
5569
96.9M
            return result;
5570
96.9M
        }
5571
5572
1.66k
        return std::char_traits<char_type>::eof();
5573
96.9M
    }
5574
5575
  private:
5576
    IteratorType current;
5577
    IteratorType end;
5578
5579
    template<typename BaseInputAdapter, size_t T>
5580
    friend struct wide_string_input_helper;
5581
5582
    bool empty() const
5583
    {
5584
        return current == end;
5585
    }
5586
};
5587
5588
5589
template<typename BaseInputAdapter, size_t T>
5590
struct wide_string_input_helper;
5591
5592
template<typename BaseInputAdapter>
5593
struct wide_string_input_helper<BaseInputAdapter, 4>
5594
{
5595
    // UTF-32
5596
    static void fill_buffer(BaseInputAdapter& input,
5597
                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5598
                            size_t& utf8_bytes_index,
5599
                            size_t& utf8_bytes_filled)
5600
    {
5601
        utf8_bytes_index = 0;
5602
5603
        if (JSON_HEDLEY_UNLIKELY(input.empty()))
5604
        {
5605
            utf8_bytes[0] = std::char_traits<char>::eof();
5606
            utf8_bytes_filled = 1;
5607
        }
5608
        else
5609
        {
5610
            // get the current character
5611
            const auto wc = input.get_character();
5612
5613
            // UTF-32 to UTF-8 encoding
5614
            if (wc < 0x80)
5615
            {
5616
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5617
                utf8_bytes_filled = 1;
5618
            }
5619
            else if (wc <= 0x7FF)
5620
            {
5621
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5622
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5623
                utf8_bytes_filled = 2;
5624
            }
5625
            else if (wc <= 0xFFFF)
5626
            {
5627
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5628
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5629
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5630
                utf8_bytes_filled = 3;
5631
            }
5632
            else if (wc <= 0x10FFFF)
5633
            {
5634
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5635
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5636
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5637
                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5638
                utf8_bytes_filled = 4;
5639
            }
5640
            else
5641
            {
5642
                // unknown character
5643
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5644
                utf8_bytes_filled = 1;
5645
            }
5646
        }
5647
    }
5648
};
5649
5650
template<typename BaseInputAdapter>
5651
struct wide_string_input_helper<BaseInputAdapter, 2>
5652
{
5653
    // UTF-16
5654
    static void fill_buffer(BaseInputAdapter& input,
5655
                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5656
                            size_t& utf8_bytes_index,
5657
                            size_t& utf8_bytes_filled)
5658
    {
5659
        utf8_bytes_index = 0;
5660
5661
        if (JSON_HEDLEY_UNLIKELY(input.empty()))
5662
        {
5663
            utf8_bytes[0] = std::char_traits<char>::eof();
5664
            utf8_bytes_filled = 1;
5665
        }
5666
        else
5667
        {
5668
            // get the current character
5669
            const auto wc = input.get_character();
5670
5671
            // UTF-16 to UTF-8 encoding
5672
            if (wc < 0x80)
5673
            {
5674
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5675
                utf8_bytes_filled = 1;
5676
            }
5677
            else if (wc <= 0x7FF)
5678
            {
5679
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5680
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5681
                utf8_bytes_filled = 2;
5682
            }
5683
            else if (0xD800 > wc || wc >= 0xE000)
5684
            {
5685
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5686
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5687
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5688
                utf8_bytes_filled = 3;
5689
            }
5690
            else
5691
            {
5692
                if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5693
                {
5694
                    const auto wc2 = static_cast<unsigned int>(input.get_character());
5695
                    const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5696
                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5697
                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5698
                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5699
                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5700
                    utf8_bytes_filled = 4;
5701
                }
5702
                else
5703
                {
5704
                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5705
                    utf8_bytes_filled = 1;
5706
                }
5707
            }
5708
        }
5709
    }
5710
};
5711
5712
// Wraps another input apdater to convert wide character types into individual bytes.
5713
template<typename BaseInputAdapter, typename WideCharType>
5714
class wide_string_input_adapter
5715
{
5716
  public:
5717
    using char_type = char;
5718
5719
    wide_string_input_adapter(BaseInputAdapter base)
5720
        : base_adapter(base) {}
5721
5722
    typename std::char_traits<char>::int_type get_character() noexcept
5723
    {
5724
        // check if buffer needs to be filled
5725
        if (utf8_bytes_index == utf8_bytes_filled)
5726
        {
5727
            fill_buffer<sizeof(WideCharType)>();
5728
5729
            JSON_ASSERT(utf8_bytes_filled > 0);
5730
            JSON_ASSERT(utf8_bytes_index == 0);
5731
        }
5732
5733
        // use buffer
5734
        JSON_ASSERT(utf8_bytes_filled > 0);
5735
        JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5736
        return utf8_bytes[utf8_bytes_index++];
5737
    }
5738
5739
  private:
5740
    BaseInputAdapter base_adapter;
5741
5742
    template<size_t T>
5743
    void fill_buffer()
5744
    {
5745
        wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5746
    }
5747
5748
    /// a buffer for UTF-8 bytes
5749
    std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5750
5751
    /// index to the utf8_codes array for the next valid byte
5752
    std::size_t utf8_bytes_index = 0;
5753
    /// number of valid bytes in the utf8_codes array
5754
    std::size_t utf8_bytes_filled = 0;
5755
};
5756
5757
5758
template<typename IteratorType, typename Enable = void>
5759
struct iterator_input_adapter_factory
5760
{
5761
    using iterator_type = IteratorType;
5762
    using char_type = typename std::iterator_traits<iterator_type>::value_type;
5763
    using adapter_type = iterator_input_adapter<iterator_type>;
5764
5765
    static adapter_type create(IteratorType first, IteratorType last)
5766
1.82k
    {
5767
1.82k
        return adapter_type(std::move(first), std::move(last));
5768
1.82k
    }
5769
};
5770
5771
template<typename T>
5772
struct is_iterator_of_multibyte
5773
{
5774
    using value_type = typename std::iterator_traits<T>::value_type;
5775
    enum
5776
    {
5777
        value = sizeof(value_type) > 1
5778
    };
5779
};
5780
5781
template<typename IteratorType>
5782
struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5783
{
5784
    using iterator_type = IteratorType;
5785
    using char_type = typename std::iterator_traits<iterator_type>::value_type;
5786
    using base_adapter_type = iterator_input_adapter<iterator_type>;
5787
    using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5788
5789
    static adapter_type create(IteratorType first, IteratorType last)
5790
    {
5791
        return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5792
    }
5793
};
5794
5795
// General purpose iterator-based input
5796
template<typename IteratorType>
5797
typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5798
1.82k
{
5799
1.82k
    using factory_type = iterator_input_adapter_factory<IteratorType>;
5800
1.82k
    return factory_type::create(first, last);
5801
1.82k
}
5802
5803
// Convenience shorthand from container to iterator
5804
// Enables ADL on begin(container) and end(container)
5805
// Encloses the using declarations in namespace for not to leak them to outside scope
5806
5807
namespace container_input_adapter_factory_impl
5808
{
5809
5810
using std::begin;
5811
using std::end;
5812
5813
template<typename ContainerType, typename Enable = void>
5814
struct container_input_adapter_factory {};
5815
5816
template<typename ContainerType>
5817
struct container_input_adapter_factory< ContainerType,
5818
       void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5819
       {
5820
           using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5821
5822
           static adapter_type create(const ContainerType& container)
5823
{
5824
    return input_adapter(begin(container), end(container));
5825
}
5826
       };
5827
5828
} // namespace container_input_adapter_factory_impl
5829
5830
template<typename ContainerType>
5831
typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5832
{
5833
    return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5834
}
5835
5836
#ifndef JSON_NO_IO
5837
// Special cases with fast paths
5838
inline file_input_adapter input_adapter(std::FILE* file)
5839
0
{
5840
0
    return file_input_adapter(file);
5841
0
}
5842
5843
inline input_stream_adapter input_adapter(std::istream& stream)
5844
0
{
5845
0
    return input_stream_adapter(stream);
5846
0
}
5847
5848
inline input_stream_adapter input_adapter(std::istream&& stream)
5849
0
{
5850
0
    return input_stream_adapter(stream);
5851
0
}
5852
#endif  // JSON_NO_IO
5853
5854
using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5855
5856
// Null-delimited strings, and the like.
5857
template < typename CharT,
5858
           typename std::enable_if <
5859
               std::is_pointer<CharT>::value&&
5860
               !std::is_array<CharT>::value&&
5861
               std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5862
               sizeof(typename std::remove_pointer<CharT>::type) == 1,
5863
               int >::type = 0 >
5864
contiguous_bytes_input_adapter input_adapter(CharT b)
5865
{
5866
    auto length = std::strlen(reinterpret_cast<const char*>(b));
5867
    const auto* ptr = reinterpret_cast<const char*>(b);
5868
    return input_adapter(ptr, ptr + length);
5869
}
5870
5871
template<typename T, std::size_t N>
5872
auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5873
{
5874
    return input_adapter(array, array + N);
5875
}
5876
5877
// This class only handles inputs of input_buffer_adapter type.
5878
// It's required so that expressions like {ptr, len} can be implicitely casted
5879
// to the correct adapter.
5880
class span_input_adapter
5881
{
5882
  public:
5883
    template < typename CharT,
5884
               typename std::enable_if <
5885
                   std::is_pointer<CharT>::value&&
5886
                   std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5887
                   sizeof(typename std::remove_pointer<CharT>::type) == 1,
5888
                   int >::type = 0 >
5889
    span_input_adapter(CharT b, std::size_t l)
5890
        : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5891
5892
    template<class IteratorType,
5893
             typename std::enable_if<
5894
                 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5895
                 int>::type = 0>
5896
    span_input_adapter(IteratorType first, IteratorType last)
5897
        : ia(input_adapter(first, last)) {}
5898
5899
    contiguous_bytes_input_adapter&& get()
5900
0
    {
5901
0
        return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5902
0
    }
5903
5904
  private:
5905
    contiguous_bytes_input_adapter ia;
5906
};
5907
}  // namespace detail
5908
}  // namespace nlohmann
5909
5910
// #include <nlohmann/detail/input/json_sax.hpp>
5911
5912
5913
#include <cstddef>
5914
#include <string> // string
5915
#include <utility> // move
5916
#include <vector> // vector
5917
5918
// #include <nlohmann/detail/exceptions.hpp>
5919
5920
// #include <nlohmann/detail/macro_scope.hpp>
5921
5922
5923
namespace nlohmann
5924
{
5925
5926
/*!
5927
@brief SAX interface
5928
5929
This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
5930
Each function is called in different situations while the input is parsed. The
5931
boolean return value informs the parser whether to continue processing the
5932
input.
5933
*/
5934
template<typename BasicJsonType>
5935
struct json_sax
5936
{
5937
    using number_integer_t = typename BasicJsonType::number_integer_t;
5938
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5939
    using number_float_t = typename BasicJsonType::number_float_t;
5940
    using string_t = typename BasicJsonType::string_t;
5941
    using binary_t = typename BasicJsonType::binary_t;
5942
5943
    /*!
5944
    @brief a null value was read
5945
    @return whether parsing should proceed
5946
    */
5947
    virtual bool null() = 0;
5948
5949
    /*!
5950
    @brief a boolean value was read
5951
    @param[in] val  boolean value
5952
    @return whether parsing should proceed
5953
    */
5954
    virtual bool boolean(bool val) = 0;
5955
5956
    /*!
5957
    @brief an integer number was read
5958
    @param[in] val  integer value
5959
    @return whether parsing should proceed
5960
    */
5961
    virtual bool number_integer(number_integer_t val) = 0;
5962
5963
    /*!
5964
    @brief an unsigned integer number was read
5965
    @param[in] val  unsigned integer value
5966
    @return whether parsing should proceed
5967
    */
5968
    virtual bool number_unsigned(number_unsigned_t val) = 0;
5969
5970
    /*!
5971
    @brief an floating-point number was read
5972
    @param[in] val  floating-point value
5973
    @param[in] s    raw token value
5974
    @return whether parsing should proceed
5975
    */
5976
    virtual bool number_float(number_float_t val, const string_t& s) = 0;
5977
5978
    /*!
5979
    @brief a string was read
5980
    @param[in] val  string value
5981
    @return whether parsing should proceed
5982
    @note It is safe to move the passed string.
5983
    */
5984
    virtual bool string(string_t& val) = 0;
5985
5986
    /*!
5987
    @brief a binary string was read
5988
    @param[in] val  binary value
5989
    @return whether parsing should proceed
5990
    @note It is safe to move the passed binary.
5991
    */
5992
    virtual bool binary(binary_t& val) = 0;
5993
5994
    /*!
5995
    @brief the beginning of an object was read
5996
    @param[in] elements  number of object elements or -1 if unknown
5997
    @return whether parsing should proceed
5998
    @note binary formats may report the number of elements
5999
    */
6000
    virtual bool start_object(std::size_t elements) = 0;
6001
6002
    /*!
6003
    @brief an object key was read
6004
    @param[in] val  object key
6005
    @return whether parsing should proceed
6006
    @note It is safe to move the passed string.
6007
    */
6008
    virtual bool key(string_t& val) = 0;
6009
6010
    /*!
6011
    @brief the end of an object was read
6012
    @return whether parsing should proceed
6013
    */
6014
    virtual bool end_object() = 0;
6015
6016
    /*!
6017
    @brief the beginning of an array was read
6018
    @param[in] elements  number of array elements or -1 if unknown
6019
    @return whether parsing should proceed
6020
    @note binary formats may report the number of elements
6021
    */
6022
    virtual bool start_array(std::size_t elements) = 0;
6023
6024
    /*!
6025
    @brief the end of an array was read
6026
    @return whether parsing should proceed
6027
    */
6028
    virtual bool end_array() = 0;
6029
6030
    /*!
6031
    @brief a parse error occurred
6032
    @param[in] position    the position in the input where the error occurs
6033
    @param[in] last_token  the last read token
6034
    @param[in] ex          an exception object describing the error
6035
    @return whether parsing should proceed (must return false)
6036
    */
6037
    virtual bool parse_error(std::size_t position,
6038
                             const std::string& last_token,
6039
                             const detail::exception& ex) = 0;
6040
6041
    json_sax() = default;
6042
    json_sax(const json_sax&) = default;
6043
    json_sax(json_sax&&) noexcept = default;
6044
    json_sax& operator=(const json_sax&) = default;
6045
    json_sax& operator=(json_sax&&) noexcept = default;
6046
    virtual ~json_sax() = default;
6047
};
6048
6049
6050
namespace detail
6051
{
6052
/*!
6053
@brief SAX implementation to create a JSON value from SAX events
6054
6055
This class implements the @ref json_sax interface and processes the SAX events
6056
to create a JSON value which makes it basically a DOM parser. The structure or
6057
hierarchy of the JSON value is managed by the stack `ref_stack` which contains
6058
a pointer to the respective array or object for each recursion depth.
6059
6060
After successful parsing, the value that is passed by reference to the
6061
constructor contains the parsed value.
6062
6063
@tparam BasicJsonType  the JSON type
6064
*/
6065
template<typename BasicJsonType>
6066
class json_sax_dom_parser
6067
{
6068
  public:
6069
    using number_integer_t = typename BasicJsonType::number_integer_t;
6070
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6071
    using number_float_t = typename BasicJsonType::number_float_t;
6072
    using string_t = typename BasicJsonType::string_t;
6073
    using binary_t = typename BasicJsonType::binary_t;
6074
6075
    /*!
6076
    @param[in,out] r  reference to a JSON value that is manipulated while
6077
                       parsing
6078
    @param[in] allow_exceptions_  whether parse errors yield exceptions
6079
    */
6080
    explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6081
        : root(r), allow_exceptions(allow_exceptions_)
6082
1.82k
    {}
6083
6084
    // make class move-only
6085
    json_sax_dom_parser(const json_sax_dom_parser&) = delete;
6086
    json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6087
    json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
6088
    json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6089
1.82k
    ~json_sax_dom_parser() = default;
6090
6091
    bool null()
6092
23.6k
    {
6093
23.6k
        handle_value(nullptr);
6094
23.6k
        return true;
6095
23.6k
    }
6096
6097
    bool boolean(bool val)
6098
22.8k
    {
6099
22.8k
        handle_value(val);
6100
22.8k
        return true;
6101
22.8k
    }
6102
6103
    bool number_integer(number_integer_t val)
6104
20.4k
    {
6105
20.4k
        handle_value(val);
6106
20.4k
        return true;
6107
20.4k
    }
6108
6109
    bool number_unsigned(number_unsigned_t val)
6110
6.13M
    {
6111
6.13M
        handle_value(val);
6112
6.13M
        return true;
6113
6.13M
    }
6114
6115
    bool number_float(number_float_t val, const string_t& /*unused*/)
6116
50.0k
    {
6117
50.0k
        handle_value(val);
6118
50.0k
        return true;
6119
50.0k
    }
6120
6121
    bool string(string_t& val)
6122
71.5k
    {
6123
71.5k
        handle_value(val);
6124
71.5k
        return true;
6125
71.5k
    }
6126
6127
    bool binary(binary_t& val)
6128
    {
6129
        handle_value(std::move(val));
6130
        return true;
6131
    }
6132
6133
    bool start_object(std::size_t len)
6134
1.55M
    {
6135
1.55M
        ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6136
6137
1.55M
        if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6138
0
        {
6139
0
            JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6140
0
        }
6141
6142
1.55M
        return true;
6143
1.55M
    }
6144
6145
    bool key(string_t& val)
6146
488k
    {
6147
        // add null at given key and store the reference for later
6148
488k
        object_element = &(ref_stack.back()->m_value.object->operator[](val));
6149
488k
        return true;
6150
488k
    }
6151
6152
    bool end_object()
6153
1.32M
    {
6154
1.32M
        ref_stack.back()->set_parents();
6155
1.32M
        ref_stack.pop_back();
6156
1.32M
        return true;
6157
1.32M
    }
6158
6159
    bool start_array(std::size_t len)
6160
5.67M
    {
6161
5.67M
        ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6162
6163
5.67M
        if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6164
0
        {
6165
0
            JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6166
0
        }
6167
6168
5.67M
        return true;
6169
5.67M
    }
6170
6171
    bool end_array()
6172
57.8k
    {
6173
57.8k
        ref_stack.back()->set_parents();
6174
57.8k
        ref_stack.pop_back();
6175
57.8k
        return true;
6176
57.8k
    }
6177
6178
    template<class Exception>
6179
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6180
                     const Exception& ex)
6181
214
    {
6182
214
        errored = true;
6183
214
        static_cast<void>(ex);
6184
214
        if (allow_exceptions)
6185
214
        {
6186
214
            JSON_THROW(ex);
6187
214
        }
6188
0
        return false;
6189
214
    }
bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::parse_error<nlohmann::detail::out_of_range>(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, nlohmann::detail::out_of_range const&)
Line
Count
Source
6181
4
    {
6182
4
        errored = true;
6183
4
        static_cast<void>(ex);
6184
4
        if (allow_exceptions)
6185
4
        {
6186
4
            JSON_THROW(ex);
6187
4
        }
6188
0
        return false;
6189
4
    }
bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::parse_error<nlohmann::detail::parse_error>(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, nlohmann::detail::parse_error const&)
Line
Count
Source
6181
210
    {
6182
210
        errored = true;
6183
210
        static_cast<void>(ex);
6184
210
        if (allow_exceptions)
6185
210
        {
6186
210
            JSON_THROW(ex);
6187
210
        }
6188
0
        return false;
6189
210
    }
6190
6191
    constexpr bool is_errored() const
6192
1.60k
    {
6193
1.60k
        return errored;
6194
1.60k
    }
6195
6196
  private:
6197
    /*!
6198
    @invariant If the ref stack is empty, then the passed value will be the new
6199
               root.
6200
    @invariant If the ref stack contains a value, then it is an array or an
6201
               object to which we can add elements
6202
    */
6203
    template<typename Value>
6204
    JSON_HEDLEY_RETURNS_NON_NULL
6205
    BasicJsonType* handle_value(Value&& v)
6206
13.5M
    {
6207
13.5M
        if (ref_stack.empty())
6208
1.80k
        {
6209
1.80k
            root = BasicJsonType(std::forward<Value>(v));
6210
1.80k
            return &root;
6211
1.80k
        }
6212
6213
13.5M
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215
13.5M
        if (ref_stack.back()->is_array())
6216
13.0M
        {
6217
13.0M
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218
13.0M
            return &(ref_stack.back()->m_value.array->back());
6219
13.0M
        }
6220
6221
488k
        JSON_ASSERT(ref_stack.back()->is_object());
6222
488k
        JSON_ASSERT(object_element);
6223
0
        *object_element = BasicJsonType(std::forward<Value>(v));
6224
488k
        return object_element;
6225
13.5M
    }
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<unsigned char, std::__1::allocator<unsigned char> > >* 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<nlohmann::detail::value_t>(nlohmann::detail::value_t&&)
Line
Count
Source
6206
7.23M
    {
6207
7.23M
        if (ref_stack.empty())
6208
1.80k
        {
6209
1.80k
            root = BasicJsonType(std::forward<Value>(v));
6210
1.80k
            return &root;
6211
1.80k
        }
6212
6213
7.22M
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215
7.22M
        if (ref_stack.back()->is_array())
6216
6.94M
        {
6217
6.94M
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218
6.94M
            return &(ref_stack.back()->m_value.array->back());
6219
6.94M
        }
6220
6221
286k
        JSON_ASSERT(ref_stack.back()->is_object());
6222
286k
        JSON_ASSERT(object_element);
6223
0
        *object_element = BasicJsonType(std::forward<Value>(v));
6224
286k
        return object_element;
6225
7.22M
    }
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<unsigned char, std::__1::allocator<unsigned char> > >* 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<double&>(double&)
Line
Count
Source
6206
50.0k
    {
6207
50.0k
        if (ref_stack.empty())
6208
0
        {
6209
0
            root = BasicJsonType(std::forward<Value>(v));
6210
0
            return &root;
6211
0
        }
6212
6213
50.0k
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215
50.0k
        if (ref_stack.back()->is_array())
6216
48.2k
        {
6217
48.2k
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218
48.2k
            return &(ref_stack.back()->m_value.array->back());
6219
48.2k
        }
6220
6221
1.77k
        JSON_ASSERT(ref_stack.back()->is_object());
6222
1.77k
        JSON_ASSERT(object_element);
6223
0
        *object_element = BasicJsonType(std::forward<Value>(v));
6224
1.77k
        return object_element;
6225
50.0k
    }
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<unsigned char, std::__1::allocator<unsigned char> > >* 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<bool&>(bool&)
Line
Count
Source
6206
22.8k
    {
6207
22.8k
        if (ref_stack.empty())
6208
0
        {
6209
0
            root = BasicJsonType(std::forward<Value>(v));
6210
0
            return &root;
6211
0
        }
6212
6213
22.8k
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215
22.8k
        if (ref_stack.back()->is_array())
6216
22.4k
        {
6217
22.4k
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218
22.4k
            return &(ref_stack.back()->m_value.array->back());
6219
22.4k
        }
6220
6221
392
        JSON_ASSERT(ref_stack.back()->is_object());
6222
392
        JSON_ASSERT(object_element);
6223
0
        *object_element = BasicJsonType(std::forward<Value>(v));
6224
392
        return object_element;
6225
22.8k
    }
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<unsigned char, std::__1::allocator<unsigned char> > >* 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<decltype(nullptr)>(decltype(nullptr)&&)
Line
Count
Source
6206
23.6k
    {
6207
23.6k
        if (ref_stack.empty())
6208
0
        {
6209
0
            root = BasicJsonType(std::forward<Value>(v));
6210
0
            return &root;
6211
0
        }
6212
6213
23.6k
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215
23.6k
        if (ref_stack.back()->is_array())
6216
23.4k
        {
6217
23.4k
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218
23.4k
            return &(ref_stack.back()->m_value.array->back());
6219
23.4k
        }
6220
6221
135
        JSON_ASSERT(ref_stack.back()->is_object());
6222
135
        JSON_ASSERT(object_element);
6223
0
        *object_element = BasicJsonType(std::forward<Value>(v));
6224
135
        return object_element;
6225
23.6k
    }
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<unsigned char, std::__1::allocator<unsigned char> > >* 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<long&>(long&)
Line
Count
Source
6206
20.4k
    {
6207
20.4k
        if (ref_stack.empty())
6208
0
        {
6209
0
            root = BasicJsonType(std::forward<Value>(v));
6210
0
            return &root;
6211
0
        }
6212
6213
20.4k
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215
20.4k
        if (ref_stack.back()->is_array())
6216
13.7k
        {
6217
13.7k
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218
13.7k
            return &(ref_stack.back()->m_value.array->back());
6219
13.7k
        }
6220
6221
6.74k
        JSON_ASSERT(ref_stack.back()->is_object());
6222
6.74k
        JSON_ASSERT(object_element);
6223
0
        *object_element = BasicJsonType(std::forward<Value>(v));
6224
6.74k
        return object_element;
6225
20.4k
    }
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<unsigned char, std::__1::allocator<unsigned char> > >* 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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> >&)
Line
Count
Source
6206
71.5k
    {
6207
71.5k
        if (ref_stack.empty())
6208
0
        {
6209
0
            root = BasicJsonType(std::forward<Value>(v));
6210
0
            return &root;
6211
0
        }
6212
6213
71.5k
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215
71.5k
        if (ref_stack.back()->is_array())
6216
787
        {
6217
787
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218
787
            return &(ref_stack.back()->m_value.array->back());
6219
787
        }
6220
6221
70.7k
        JSON_ASSERT(ref_stack.back()->is_object());
6222
70.7k
        JSON_ASSERT(object_element);
6223
0
        *object_element = BasicJsonType(std::forward<Value>(v));
6224
70.7k
        return object_element;
6225
71.5k
    }
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<unsigned char, std::__1::allocator<unsigned char> > >* 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<unsigned long&>(unsigned long&)
Line
Count
Source
6206
6.13M
    {
6207
6.13M
        if (ref_stack.empty())
6208
0
        {
6209
0
            root = BasicJsonType(std::forward<Value>(v));
6210
0
            return &root;
6211
0
        }
6212
6213
6.13M
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215
6.13M
        if (ref_stack.back()->is_array())
6216
6.00M
        {
6217
6.00M
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218
6.00M
            return &(ref_stack.back()->m_value.array->back());
6219
6.00M
        }
6220
6221
122k
        JSON_ASSERT(ref_stack.back()->is_object());
6222
122k
        JSON_ASSERT(object_element);
6223
0
        *object_element = BasicJsonType(std::forward<Value>(v));
6224
122k
        return object_element;
6225
6.13M
    }
6226
6227
    /// the parsed JSON value
6228
    BasicJsonType& root;
6229
    /// stack to model hierarchy of values
6230
    std::vector<BasicJsonType*> ref_stack {};
6231
    /// helper to hold the reference for the next object element
6232
    BasicJsonType* object_element = nullptr;
6233
    /// whether a syntax error occurred
6234
    bool errored = false;
6235
    /// whether to throw exceptions in case of errors
6236
    const bool allow_exceptions = true;
6237
};
6238
6239
template<typename BasicJsonType>
6240
class json_sax_dom_callback_parser
6241
{
6242
  public:
6243
    using number_integer_t = typename BasicJsonType::number_integer_t;
6244
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6245
    using number_float_t = typename BasicJsonType::number_float_t;
6246
    using string_t = typename BasicJsonType::string_t;
6247
    using binary_t = typename BasicJsonType::binary_t;
6248
    using parser_callback_t = typename BasicJsonType::parser_callback_t;
6249
    using parse_event_t = typename BasicJsonType::parse_event_t;
6250
6251
    json_sax_dom_callback_parser(BasicJsonType& r,
6252
                                 const parser_callback_t cb,
6253
                                 const bool allow_exceptions_ = true)
6254
        : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6255
0
    {
6256
0
        keep_stack.push_back(true);
6257
0
    }
6258
6259
    // make class move-only
6260
    json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6261
    json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6262
    json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6263
    json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6264
0
    ~json_sax_dom_callback_parser() = default;
6265
6266
    bool null()
6267
0
    {
6268
0
        handle_value(nullptr);
6269
0
        return true;
6270
0
    }
6271
6272
    bool boolean(bool val)
6273
0
    {
6274
0
        handle_value(val);
6275
0
        return true;
6276
0
    }
6277
6278
    bool number_integer(number_integer_t val)
6279
0
    {
6280
0
        handle_value(val);
6281
0
        return true;
6282
0
    }
6283
6284
    bool number_unsigned(number_unsigned_t val)
6285
0
    {
6286
0
        handle_value(val);
6287
0
        return true;
6288
0
    }
6289
6290
    bool number_float(number_float_t val, const string_t& /*unused*/)
6291
0
    {
6292
0
        handle_value(val);
6293
0
        return true;
6294
0
    }
6295
6296
    bool string(string_t& val)
6297
0
    {
6298
0
        handle_value(val);
6299
0
        return true;
6300
0
    }
6301
6302
    bool binary(binary_t& val)
6303
    {
6304
        handle_value(std::move(val));
6305
        return true;
6306
    }
6307
6308
    bool start_object(std::size_t len)
6309
0
    {
6310
        // check callback for object start
6311
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6312
0
        keep_stack.push_back(keep);
6313
6314
0
        auto val = handle_value(BasicJsonType::value_t::object, true);
6315
0
        ref_stack.push_back(val.second);
6316
6317
        // check object limit
6318
0
        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6319
0
        {
6320
0
            JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6321
0
        }
6322
6323
0
        return true;
6324
0
    }
6325
6326
    bool key(string_t& val)
6327
0
    {
6328
0
        BasicJsonType k = BasicJsonType(val);
6329
6330
        // check callback for key
6331
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6332
0
        key_keep_stack.push_back(keep);
6333
6334
        // add discarded value at given key and store the reference for later
6335
0
        if (keep && ref_stack.back())
6336
0
        {
6337
0
            object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6338
0
        }
6339
6340
0
        return true;
6341
0
    }
6342
6343
    bool end_object()
6344
0
    {
6345
0
        if (ref_stack.back())
6346
0
        {
6347
0
            if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6348
0
            {
6349
                // discard object
6350
0
                *ref_stack.back() = discarded;
6351
0
            }
6352
0
            else
6353
0
            {
6354
0
                ref_stack.back()->set_parents();
6355
0
            }
6356
0
        }
6357
6358
0
        JSON_ASSERT(!ref_stack.empty());
6359
0
        JSON_ASSERT(!keep_stack.empty());
6360
0
        ref_stack.pop_back();
6361
0
        keep_stack.pop_back();
6362
6363
0
        if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6364
0
        {
6365
            // remove discarded value
6366
0
            for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6367
0
            {
6368
0
                if (it->is_discarded())
6369
0
                {
6370
0
                    ref_stack.back()->erase(it);
6371
0
                    break;
6372
0
                }
6373
0
            }
6374
0
        }
6375
6376
0
        return true;
6377
0
    }
6378
6379
    bool start_array(std::size_t len)
6380
0
    {
6381
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6382
0
        keep_stack.push_back(keep);
6383
6384
0
        auto val = handle_value(BasicJsonType::value_t::array, true);
6385
0
        ref_stack.push_back(val.second);
6386
6387
        // check array limit
6388
0
        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6389
0
        {
6390
0
            JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6391
0
        }
6392
6393
0
        return true;
6394
0
    }
6395
6396
    bool end_array()
6397
0
    {
6398
0
        bool keep = true;
6399
6400
0
        if (ref_stack.back())
6401
0
        {
6402
0
            keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6403
0
            if (keep)
6404
0
            {
6405
0
                ref_stack.back()->set_parents();
6406
0
            }
6407
0
            else
6408
0
            {
6409
                // discard array
6410
0
                *ref_stack.back() = discarded;
6411
0
            }
6412
0
        }
6413
6414
0
        JSON_ASSERT(!ref_stack.empty());
6415
0
        JSON_ASSERT(!keep_stack.empty());
6416
0
        ref_stack.pop_back();
6417
0
        keep_stack.pop_back();
6418
6419
        // remove discarded value
6420
0
        if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6421
0
        {
6422
0
            ref_stack.back()->m_value.array->pop_back();
6423
0
        }
6424
6425
0
        return true;
6426
0
    }
6427
6428
    template<class Exception>
6429
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6430
                     const Exception& ex)
6431
0
    {
6432
0
        errored = true;
6433
0
        static_cast<void>(ex);
6434
0
        if (allow_exceptions)
6435
0
        {
6436
0
            JSON_THROW(ex);
6437
0
        }
6438
0
        return false;
6439
0
    }
Unexecuted instantiation: bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::parse_error<nlohmann::detail::out_of_range>(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, nlohmann::detail::out_of_range const&)
Unexecuted instantiation: bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::parse_error<nlohmann::detail::parse_error>(unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, nlohmann::detail::parse_error const&)
6440
6441
    constexpr bool is_errored() const
6442
0
    {
6443
0
        return errored;
6444
0
    }
6445
6446
  private:
6447
    /*!
6448
    @param[in] v  value to add to the JSON value we build during parsing
6449
    @param[in] skip_callback  whether we should skip calling the callback
6450
               function; this is required after start_array() and
6451
               start_object() SAX events, because otherwise we would call the
6452
               callback function with an empty array or object, respectively.
6453
6454
    @invariant If the ref stack is empty, then the passed value will be the new
6455
               root.
6456
    @invariant If the ref stack contains a value, then it is an array or an
6457
               object to which we can add elements
6458
6459
    @return pair of boolean (whether value should be kept) and pointer (to the
6460
            passed value in the ref_stack hierarchy; nullptr if not kept)
6461
    */
6462
    template<typename Value>
6463
    std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6464
0
    {
6465
0
        JSON_ASSERT(!keep_stack.empty());
6466
6467
        // do not handle this value if we know it would be added to a discarded
6468
        // container
6469
0
        if (!keep_stack.back())
6470
0
        {
6471
0
            return {false, nullptr};
6472
0
        }
6473
6474
        // create value
6475
0
        auto value = BasicJsonType(std::forward<Value>(v));
6476
6477
        // check callback
6478
0
        const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6479
6480
        // do not handle this value if we just learnt it shall be discarded
6481
0
        if (!keep)
6482
0
        {
6483
0
            return {false, nullptr};
6484
0
        }
6485
6486
0
        if (ref_stack.empty())
6487
0
        {
6488
0
            root = std::move(value);
6489
0
            return {true, &root};
6490
0
        }
6491
6492
        // skip this value if we already decided to skip the parent
6493
        // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6494
0
        if (!ref_stack.back())
6495
0
        {
6496
0
            return {false, nullptr};
6497
0
        }
6498
6499
        // we now only expect arrays and objects
6500
0
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6501
6502
        // array
6503
0
        if (ref_stack.back()->is_array())
6504
0
        {
6505
0
            ref_stack.back()->m_value.array->emplace_back(std::move(value));
6506
0
            return {true, &(ref_stack.back()->m_value.array->back())};
6507
0
        }
6508
6509
        // object
6510
0
        JSON_ASSERT(ref_stack.back()->is_object());
6511
        // check if we should store an element for the current key
6512
0
        JSON_ASSERT(!key_keep_stack.empty());
6513
0
        const bool store_element = key_keep_stack.back();
6514
0
        key_keep_stack.pop_back();
6515
6516
0
        if (!store_element)
6517
0
        {
6518
0
            return {false, nullptr};
6519
0
        }
6520
6521
0
        JSON_ASSERT(object_element);
6522
0
        *object_element = std::move(value);
6523
0
        return {true, object_element};
6524
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*> 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*> 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*> 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*> 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*> 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*> 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*> 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::handle_value<unsigned long&>(unsigned long&, bool)
6525
6526
    /// the parsed JSON value
6527
    BasicJsonType& root;
6528
    /// stack to model hierarchy of values
6529
    std::vector<BasicJsonType*> ref_stack {};
6530
    /// stack to manage which values to keep
6531
    std::vector<bool> keep_stack {};
6532
    /// stack to manage which object keys to keep
6533
    std::vector<bool> key_keep_stack {};
6534
    /// helper to hold the reference for the next object element
6535
    BasicJsonType* object_element = nullptr;
6536
    /// whether a syntax error occurred
6537
    bool errored = false;
6538
    /// callback function
6539
    const parser_callback_t callback = nullptr;
6540
    /// whether to throw exceptions in case of errors
6541
    const bool allow_exceptions = true;
6542
    /// a discarded value for the callback
6543
    BasicJsonType discarded = BasicJsonType::value_t::discarded;
6544
};
6545
6546
template<typename BasicJsonType>
6547
class json_sax_acceptor
6548
{
6549
  public:
6550
    using number_integer_t = typename BasicJsonType::number_integer_t;
6551
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6552
    using number_float_t = typename BasicJsonType::number_float_t;
6553
    using string_t = typename BasicJsonType::string_t;
6554
    using binary_t = typename BasicJsonType::binary_t;
6555
6556
    bool null()
6557
    {
6558
        return true;
6559
    }
6560
6561
    bool boolean(bool /*unused*/)
6562
    {
6563
        return true;
6564
    }
6565
6566
    bool number_integer(number_integer_t /*unused*/)
6567
    {
6568
        return true;
6569
    }
6570
6571
    bool number_unsigned(number_unsigned_t /*unused*/)
6572
    {
6573
        return true;
6574
    }
6575
6576
    bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6577
    {
6578
        return true;
6579
    }
6580
6581
    bool string(string_t& /*unused*/)
6582
    {
6583
        return true;
6584
    }
6585
6586
    bool binary(binary_t& /*unused*/)
6587
    {
6588
        return true;
6589
    }
6590
6591
    bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6592
    {
6593
        return true;
6594
    }
6595
6596
    bool key(string_t& /*unused*/)
6597
    {
6598
        return true;
6599
    }
6600
6601
    bool end_object()
6602
    {
6603
        return true;
6604
    }
6605
6606
    bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6607
    {
6608
        return true;
6609
    }
6610
6611
    bool end_array()
6612
    {
6613
        return true;
6614
    }
6615
6616
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6617
    {
6618
        return false;
6619
    }
6620
};
6621
}  // namespace detail
6622
6623
}  // namespace nlohmann
6624
6625
// #include <nlohmann/detail/input/lexer.hpp>
6626
6627
6628
#include <array> // array
6629
#include <clocale> // localeconv
6630
#include <cstddef> // size_t
6631
#include <cstdio> // snprintf
6632
#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6633
#include <initializer_list> // initializer_list
6634
#include <string> // char_traits, string
6635
#include <utility> // move
6636
#include <vector> // vector
6637
6638
// #include <nlohmann/detail/input/input_adapters.hpp>
6639
6640
// #include <nlohmann/detail/input/position_t.hpp>
6641
6642
// #include <nlohmann/detail/macro_scope.hpp>
6643
6644
6645
namespace nlohmann
6646
{
6647
namespace detail
6648
{
6649
///////////
6650
// lexer //
6651
///////////
6652
6653
template<typename BasicJsonType>
6654
class lexer_base
6655
{
6656
  public:
6657
    /// token types for the parser
6658
    enum class token_type
6659
    {
6660
        uninitialized,    ///< indicating the scanner is uninitialized
6661
        literal_true,     ///< the `true` literal
6662
        literal_false,    ///< the `false` literal
6663
        literal_null,     ///< the `null` literal
6664
        value_string,     ///< a string -- use get_string() for actual value
6665
        value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
6666
        value_integer,    ///< a signed integer -- use get_number_integer() for actual value
6667
        value_float,      ///< an floating point number -- use get_number_float() for actual value
6668
        begin_array,      ///< the character for array begin `[`
6669
        begin_object,     ///< the character for object begin `{`
6670
        end_array,        ///< the character for array end `]`
6671
        end_object,       ///< the character for object end `}`
6672
        name_separator,   ///< the name separator `:`
6673
        value_separator,  ///< the value separator `,`
6674
        parse_error,      ///< indicating a parse error
6675
        end_of_input,     ///< indicating the end of the input buffer
6676
        literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
6677
    };
6678
6679
    /// return name of values of type token_type (only used for errors)
6680
    JSON_HEDLEY_RETURNS_NON_NULL
6681
    JSON_HEDLEY_CONST
6682
    static const char* token_type_name(const token_type t) noexcept
6683
268
    {
6684
268
        switch (t)
6685
268
        {
6686
0
            case token_type::uninitialized:
6687
0
                return "<uninitialized>";
6688
0
            case token_type::literal_true:
6689
0
                return "true literal";
6690
0
            case token_type::literal_false:
6691
0
                return "false literal";
6692
0
            case token_type::literal_null:
6693
0
                return "null literal";
6694
18
            case token_type::value_string:
6695
18
                return "string literal";
6696
7
            case token_type::value_unsigned:
6697
7
            case token_type::value_integer:
6698
7
            case token_type::value_float:
6699
7
                return "number literal";
6700
8
            case token_type::begin_array:
6701
8
                return "'['";
6702
2
            case token_type::begin_object:
6703
2
                return "'{'";
6704
75
            case token_type::end_array:
6705
75
                return "']'";
6706
16
            case token_type::end_object:
6707
16
                return "'}'";
6708
49
            case token_type::name_separator:
6709
49
                return "':'";
6710
3
            case token_type::value_separator:
6711
3
                return "','";
6712
0
            case token_type::parse_error:
6713
0
                return "<parse error>";
6714
61
            case token_type::end_of_input:
6715
61
                return "end of input";
6716
29
            case token_type::literal_or_value:
6717
29
                return "'[', '{', or a literal";
6718
            // LCOV_EXCL_START
6719
0
            default: // catch non-enum values
6720
0
                return "unknown token";
6721
                // LCOV_EXCL_STOP
6722
268
        }
6723
268
    }
6724
};
6725
/*!
6726
@brief lexical analysis
6727
6728
This class organizes the lexical analysis during JSON deserialization.
6729
*/
6730
template<typename BasicJsonType, typename InputAdapterType>
6731
class lexer : public lexer_base<BasicJsonType>
6732
{
6733
    using number_integer_t = typename BasicJsonType::number_integer_t;
6734
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6735
    using number_float_t = typename BasicJsonType::number_float_t;
6736
    using string_t = typename BasicJsonType::string_t;
6737
    using char_type = typename InputAdapterType::char_type;
6738
    using char_int_type = typename std::char_traits<char_type>::int_type;
6739
6740
  public:
6741
    using token_type = typename lexer_base<BasicJsonType>::token_type;
6742
6743
    explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6744
        : ia(std::move(adapter))
6745
        , ignore_comments(ignore_comments_)
6746
        , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6747
1.82k
    {}
6748
6749
    // delete because of pointer members
6750
    lexer(const lexer&) = delete;
6751
    lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6752
    lexer& operator=(lexer&) = delete;
6753
    lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6754
1.82k
    ~lexer() = default;
6755
6756
  private:
6757
    /////////////////////
6758
    // locales
6759
    /////////////////////
6760
6761
    /// return the locale-dependent decimal point
6762
    JSON_HEDLEY_PURE
6763
    static char get_decimal_point() noexcept
6764
1.82k
    {
6765
1.82k
        const auto* loc = localeconv();
6766
1.82k
        JSON_ASSERT(loc != nullptr);
6767
1.82k
        return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6768
1.82k
    }
6769
6770
    /////////////////////
6771
    // scan functions
6772
    /////////////////////
6773
6774
    /*!
6775
    @brief get codepoint from 4 hex characters following `\u`
6776
6777
    For input "\u c1 c2 c3 c4" the codepoint is:
6778
      (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
6779
    = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
6780
6781
    Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
6782
    must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
6783
    conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
6784
    between the ASCII value of the character and the desired integer value.
6785
6786
    @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
6787
            non-hex character)
6788
    */
6789
    int get_codepoint()
6790
7.75k
    {
6791
        // this function only makes sense after reading `\u`
6792
7.75k
        JSON_ASSERT(current == 'u');
6793
0
        int codepoint = 0;
6794
6795
7.75k
        const auto factors = { 12u, 8u, 4u, 0u };
6796
7.75k
        for (const auto factor : factors)
6797
31.0k
        {
6798
31.0k
            get();
6799
6800
31.0k
            if (current >= '0' && current <= '9')
6801
28.5k
            {
6802
28.5k
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6803
28.5k
            }
6804
2.42k
            else if (current >= 'A' && current <= 'F')
6805
170
            {
6806
170
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6807
170
            }
6808
2.25k
            else if (current >= 'a' && current <= 'f')
6809
2.25k
            {
6810
2.25k
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6811
2.25k
            }
6812
2
            else
6813
2
            {
6814
2
                return -1;
6815
2
            }
6816
31.0k
        }
6817
6818
7.75k
        JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6819
0
        return codepoint;
6820
7.75k
    }
6821
6822
    /*!
6823
    @brief check if the next byte(s) are inside a given range
6824
6825
    Adds the current byte and, for each passed range, reads a new byte and
6826
    checks if it is inside the range. If a violation was detected, set up an
6827
    error message and return false. Otherwise, return true.
6828
6829
    @param[in] ranges  list of integers; interpreted as list of pairs of
6830
                       inclusive lower and upper bound, respectively
6831
6832
    @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
6833
         1, 2, or 3 pairs. This precondition is enforced by an assertion.
6834
6835
    @return true if and only if no range violation was detected
6836
    */
6837
    bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6838
45.8k
    {
6839
45.8k
        JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6840
0
        add(current);
6841
6842
149k
        for (auto range = ranges.begin(); range != ranges.end(); ++range)
6843
103k
        {
6844
103k
            get();
6845
103k
            if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6846
103k
            {
6847
103k
                add(current);
6848
103k
            }
6849
4
            else
6850
4
            {
6851
4
                error_message = "invalid string: ill-formed UTF-8 byte";
6852
4
                return false;
6853
4
            }
6854
103k
        }
6855
6856
45.8k
        return true;
6857
45.8k
    }
6858
6859
    /*!
6860
    @brief scan a string literal
6861
6862
    This function scans a string according to Sect. 7 of RFC 8259. While
6863
    scanning, bytes are escaped and copied into buffer token_buffer. Then the
6864
    function returns successfully, token_buffer is *not* null-terminated (as it
6865
    may contain \0 bytes), and token_buffer.size() is the number of bytes in the
6866
    string.
6867
6868
    @return token_type::value_string if string could be successfully scanned,
6869
            token_type::parse_error otherwise
6870
6871
    @note In case of errors, variable error_message contains a textual
6872
          description.
6873
    */
6874
    token_type scan_string()
6875
559k
    {
6876
        // reset token_buffer (ignore opening quote)
6877
559k
        reset();
6878
6879
        // we entered the function by reading an open quote
6880
559k
        JSON_ASSERT(current == '\"');
6881
6882
72.7M
        while (true)
6883
72.7M
        {
6884
            // get next character
6885
72.7M
            switch (get())
6886
72.7M
            {
6887
                // end of file while parsing string
6888
14
                case std::char_traits<char_type>::eof():
6889
14
                {
6890
14
                    error_message = "invalid string: missing closing quote";
6891
14
                    return token_type::parse_error;
6892
0
                }
6893
6894
                // closing quote
6895
559k
                case '\"':
6896
559k
                {
6897
559k
                    return token_type::value_string;
6898
0
                }
6899
6900
                // escapes
6901
8.49k
                case '\\':
6902
8.49k
                {
6903
8.49k
                    switch (get())
6904
8.49k
                    {
6905
                        // quotation mark
6906
26
                        case '\"':
6907
26
                            add('\"');
6908
26
                            break;
6909
                        // reverse solidus
6910
484
                        case '\\':
6911
484
                            add('\\');
6912
484
                            break;
6913
                        // solidus
6914
80
                        case '/':
6915
80
                            add('/');
6916
80
                            break;
6917
                        // backspace
6918
145
                        case 'b':
6919
145
                            add('\b');
6920
145
                            break;
6921
                        // form feed
6922
6
                        case 'f':
6923
6
                            add('\f');
6924
6
                            break;
6925
                        // line feed
6926
1
                        case 'n':
6927
1
                            add('\n');
6928
1
                            break;
6929
                        // carriage return
6930
114
                        case 'r':
6931
114
                            add('\r');
6932
114
                            break;
6933
                        // tab
6934
14
                        case 't':
6935
14
                            add('\t');
6936
14
                            break;
6937
6938
                        // unicode escapes
6939
7.62k
                        case 'u':
6940
7.62k
                        {
6941
7.62k
                            const int codepoint1 = get_codepoint();
6942
7.62k
                            int codepoint = codepoint1; // start with codepoint1
6943
6944
7.62k
                            if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6945
2
                            {
6946
2
                                error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6947
2
                                return token_type::parse_error;
6948
2
                            }
6949
6950
                            // check if code point is a high surrogate
6951
7.62k
                            if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6952
129
                            {
6953
                                // expect next \uxxxx entry
6954
129
                                if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6955
129
                                {
6956
129
                                    const int codepoint2 = get_codepoint();
6957
6958
129
                                    if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6959
0
                                    {
6960
0
                                        error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6961
0
                                        return token_type::parse_error;
6962
0
                                    }
6963
6964
                                    // check if codepoint2 is a low surrogate
6965
129
                                    if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6966
128
                                    {
6967
                                        // overwrite codepoint
6968
128
                                        codepoint = static_cast<int>(
6969
                                                        // high surrogate occupies the most significant 22 bits
6970
128
                                                        (static_cast<unsigned int>(codepoint1) << 10u)
6971
                                                        // low surrogate occupies the least significant 15 bits
6972
128
                                                        + static_cast<unsigned int>(codepoint2)
6973
                                                        // there is still the 0xD800, 0xDC00 and 0x10000 noise
6974
                                                        // in the result so we have to subtract with:
6975
                                                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6976
128
                                                        - 0x35FDC00u);
6977
128
                                    }
6978
1
                                    else
6979
1
                                    {
6980
1
                                        error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6981
1
                                        return token_type::parse_error;
6982
1
                                    }
6983
129
                                }
6984
0
                                else
6985
0
                                {
6986
0
                                    error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6987
0
                                    return token_type::parse_error;
6988
0
                                }
6989
129
                            }
6990
7.49k
                            else
6991
7.49k
                            {
6992
7.49k
                                if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6993
0
                                {
6994
0
                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6995
0
                                    return token_type::parse_error;
6996
0
                                }
6997
7.49k
                            }
6998
6999
                            // result of the above calculation yields a proper codepoint
7000
7.62k
                            JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7001
7002
                            // translate codepoint into bytes
7003
7.62k
                            if (codepoint < 0x80)
7004
6.44k
                            {
7005
                                // 1-byte characters: 0xxxxxxx (ASCII)
7006
6.44k
                                add(static_cast<char_int_type>(codepoint));
7007
6.44k
                            }
7008
1.17k
                            else if (codepoint <= 0x7FF)
7009
335
                            {
7010
                                // 2-byte characters: 110xxxxx 10xxxxxx
7011
335
                                add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7012
335
                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7013
335
                            }
7014
839
                            else if (codepoint <= 0xFFFF)
7015
711
                            {
7016
                                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7017
711
                                add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7018
711
                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7019
711
                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7020
711
                            }
7021
128
                            else
7022
128
                            {
7023
                                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7024
128
                                add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7025
128
                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7026
128
                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7027
128
                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7028
128
                            }
7029
7030
7.62k
                            break;
7031
7.62k
                        }
7032
7033
                        // other characters after escape
7034
0
                        default:
7035
0
                            error_message = "invalid string: forbidden character after backslash";
7036
0
                            return token_type::parse_error;
7037
8.49k
                    }
7038
7039
8.49k
                    break;
7040
8.49k
                }
7041
7042
                // invalid control characters
7043
8.49k
                case 0x00:
7044
2
                {
7045
2
                    error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7046
2
                    return token_type::parse_error;
7047
8.49k
                }
7048
7049
1
                case 0x01:
7050
1
                {
7051
1
                    error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7052
1
                    return token_type::parse_error;
7053
8.49k
                }
7054
7055
0
                case 0x02:
7056
0
                {
7057
0
                    error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7058
0
                    return token_type::parse_error;
7059
8.49k
                }
7060
7061
0
                case 0x03:
7062
0
                {
7063
0
                    error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7064
0
                    return token_type::parse_error;
7065
8.49k
                }
7066
7067
0
                case 0x04:
7068
0
                {
7069
0
                    error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7070
0
                    return token_type::parse_error;
7071
8.49k
                }
7072
7073
0
                case 0x05:
7074
0
                {
7075
0
                    error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7076
0
                    return token_type::parse_error;
7077
8.49k
                }
7078
7079
0
                case 0x06:
7080
0
                {
7081
0
                    error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7082
0
                    return token_type::parse_error;
7083
8.49k
                }
7084
7085
0
                case 0x07:
7086
0
                {
7087
0
                    error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7088
0
                    return token_type::parse_error;
7089
8.49k
                }
7090
7091
0
                case 0x08:
7092
0
                {
7093
0
                    error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7094
0
                    return token_type::parse_error;
7095
8.49k
                }
7096
7097
0
                case 0x09:
7098
0
                {
7099
0
                    error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7100
0
                    return token_type::parse_error;
7101
8.49k
                }
7102
7103
1
                case 0x0A:
7104
1
                {
7105
1
                    error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7106
1
                    return token_type::parse_error;
7107
8.49k
                }
7108
7109
0
                case 0x0B:
7110
0
                {
7111
0
                    error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7112
0
                    return token_type::parse_error;
7113
8.49k
                }
7114
7115
0
                case 0x0C:
7116
0
                {
7117
0
                    error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7118
0
                    return token_type::parse_error;
7119
8.49k
                }
7120
7121
0
                case 0x0D:
7122
0
                {
7123
0
                    error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7124
0
                    return token_type::parse_error;
7125
8.49k
                }
7126
7127
0
                case 0x0E:
7128
0
                {
7129
0
                    error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7130
0
                    return token_type::parse_error;
7131
8.49k
                }
7132
7133
0
                case 0x0F:
7134
0
                {
7135
0
                    error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7136
0
                    return token_type::parse_error;
7137
8.49k
                }
7138
7139
0
                case 0x10:
7140
0
                {
7141
0
                    error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7142
0
                    return token_type::parse_error;
7143
8.49k
                }
7144
7145
1
                case 0x11:
7146
1
                {
7147
1
                    error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7148
1
                    return token_type::parse_error;
7149
8.49k
                }
7150
7151
0
                case 0x12:
7152
0
                {
7153
0
                    error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7154
0
                    return token_type::parse_error;
7155
8.49k
                }
7156
7157
0
                case 0x13:
7158
0
                {
7159
0
                    error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7160
0
                    return token_type::parse_error;
7161
8.49k
                }
7162
7163
0
                case 0x14:
7164
0
                {
7165
0
                    error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7166
0
                    return token_type::parse_error;
7167
8.49k
                }
7168
7169
0
                case 0x15:
7170
0
                {
7171
0
                    error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7172
0
                    return token_type::parse_error;
7173
8.49k
                }
7174
7175
0
                case 0x16:
7176
0
                {
7177
0
                    error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7178
0
                    return token_type::parse_error;
7179
8.49k
                }
7180
7181
0
                case 0x17:
7182
0
                {
7183
0
                    error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7184
0
                    return token_type::parse_error;
7185
8.49k
                }
7186
7187
0
                case 0x18:
7188
0
                {
7189
0
                    error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7190
0
                    return token_type::parse_error;
7191
8.49k
                }
7192
7193
0
                case 0x19:
7194
0
                {
7195
0
                    error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7196
0
                    return token_type::parse_error;
7197
8.49k
                }
7198
7199
0
                case 0x1A:
7200
0
                {
7201
0
                    error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7202
0
                    return token_type::parse_error;
7203
8.49k
                }
7204
7205
0
                case 0x1B:
7206
0
                {
7207
0
                    error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7208
0
                    return token_type::parse_error;
7209
8.49k
                }
7210
7211
0
                case 0x1C:
7212
0
                {
7213
0
                    error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7214
0
                    return token_type::parse_error;
7215
8.49k
                }
7216
7217
0
                case 0x1D:
7218
0
                {
7219
0
                    error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7220
0
                    return token_type::parse_error;
7221
8.49k
                }
7222
7223
0
                case 0x1E:
7224
0
                {
7225
0
                    error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7226
0
                    return token_type::parse_error;
7227
8.49k
                }
7228
7229
0
                case 0x1F:
7230
0
                {
7231
0
                    error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7232
0
                    return token_type::parse_error;
7233
8.49k
                }
7234
7235
                // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7236
36.1k
                case 0x20:
7237
237k
                case 0x21:
7238
463k
                case 0x23:
7239
501k
                case 0x24:
7240
1.41M
                case 0x25:
7241
1.47M
                case 0x26:
7242
1.48M
                case 0x27:
7243
1.51M
                case 0x28:
7244
2.35M
                case 0x29:
7245
2.37M
                case 0x2A:
7246
2.67M
                case 0x2B:
7247
6.81M
                case 0x2C:
7248
6.96M
                case 0x2D:
7249
6.99M
                case 0x2E:
7250
8.68M
                case 0x2F:
7251
9.14M
                case 0x30:
7252
9.40M
                case 0x31:
7253
9.67M
                case 0x32:
7254
10.0M
                case 0x33:
7255
10.5M
                case 0x34:
7256
10.7M
                case 0x35:
7257
11.7M
                case 0x36:
7258
12.6M
                case 0x37:
7259
14.5M
                case 0x38:
7260
15.1M
                case 0x39:
7261
15.3M
                case 0x3A:
7262
15.4M
                case 0x3B:
7263
15.4M
                case 0x3C:
7264
15.5M
                case 0x3D:
7265
15.6M
                case 0x3E:
7266
15.6M
                case 0x3F:
7267
15.6M
                case 0x40:
7268
16.7M
                case 0x41:
7269
16.8M
                case 0x42:
7270
17.3M
                case 0x43:
7271
17.4M
                case 0x44:
7272
17.7M
                case 0x45:
7273
17.7M
                case 0x46:
7274
17.7M
                case 0x47:
7275
17.8M
                case 0x48:
7276
17.9M
                case 0x49:
7277
17.9M
                case 0x4A:
7278
18.1M
                case 0x4B:
7279
18.3M
                case 0x4C:
7280
18.4M
                case 0x4D:
7281
18.4M
                case 0x4E:
7282
18.5M
                case 0x4F:
7283
19.5M
                case 0x50:
7284
30.4M
                case 0x51:
7285
30.5M
                case 0x52:
7286
30.7M
                case 0x53:
7287
30.8M
                case 0x54:
7288
30.8M
                case 0x55:
7289
30.9M
                case 0x56:
7290
31.0M
                case 0x57:
7291
31.1M
                case 0x58:
7292
31.3M
                case 0x59:
7293
31.3M
                case 0x5A:
7294
45.0M
                case 0x5B:
7295
45.0M
                case 0x5D:
7296
45.1M
                case 0x5E:
7297
45.1M
                case 0x5F:
7298
46.3M
                case 0x60:
7299
52.4M
                case 0x61:
7300
52.7M
                case 0x62:
7301
53.5M
                case 0x63:
7302
54.4M
                case 0x64:
7303
55.4M
                case 0x65:
7304
55.5M
                case 0x66:
7305
55.9M
                case 0x67:
7306
55.9M
                case 0x68:
7307
56.4M
                case 0x69:
7308
56.6M
                case 0x6A:
7309
56.8M
                case 0x6B:
7310
57.8M
                case 0x6C:
7311
66.2M
                case 0x6D:
7312
66.4M
                case 0x6E:
7313
66.6M
                case 0x6F:
7314
67.7M
                case 0x70:
7315
68.5M
                case 0x71:
7316
69.1M
                case 0x72:
7317
69.6M
                case 0x73:
7318
70.2M
                case 0x74:
7319
70.4M
                case 0x75:
7320
70.5M
                case 0x76:
7321
70.6M
                case 0x77:
7322
70.6M
                case 0x78:
7323
70.8M
                case 0x79:
7324
70.8M
                case 0x7A:
7325
71.4M
                case 0x7B:
7326
71.4M
                case 0x7C:
7327
71.9M
                case 0x7D:
7328
72.0M
                case 0x7E:
7329
72.1M
                case 0x7F:
7330
72.1M
                {
7331
72.1M
                    add(current);
7332
72.1M
                    break;
7333
72.0M
                }
7334
7335
                // U+0080..U+07FF: bytes C2..DF 80..BF
7336
583
                case 0xC2:
7337
1.08k
                case 0xC3:
7338
1.28k
                case 0xC4:
7339
3.81k
                case 0xC5:
7340
3.86k
                case 0xC6:
7341
4.03k
                case 0xC7:
7342
4.22k
                case 0xC8:
7343
4.28k
                case 0xC9:
7344
5.00k
                case 0xCA:
7345
5.03k
                case 0xCB:
7346
5.11k
                case 0xCC:
7347
5.21k
                case 0xCD:
7348
7.66k
                case 0xCE:
7349
7.75k
                case 0xCF:
7350
8.14k
                case 0xD0:
7351
8.39k
                case 0xD1:
7352
8.39k
                case 0xD2:
7353
8.53k
                case 0xD3:
7354
8.76k
                case 0xD4:
7355
10.9k
                case 0xD5:
7356
12.1k
                case 0xD6:
7357
12.2k
                case 0xD7:
7358
12.8k
                case 0xD8:
7359
12.9k
                case 0xD9:
7360
12.9k
                case 0xDA:
7361
13.5k
                case 0xDB:
7362
13.7k
                case 0xDC:
7363
13.8k
                case 0xDD:
7364
13.8k
                case 0xDE:
7365
13.9k
                case 0xDF:
7366
13.9k
                {
7367
13.9k
                    if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7368
1
                    {
7369
1
                        return token_type::parse_error;
7370
1
                    }
7371
13.9k
                    break;
7372
13.9k
                }
7373
7374
                // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7375
13.9k
                case 0xE0:
7376
299
                {
7377
299
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7378
1
                    {
7379
1
                        return token_type::parse_error;
7380
1
                    }
7381
298
                    break;
7382
299
                }
7383
7384
                // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7385
                // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7386
298
                case 0xE1:
7387
2.43k
                case 0xE2:
7388
2.46k
                case 0xE3:
7389
2.47k
                case 0xE4:
7390
2.49k
                case 0xE5:
7391
2.61k
                case 0xE6:
7392
2.61k
                case 0xE7:
7393
2.61k
                case 0xE8:
7394
2.67k
                case 0xE9:
7395
3.06k
                case 0xEA:
7396
3.22k
                case 0xEB:
7397
3.22k
                case 0xEC:
7398
3.25k
                case 0xEE:
7399
5.90k
                case 0xEF:
7400
5.90k
                {
7401
5.90k
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7402
2
                    {
7403
2
                        return token_type::parse_error;
7404
2
                    }
7405
5.90k
                    break;
7406
5.90k
                }
7407
7408
                // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7409
5.90k
                case 0xED:
7410
0
                {
7411
0
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7412
0
                    {
7413
0
                        return token_type::parse_error;
7414
0
                    }
7415
0
                    break;
7416
0
                }
7417
7418
                // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7419
115
                case 0xF0:
7420
115
                {
7421
115
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7422
0
                    {
7423
0
                        return token_type::parse_error;
7424
0
                    }
7425
115
                    break;
7426
115
                }
7427
7428
                // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7429
10.3k
                case 0xF1:
7430
10.3k
                case 0xF2:
7431
25.6k
                case 0xF3:
7432
25.6k
                {
7433
25.6k
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7434
0
                    {
7435
0
                        return token_type::parse_error;
7436
0
                    }
7437
25.6k
                    break;
7438
25.6k
                }
7439
7440
                // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7441
25.6k
                case 0xF4:
7442
3
                {
7443
3
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7444
0
                    {
7445
0
                        return token_type::parse_error;
7446
0
                    }
7447
3
                    break;
7448
3
                }
7449
7450
                // remaining bytes (80..C1 and F5..FF) are ill-formed
7451
3
                default:
7452
2
                {
7453
2
                    error_message = "invalid string: ill-formed UTF-8 byte";
7454
2
                    return token_type::parse_error;
7455
3
                }
7456
72.7M
            }
7457
72.7M
        }
7458
559k
    }
7459
7460
    /*!
7461
     * @brief scan a comment
7462
     * @return whether comment could be scanned successfully
7463
     */
7464
    bool scan_comment()
7465
0
    {
7466
0
        switch (get())
7467
0
        {
7468
            // single-line comments skip input until a newline or EOF is read
7469
0
            case '/':
7470
0
            {
7471
0
                while (true)
7472
0
                {
7473
0
                    switch (get())
7474
0
                    {
7475
0
                        case '\n':
7476
0
                        case '\r':
7477
0
                        case std::char_traits<char_type>::eof():
7478
0
                        case '\0':
7479
0
                            return true;
7480
7481
0
                        default:
7482
0
                            break;
7483
0
                    }
7484
0
                }
7485
0
            }
7486
7487
            // multi-line comments skip input until */ is read
7488
0
            case '*':
7489
0
            {
7490
0
                while (true)
7491
0
                {
7492
0
                    switch (get())
7493
0
                    {
7494
0
                        case std::char_traits<char_type>::eof():
7495
0
                        case '\0':
7496
0
                        {
7497
0
                            error_message = "invalid comment; missing closing '*/'";
7498
0
                            return false;
7499
0
                        }
7500
7501
0
                        case '*':
7502
0
                        {
7503
0
                            switch (get())
7504
0
                            {
7505
0
                                case '/':
7506
0
                                    return true;
7507
7508
0
                                default:
7509
0
                                {
7510
0
                                    unget();
7511
0
                                    continue;
7512
0
                                }
7513
0
                            }
7514
0
                        }
7515
7516
0
                        default:
7517
0
                            continue;
7518
0
                    }
7519
0
                }
7520
0
            }
7521
7522
            // unexpected character after reading '/'
7523
0
            default:
7524
0
            {
7525
0
                error_message = "invalid comment; expecting '/' or '*' after '/'";
7526
0
                return false;
7527
0
            }
7528
0
        }
7529
0
    }
7530
7531
    JSON_HEDLEY_NON_NULL(2)
7532
    static void strtof(float& f, const char* str, char** endptr) noexcept
7533
    {
7534
        f = std::strtof(str, endptr);
7535
    }
7536
7537
    JSON_HEDLEY_NON_NULL(2)
7538
    static void strtof(double& f, const char* str, char** endptr) noexcept
7539
50.0k
    {
7540
50.0k
        f = std::strtod(str, endptr);
7541
50.0k
    }
7542
7543
    JSON_HEDLEY_NON_NULL(2)
7544
    static void strtof(long double& f, const char* str, char** endptr) noexcept
7545
    {
7546
        f = std::strtold(str, endptr);
7547
    }
7548
7549
    /*!
7550
    @brief scan a number literal
7551
7552
    This function scans a string according to Sect. 6 of RFC 8259.
7553
7554
    The function is realized with a deterministic finite state machine derived
7555
    from the grammar described in RFC 8259. Starting in state "init", the
7556
    input is read and used to determined the next state. Only state "done"
7557
    accepts the number. State "error" is a trap state to model errors. In the
7558
    table below, "anything" means any character but the ones listed before.
7559
7560
    state    | 0        | 1-9      | e E      | +       | -       | .        | anything
7561
    ---------|----------|----------|----------|---------|---------|----------|-----------
7562
    init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
7563
    minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
7564
    zero     | done     | done     | exponent | done    | done    | decimal1 | done
7565
    any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
7566
    decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
7567
    decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
7568
    exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
7569
    sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
7570
    any2     | any2     | any2     | done     | done    | done    | done     | done
7571
7572
    The state machine is realized with one label per state (prefixed with
7573
    "scan_number_") and `goto` statements between them. The state machine
7574
    contains cycles, but any cycle can be left when EOF is read. Therefore,
7575
    the function is guaranteed to terminate.
7576
7577
    During scanning, the read bytes are stored in token_buffer. This string is
7578
    then converted to a signed integer, an unsigned integer, or a
7579
    floating-point number.
7580
7581
    @return token_type::value_unsigned, token_type::value_integer, or
7582
            token_type::value_float if number could be successfully scanned,
7583
            token_type::parse_error otherwise
7584
7585
    @note The scanner is independent of the current locale. Internally, the
7586
          locale's decimal point is used instead of `.` to work with the
7587
          locale-dependent converters.
7588
    */
7589
    token_type scan_number()  // lgtm [cpp/use-of-goto]
7590
6.20M
    {
7591
        // reset token_buffer to store the number's bytes
7592
6.20M
        reset();
7593
7594
        // the type of the parsed number; initially set to unsigned; will be
7595
        // changed if minus sign, decimal point or exponent is read
7596
6.20M
        token_type number_type = token_type::value_unsigned;
7597
7598
        // state (init): we just found out we need to scan a number
7599
6.20M
        switch (current)
7600
6.20M
        {
7601
23.7k
            case '-':
7602
23.7k
            {
7603
23.7k
                add(current);
7604
23.7k
                goto scan_number_minus;
7605
0
            }
7606
7607
62.8k
            case '0':
7608
62.8k
            {
7609
62.8k
                add(current);
7610
62.8k
                goto scan_number_zero;
7611
0
            }
7612
7613
99.1k
            case '1':
7614
127k
            case '2':
7615
835k
            case '3':
7616
846k
            case '4':
7617
858k
            case '5':
7618
3.08M
            case '6':
7619
3.30M
            case '7':
7620
4.72M
            case '8':
7621
6.11M
            case '9':
7622
6.11M
            {
7623
6.11M
                add(current);
7624
6.11M
                goto scan_number_any1;
7625
4.72M
            }
7626
7627
            // all other characters are rejected outside scan_number()
7628
0
            default:            // LCOV_EXCL_LINE
7629
0
                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7630
6.20M
        }
7631
7632
23.7k
scan_number_minus:
7633
        // state: we just parsed a leading minus sign
7634
23.7k
        number_type = token_type::value_integer;
7635
23.7k
        switch (get())
7636
23.7k
        {
7637
1.76k
            case '0':
7638
1.76k
            {
7639
1.76k
                add(current);
7640
1.76k
                goto scan_number_zero;
7641
0
            }
7642
7643
4.95k
            case '1':
7644
11.5k
            case '2':
7645
13.3k
            case '3':
7646
16.1k
            case '4':
7647
17.0k
            case '5':
7648
17.5k
            case '6':
7649
21.0k
            case '7':
7650
21.2k
            case '8':
7651
22.0k
            case '9':
7652
22.0k
            {
7653
22.0k
                add(current);
7654
22.0k
                goto scan_number_any1;
7655
21.2k
            }
7656
7657
5
            default:
7658
5
            {
7659
5
                error_message = "invalid number; expected digit after '-'";
7660
5
                return token_type::parse_error;
7661
21.2k
            }
7662
23.7k
        }
7663
7664
64.6k
scan_number_zero:
7665
        // state: we just parse a zero (maybe with a leading minus sign)
7666
64.6k
        switch (get())
7667
64.6k
        {
7668
291
            case '.':
7669
291
            {
7670
291
                add(decimal_point_char);
7671
291
                goto scan_number_decimal1;
7672
0
            }
7673
7674
54
            case 'e':
7675
310
            case 'E':
7676
310
            {
7677
310
                add(current);
7678
310
                goto scan_number_exponent;
7679
54
            }
7680
7681
64.0k
            default:
7682
64.0k
                goto scan_number_done;
7683
64.6k
        }
7684
7685
6.47M
scan_number_any1:
7686
        // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7687
6.47M
        switch (get())
7688
6.47M
        {
7689
51.1k
            case '0':
7690
68.8k
            case '1':
7691
90.2k
            case '2':
7692
113k
            case '3':
7693
142k
            case '4':
7694
162k
            case '5':
7695
213k
            case '6':
7696
245k
            case '7':
7697
307k
            case '8':
7698
334k
            case '9':
7699
334k
            {
7700
334k
                add(current);
7701
334k
                goto scan_number_any1;
7702
307k
            }
7703
7704
14.9k
            case '.':
7705
14.9k
            {
7706
14.9k
                add(decimal_point_char);
7707
14.9k
                goto scan_number_decimal1;
7708
307k
            }
7709
7710
119
            case 'e':
7711
31.5k
            case 'E':
7712
31.5k
            {
7713
31.5k
                add(current);
7714
31.5k
                goto scan_number_exponent;
7715
119
            }
7716
7717
6.08M
            default:
7718
6.08M
                goto scan_number_done;
7719
6.47M
        }
7720
7721
15.1k
scan_number_decimal1:
7722
        // state: we just parsed a decimal point
7723
15.1k
        number_type = token_type::value_float;
7724
15.1k
        switch (get())
7725
15.1k
        {
7726
693
            case '0':
7727
2.63k
            case '1':
7728
3.07k
            case '2':
7729
3.09k
            case '3':
7730
3.09k
            case '4':
7731
3.10k
            case '5':
7732
11.4k
            case '6':
7733
11.5k
            case '7':
7734
14.6k
            case '8':
7735
15.1k
            case '9':
7736
15.1k
            {
7737
15.1k
                add(current);
7738
15.1k
                goto scan_number_decimal2;
7739
14.6k
            }
7740
7741
0
            default:
7742
0
            {
7743
0
                error_message = "invalid number; expected digit after '.'";
7744
0
                return token_type::parse_error;
7745
14.6k
            }
7746
15.1k
        }
7747
7748
17.5k
scan_number_decimal2:
7749
        // we just parsed at least one number after a decimal point
7750
17.5k
        switch (get())
7751
17.5k
        {
7752
201
            case '0':
7753
499
            case '1':
7754
776
            case '2':
7755
961
            case '3':
7756
1.30k
            case '4':
7757
1.65k
            case '5':
7758
1.80k
            case '6':
7759
2.08k
            case '7':
7760
2.18k
            case '8':
7761
2.39k
            case '9':
7762
2.39k
            {
7763
2.39k
                add(current);
7764
2.39k
                goto scan_number_decimal2;
7765
2.18k
            }
7766
7767
128
            case 'e':
7768
346
            case 'E':
7769
346
            {
7770
346
                add(current);
7771
346
                goto scan_number_exponent;
7772
128
            }
7773
7774
14.8k
            default:
7775
14.8k
                goto scan_number_done;
7776
17.5k
        }
7777
7778
32.2k
scan_number_exponent:
7779
        // we just parsed an exponent
7780
32.2k
        number_type = token_type::value_float;
7781
32.2k
        switch (get())
7782
32.2k
        {
7783
0
            case '+':
7784
18
            case '-':
7785
18
            {
7786
18
                add(current);
7787
18
                goto scan_number_sign;
7788
0
            }
7789
7790
102
            case '0':
7791
4.03k
            case '1':
7792
4.10k
            case '2':
7793
12.0k
            case '3':
7794
12.0k
            case '4':
7795
16.1k
            case '5':
7796
28.2k
            case '6':
7797
32.1k
            case '7':
7798
32.2k
            case '8':
7799
32.2k
            case '9':
7800
32.2k
            {
7801
32.2k
                add(current);
7802
32.2k
                goto scan_number_any2;
7803
32.2k
            }
7804
7805
2
            default:
7806
2
            {
7807
2
                error_message =
7808
2
                    "invalid number; expected '+', '-', or digit after exponent";
7809
2
                return token_type::parse_error;
7810
32.2k
            }
7811
32.2k
        }
7812
7813
18
scan_number_sign:
7814
        // we just parsed an exponent sign
7815
18
        switch (get())
7816
18
        {
7817
0
            case '0':
7818
0
            case '1':
7819
16
            case '2':
7820
16
            case '3':
7821
16
            case '4':
7822
16
            case '5':
7823
16
            case '6':
7824
16
            case '7':
7825
18
            case '8':
7826
18
            case '9':
7827
18
            {
7828
18
                add(current);
7829
18
                goto scan_number_any2;
7830
18
            }
7831
7832
0
            default:
7833
0
            {
7834
0
                error_message = "invalid number; expected digit after exponent sign";
7835
0
                return token_type::parse_error;
7836
18
            }
7837
18
        }
7838
7839
36.4k
scan_number_any2:
7840
        // we just parsed a number after the exponent or exponent sign
7841
36.4k
        switch (get())
7842
36.4k
        {
7843
27
            case '0':
7844
37
            case '1':
7845
55
            case '2':
7846
73
            case '3':
7847
115
            case '4':
7848
125
            case '5':
7849
144
            case '6':
7850
246
            case '7':
7851
255
            case '8':
7852
4.15k
            case '9':
7853
4.15k
            {
7854
4.15k
                add(current);
7855
4.15k
                goto scan_number_any2;
7856
255
            }
7857
7858
32.2k
            default:
7859
32.2k
                goto scan_number_done;
7860
36.4k
        }
7861
7862
6.20M
scan_number_done:
7863
        // unget the character after the number (we only read it to know that
7864
        // we are done scanning a number)
7865
6.20M
        unget();
7866
7867
6.20M
        char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7868
6.20M
        errno = 0;
7869
7870
        // try to parse integers first and fall back to floats
7871
6.20M
        if (number_type == token_type::value_unsigned)
7872
6.13M
        {
7873
6.13M
            const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7874
7875
            // we checked the number format before
7876
6.13M
            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7877
7878
6.13M
            if (errno == 0)
7879
6.13M
            {
7880
6.13M
                value_unsigned = static_cast<number_unsigned_t>(x);
7881
6.13M
                if (value_unsigned == x)
7882
6.13M
                {
7883
6.13M
                    return token_type::value_unsigned;
7884
6.13M
                }
7885
6.13M
            }
7886
6.13M
        }
7887
68.3k
        else if (number_type == token_type::value_integer)
7888
21.2k
        {
7889
21.2k
            const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7890
7891
            // we checked the number format before
7892
21.2k
            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7893
7894
21.2k
            if (errno == 0)
7895
20.4k
            {
7896
20.4k
                value_integer = static_cast<number_integer_t>(x);
7897
20.4k
                if (value_integer == x)
7898
20.4k
                {
7899
20.4k
                    return token_type::value_integer;
7900
20.4k
                }
7901
20.4k
            }
7902
21.2k
        }
7903
7904
        // this code is reached if we parse a floating-point number or if an
7905
        // integer conversion above failed
7906
50.0k
        strtof(value_float, token_buffer.data(), &endptr);
7907
7908
        // we checked the number format before
7909
50.0k
        JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7910
7911
0
        return token_type::value_float;
7912
6.20M
    }
7913
7914
    /*!
7915
    @param[in] literal_text  the literal text to expect
7916
    @param[in] length        the length of the passed literal text
7917
    @param[in] return_type   the token type to return on success
7918
    */
7919
    JSON_HEDLEY_NON_NULL(2)
7920
    token_type scan_literal(const char_type* literal_text, const std::size_t length,
7921
                            token_type return_type)
7922
46.4k
    {
7923
46.4k
        JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7924
185k
        for (std::size_t i = 1; i < length; ++i)
7925
139k
        {
7926
139k
            if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7927
5
            {
7928
5
                error_message = "invalid literal";
7929
5
                return token_type::parse_error;
7930
5
            }
7931
139k
        }
7932
46.4k
        return return_type;
7933
46.4k
    }
7934
7935
    /////////////////////
7936
    // input management
7937
    /////////////////////
7938
7939
    /// reset token_buffer; current character is beginning of token
7940
    void reset() noexcept
7941
6.76M
    {
7942
6.76M
        token_buffer.clear();
7943
6.76M
        token_string.clear();
7944
6.76M
        token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7945
6.76M
    }
7946
7947
    /*
7948
    @brief get next character from the input
7949
7950
    This function provides the interface to the used input adapter. It does
7951
    not throw in case the input reached EOF, but returns a
7952
    `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
7953
    for use in error messages.
7954
7955
    @return character read from the input
7956
    */
7957
    char_int_type get()
7958
103M
    {
7959
103M
        ++position.chars_read_total;
7960
103M
        ++position.chars_read_current_line;
7961
7962
103M
        if (next_unget)
7963
6.20M
        {
7964
            // just reset the next_unget variable and work with current
7965
6.20M
            next_unget = false;
7966
6.20M
        }
7967
96.9M
        else
7968
96.9M
        {
7969
96.9M
            current = ia.get_character();
7970
96.9M
        }
7971
7972
103M
        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7973
103M
        {
7974
103M
            token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7975
103M
        }
7976
7977
103M
        if (current == '\n')
7978
33.2k
        {
7979
33.2k
            ++position.lines_read;
7980
33.2k
            position.chars_read_current_line = 0;
7981
33.2k
        }
7982
7983
103M
        return current;
7984
103M
    }
7985
7986
    /*!
7987
    @brief unget current character (read it again on next get)
7988
7989
    We implement unget by setting variable next_unget to true. The input is not
7990
    changed - we just simulate ungetting by modifying chars_read_total,
7991
    chars_read_current_line, and token_string. The next call to get() will
7992
    behave as if the unget character is read again.
7993
    */
7994
    void unget()
7995
6.20M
    {
7996
6.20M
        next_unget = true;
7997
7998
6.20M
        --position.chars_read_total;
7999
8000
        // in case we "unget" a newline, we have to also decrement the lines_read
8001
6.20M
        if (position.chars_read_current_line == 0)
8002
1.05k
        {
8003
1.05k
            if (position.lines_read > 0)
8004
1.05k
            {
8005
1.05k
                --position.lines_read;
8006
1.05k
            }
8007
1.05k
        }
8008
6.20M
        else
8009
6.20M
        {
8010
6.20M
            --position.chars_read_current_line;
8011
6.20M
        }
8012
8013
6.20M
        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8014
6.20M
        {
8015
6.20M
            JSON_ASSERT(!token_string.empty());
8016
0
            token_string.pop_back();
8017
6.20M
        }
8018
6.20M
    }
8019
8020
    /// add a character to token_buffer
8021
    void add(char_int_type c)
8022
78.9M
    {
8023
78.9M
        token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8024
78.9M
    }
8025
8026
  public:
8027
    /////////////////////
8028
    // value getters
8029
    /////////////////////
8030
8031
    /// return integer value
8032
    constexpr number_integer_t get_number_integer() const noexcept
8033
20.4k
    {
8034
20.4k
        return value_integer;
8035
20.4k
    }
8036
8037
    /// return unsigned integer value
8038
    constexpr number_unsigned_t get_number_unsigned() const noexcept
8039
6.13M
    {
8040
6.13M
        return value_unsigned;
8041
6.13M
    }
8042
8043
    /// return floating-point value
8044
    constexpr number_float_t get_number_float() const noexcept
8045
50.0k
    {
8046
50.0k
        return value_float;
8047
50.0k
    }
8048
8049
    /// return current string value (implicitly resets the token; useful only once)
8050
    string_t& get_string()
8051
609k
    {
8052
609k
        return token_buffer;
8053
609k
    }
8054
8055
    /////////////////////
8056
    // diagnostics
8057
    /////////////////////
8058
8059
    /// return position of last read token
8060
    constexpr position_t get_position() const noexcept
8061
424
    {
8062
424
        return position;
8063
424
    }
8064
8065
    /// return the last read token (for errors only).  Will never contain EOF
8066
    /// (an arbitrary value that is not a valid char value, often -1), because
8067
    /// 255 may legitimately occur.  May contain NUL, which should be escaped.
8068
    std::string get_token_string() const
8069
328
    {
8070
        // escape control characters
8071
328
        std::string result;
8072
328
        for (const auto c : token_string)
8073
4.15M
        {
8074
4.15M
            if (static_cast<unsigned char>(c) <= '\x1F')
8075
94.7k
            {
8076
                // escape control characters
8077
94.7k
                std::array<char, 9> cs{{}};
8078
94.7k
                (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8079
94.7k
                result += cs.data();
8080
94.7k
            }
8081
4.05M
            else
8082
4.05M
            {
8083
                // add character as is
8084
4.05M
                result.push_back(static_cast<std::string::value_type>(c));
8085
4.05M
            }
8086
4.15M
        }
8087
8088
328
        return result;
8089
328
    }
8090
8091
    /// return syntax error message
8092
    JSON_HEDLEY_RETURNS_NON_NULL
8093
    constexpr const char* get_error_message() const noexcept
8094
110
    {
8095
110
        return error_message;
8096
110
    }
8097
8098
    /////////////////////
8099
    // actual scanner
8100
    /////////////////////
8101
8102
    /*!
8103
    @brief skip the UTF-8 byte order mark
8104
    @return true iff there is no BOM or the correct BOM has been skipped
8105
    */
8106
    bool skip_bom()
8107
1.82k
    {
8108
1.82k
        if (get() == 0xEF)
8109
0
        {
8110
            // check if we completely parse the BOM
8111
0
            return get() == 0xBB && get() == 0xBF;
8112
0
        }
8113
8114
        // the first character is not the beginning of the BOM; unget it to
8115
        // process is later
8116
1.82k
        unget();
8117
1.82k
        return true;
8118
1.82k
    }
8119
8120
    void skip_whitespace()
8121
23.3M
    {
8122
23.3M
        do
8123
23.4M
        {
8124
23.4M
            get();
8125
23.4M
        }
8126
23.4M
        while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8127
23.3M
    }
8128
8129
    token_type scan()
8130
23.3M
    {
8131
        // initially, skip the BOM
8132
23.3M
        if (position.chars_read_total == 0 && !skip_bom())
8133
0
        {
8134
0
            error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8135
0
            return token_type::parse_error;
8136
0
        }
8137
8138
        // read next character and ignore whitespace
8139
23.3M
        skip_whitespace();
8140
8141
        // ignore comments
8142
23.3M
        while (ignore_comments && current == '/')
8143
0
        {
8144
0
            if (!scan_comment())
8145
0
            {
8146
0
                return token_type::parse_error;
8147
0
            }
8148
8149
            // skip following whitespace
8150
0
            skip_whitespace();
8151
0
        }
8152
8153
23.3M
        switch (current)
8154
23.3M
        {
8155
            // structural characters
8156
5.67M
            case '[':
8157
5.67M
                return token_type::begin_array;
8158
57.8k
            case ']':
8159
57.8k
                return token_type::end_array;
8160
1.55M
            case '{':
8161
1.55M
                return token_type::begin_object;
8162
1.32M
            case '}':
8163
1.32M
                return token_type::end_object;
8164
488k
            case ':':
8165
488k
                return token_type::name_separator;
8166
7.43M
            case ',':
8167
7.43M
                return token_type::value_separator;
8168
8169
            // literals
8170
22.6k
            case 't':
8171
22.6k
            {
8172
22.6k
                std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8173
22.6k
                return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8174
0
            }
8175
138
            case 'f':
8176
138
            {
8177
138
                std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8178
138
                return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8179
0
            }
8180
23.6k
            case 'n':
8181
23.6k
            {
8182
23.6k
                std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8183
23.6k
                return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8184
0
            }
8185
8186
            // string
8187
559k
            case '\"':
8188
559k
                return scan_string();
8189
8190
            // number
8191
23.7k
            case '-':
8192
86.6k
            case '0':
8193
185k
            case '1':
8194
214k
            case '2':
8195
921k
            case '3':
8196
933k
            case '4':
8197
944k
            case '5':
8198
3.17M
            case '6':
8199
3.38M
            case '7':
8200
4.81M
            case '8':
8201
6.20M
            case '9':
8202
6.20M
                return scan_number();
8203
8204
            // end of input (the null byte is needed when parsing from
8205
            // string literals)
8206
24
            case '\0':
8207
1.66k
            case std::char_traits<char_type>::eof():
8208
1.66k
                return token_type::end_of_input;
8209
8210
            // error
8211
70
            default:
8212
70
                error_message = "invalid literal";
8213
70
                return token_type::parse_error;
8214
23.3M
        }
8215
23.3M
    }
8216
8217
  private:
8218
    /// input adapter
8219
    InputAdapterType ia;
8220
8221
    /// whether comments should be ignored (true) or signaled as errors (false)
8222
    const bool ignore_comments = false;
8223
8224
    /// the current character
8225
    char_int_type current = std::char_traits<char_type>::eof();
8226
8227
    /// whether the next get() call should just return current
8228
    bool next_unget = false;
8229
8230
    /// the start position of the current token
8231
    position_t position {};
8232
8233
    /// raw input token string (for error messages)
8234
    std::vector<char_type> token_string {};
8235
8236
    /// buffer for variable-length tokens (numbers, strings)
8237
    string_t token_buffer {};
8238
8239
    /// a description of occurred lexer errors
8240
    const char* error_message = "";
8241
8242
    // number values
8243
    number_integer_t value_integer = 0;
8244
    number_unsigned_t value_unsigned = 0;
8245
    number_float_t value_float = 0;
8246
8247
    /// the decimal point
8248
    const char_int_type decimal_point_char = '.';
8249
};
8250
}  // namespace detail
8251
}  // namespace nlohmann
8252
8253
// #include <nlohmann/detail/macro_scope.hpp>
8254
8255
// #include <nlohmann/detail/meta/is_sax.hpp>
8256
8257
8258
#include <cstdint> // size_t
8259
#include <utility> // declval
8260
#include <string> // string
8261
8262
// #include <nlohmann/detail/meta/detected.hpp>
8263
8264
// #include <nlohmann/detail/meta/type_traits.hpp>
8265
8266
8267
namespace nlohmann
8268
{
8269
namespace detail
8270
{
8271
template<typename T>
8272
using null_function_t = decltype(std::declval<T&>().null());
8273
8274
template<typename T>
8275
using boolean_function_t =
8276
    decltype(std::declval<T&>().boolean(std::declval<bool>()));
8277
8278
template<typename T, typename Integer>
8279
using number_integer_function_t =
8280
    decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8281
8282
template<typename T, typename Unsigned>
8283
using number_unsigned_function_t =
8284
    decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8285
8286
template<typename T, typename Float, typename String>
8287
using number_float_function_t = decltype(std::declval<T&>().number_float(
8288
                                    std::declval<Float>(), std::declval<const String&>()));
8289
8290
template<typename T, typename String>
8291
using string_function_t =
8292
    decltype(std::declval<T&>().string(std::declval<String&>()));
8293
8294
template<typename T, typename Binary>
8295
using binary_function_t =
8296
    decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8297
8298
template<typename T>
8299
using start_object_function_t =
8300
    decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8301
8302
template<typename T, typename String>
8303
using key_function_t =
8304
    decltype(std::declval<T&>().key(std::declval<String&>()));
8305
8306
template<typename T>
8307
using end_object_function_t = decltype(std::declval<T&>().end_object());
8308
8309
template<typename T>
8310
using start_array_function_t =
8311
    decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8312
8313
template<typename T>
8314
using end_array_function_t = decltype(std::declval<T&>().end_array());
8315
8316
template<typename T, typename Exception>
8317
using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8318
        std::declval<std::size_t>(), std::declval<const std::string&>(),
8319
        std::declval<const Exception&>()));
8320
8321
template<typename SAX, typename BasicJsonType>
8322
struct is_sax
8323
{
8324
  private:
8325
    static_assert(is_basic_json<BasicJsonType>::value,
8326
                  "BasicJsonType must be of type basic_json<...>");
8327
8328
    using number_integer_t = typename BasicJsonType::number_integer_t;
8329
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8330
    using number_float_t = typename BasicJsonType::number_float_t;
8331
    using string_t = typename BasicJsonType::string_t;
8332
    using binary_t = typename BasicJsonType::binary_t;
8333
    using exception_t = typename BasicJsonType::exception;
8334
8335
  public:
8336
    static constexpr bool value =
8337
        is_detected_exact<bool, null_function_t, SAX>::value &&
8338
        is_detected_exact<bool, boolean_function_t, SAX>::value &&
8339
        is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8340
        is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8341
        is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8342
        is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8343
        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8344
        is_detected_exact<bool, start_object_function_t, SAX>::value &&
8345
        is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8346
        is_detected_exact<bool, end_object_function_t, SAX>::value &&
8347
        is_detected_exact<bool, start_array_function_t, SAX>::value &&
8348
        is_detected_exact<bool, end_array_function_t, SAX>::value &&
8349
        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8350
};
8351
8352
template<typename SAX, typename BasicJsonType>
8353
struct is_sax_static_asserts
8354
{
8355
  private:
8356
    static_assert(is_basic_json<BasicJsonType>::value,
8357
                  "BasicJsonType must be of type basic_json<...>");
8358
8359
    using number_integer_t = typename BasicJsonType::number_integer_t;
8360
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8361
    using number_float_t = typename BasicJsonType::number_float_t;
8362
    using string_t = typename BasicJsonType::string_t;
8363
    using binary_t = typename BasicJsonType::binary_t;
8364
    using exception_t = typename BasicJsonType::exception;
8365
8366
  public:
8367
    static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8368
                  "Missing/invalid function: bool null()");
8369
    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8370
                  "Missing/invalid function: bool boolean(bool)");
8371
    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8372
                  "Missing/invalid function: bool boolean(bool)");
8373
    static_assert(
8374
        is_detected_exact<bool, number_integer_function_t, SAX,
8375
        number_integer_t>::value,
8376
        "Missing/invalid function: bool number_integer(number_integer_t)");
8377
    static_assert(
8378
        is_detected_exact<bool, number_unsigned_function_t, SAX,
8379
        number_unsigned_t>::value,
8380
        "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8381
    static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8382
                  number_float_t, string_t>::value,
8383
                  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8384
    static_assert(
8385
        is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8386
        "Missing/invalid function: bool string(string_t&)");
8387
    static_assert(
8388
        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8389
        "Missing/invalid function: bool binary(binary_t&)");
8390
    static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8391
                  "Missing/invalid function: bool start_object(std::size_t)");
8392
    static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8393
                  "Missing/invalid function: bool key(string_t&)");
8394
    static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8395
                  "Missing/invalid function: bool end_object()");
8396
    static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8397
                  "Missing/invalid function: bool start_array(std::size_t)");
8398
    static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8399
                  "Missing/invalid function: bool end_array()");
8400
    static_assert(
8401
        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8402
        "Missing/invalid function: bool parse_error(std::size_t, const "
8403
        "std::string&, const exception&)");
8404
};
8405
}  // namespace detail
8406
}  // namespace nlohmann
8407
8408
// #include <nlohmann/detail/meta/type_traits.hpp>
8409
8410
// #include <nlohmann/detail/value_t.hpp>
8411
8412
8413
namespace nlohmann
8414
{
8415
namespace detail
8416
{
8417
8418
/// how to treat CBOR tags
8419
enum class cbor_tag_handler_t
8420
{
8421
    error,   ///< throw a parse_error exception in case of a tag
8422
    ignore,  ///< ignore tags
8423
    store    ///< store tags as binary type
8424
};
8425
8426
/*!
8427
@brief determine system byte order
8428
8429
@return true if and only if system's byte order is little endian
8430
8431
@note from https://stackoverflow.com/a/1001328/266378
8432
*/
8433
static inline bool little_endianess(int num = 1) noexcept
8434
0
{
8435
0
    return *reinterpret_cast<char*>(&num) == 1;
8436
0
}
8437
8438
8439
///////////////////
8440
// binary reader //
8441
///////////////////
8442
8443
/*!
8444
@brief deserialization of CBOR, MessagePack, and UBJSON values
8445
*/
8446
template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8447
class binary_reader
8448
{
8449
    using number_integer_t = typename BasicJsonType::number_integer_t;
8450
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8451
    using number_float_t = typename BasicJsonType::number_float_t;
8452
    using string_t = typename BasicJsonType::string_t;
8453
    using binary_t = typename BasicJsonType::binary_t;
8454
    using json_sax_t = SAX;
8455
    using char_type = typename InputAdapterType::char_type;
8456
    using char_int_type = typename std::char_traits<char_type>::int_type;
8457
8458
  public:
8459
    /*!
8460
    @brief create a binary reader
8461
8462
    @param[in] adapter  input adapter to read from
8463
    */
8464
    explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8465
    {
8466
        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8467
    }
8468
8469
    // make class move-only
8470
    binary_reader(const binary_reader&) = delete;
8471
    binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8472
    binary_reader& operator=(const binary_reader&) = delete;
8473
    binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8474
    ~binary_reader() = default;
8475
8476
    /*!
8477
    @param[in] format  the binary format to parse
8478
    @param[in] sax_    a SAX event processor
8479
    @param[in] strict  whether to expect the input to be consumed completed
8480
    @param[in] tag_handler  how to treat CBOR tags
8481
8482
    @return whether parsing was successful
8483
    */
8484
    JSON_HEDLEY_NON_NULL(3)
8485
    bool sax_parse(const input_format_t format,
8486
                   json_sax_t* sax_,
8487
                   const bool strict = true,
8488
                   const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8489
    {
8490
        sax = sax_;
8491
        bool result = false;
8492
8493
        switch (format)
8494
        {
8495
            case input_format_t::bson:
8496
                result = parse_bson_internal();
8497
                break;
8498
8499
            case input_format_t::cbor:
8500
                result = parse_cbor_internal(true, tag_handler);
8501
                break;
8502
8503
            case input_format_t::msgpack:
8504
                result = parse_msgpack_internal();
8505
                break;
8506
8507
            case input_format_t::ubjson:
8508
                result = parse_ubjson_internal();
8509
                break;
8510
8511
            case input_format_t::json: // LCOV_EXCL_LINE
8512
            default:            // LCOV_EXCL_LINE
8513
                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8514
        }
8515
8516
        // strict mode: next byte must be EOF
8517
        if (result && strict)
8518
        {
8519
            if (format == input_format_t::ubjson)
8520
            {
8521
                get_ignore_noop();
8522
            }
8523
            else
8524
            {
8525
                get();
8526
            }
8527
8528
            if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8529
            {
8530
                return sax->parse_error(chars_read, get_token_string(),
8531
                                        parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8532
            }
8533
        }
8534
8535
        return result;
8536
    }
8537
8538
  private:
8539
    //////////
8540
    // BSON //
8541
    //////////
8542
8543
    /*!
8544
    @brief Reads in a BSON-object and passes it to the SAX-parser.
8545
    @return whether a valid BSON-value was passed to the SAX parser
8546
    */
8547
    bool parse_bson_internal()
8548
    {
8549
        std::int32_t document_size{};
8550
        get_number<std::int32_t, true>(input_format_t::bson, document_size);
8551
8552
        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8553
        {
8554
            return false;
8555
        }
8556
8557
        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8558
        {
8559
            return false;
8560
        }
8561
8562
        return sax->end_object();
8563
    }
8564
8565
    /*!
8566
    @brief Parses a C-style string from the BSON input.
8567
    @param[in,out] result  A reference to the string variable where the read
8568
                            string is to be stored.
8569
    @return `true` if the \x00-byte indicating the end of the string was
8570
             encountered before the EOF; false` indicates an unexpected EOF.
8571
    */
8572
    bool get_bson_cstr(string_t& result)
8573
    {
8574
        auto out = std::back_inserter(result);
8575
        while (true)
8576
        {
8577
            get();
8578
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8579
            {
8580
                return false;
8581
            }
8582
            if (current == 0x00)
8583
            {
8584
                return true;
8585
            }
8586
            *out++ = static_cast<typename string_t::value_type>(current);
8587
        }
8588
    }
8589
8590
    /*!
8591
    @brief Parses a zero-terminated string of length @a len from the BSON
8592
           input.
8593
    @param[in] len  The length (including the zero-byte at the end) of the
8594
                    string to be read.
8595
    @param[in,out] result  A reference to the string variable where the read
8596
                            string is to be stored.
8597
    @tparam NumberType The type of the length @a len
8598
    @pre len >= 1
8599
    @return `true` if the string was successfully parsed
8600
    */
8601
    template<typename NumberType>
8602
    bool get_bson_string(const NumberType len, string_t& result)
8603
    {
8604
        if (JSON_HEDLEY_UNLIKELY(len < 1))
8605
        {
8606
            auto last_token = get_token_string();
8607
            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"), BasicJsonType()));
8608
        }
8609
8610
        return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8611
    }
8612
8613
    /*!
8614
    @brief Parses a byte array input of length @a len from the BSON input.
8615
    @param[in] len  The length of the byte array to be read.
8616
    @param[in,out] result  A reference to the binary variable where the read
8617
                            array is to be stored.
8618
    @tparam NumberType The type of the length @a len
8619
    @pre len >= 0
8620
    @return `true` if the byte array was successfully parsed
8621
    */
8622
    template<typename NumberType>
8623
    bool get_bson_binary(const NumberType len, binary_t& result)
8624
    {
8625
        if (JSON_HEDLEY_UNLIKELY(len < 0))
8626
        {
8627
            auto last_token = get_token_string();
8628
            return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType()));
8629
        }
8630
8631
        // All BSON binary values have a subtype
8632
        std::uint8_t subtype{};
8633
        get_number<std::uint8_t>(input_format_t::bson, subtype);
8634
        result.set_subtype(subtype);
8635
8636
        return get_binary(input_format_t::bson, len, result);
8637
    }
8638
8639
    /*!
8640
    @brief Read a BSON document element of the given @a element_type.
8641
    @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
8642
    @param[in] element_type_parse_position The position in the input stream,
8643
               where the `element_type` was read.
8644
    @warning Not all BSON element types are supported yet. An unsupported
8645
             @a element_type will give rise to a parse_error.114:
8646
             Unsupported BSON record type 0x...
8647
    @return whether a valid BSON-object/array was passed to the SAX parser
8648
    */
8649
    bool parse_bson_element_internal(const char_int_type element_type,
8650
                                     const std::size_t element_type_parse_position)
8651
    {
8652
        switch (element_type)
8653
        {
8654
            case 0x01: // double
8655
            {
8656
                double number{};
8657
                return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8658
            }
8659
8660
            case 0x02: // string
8661
            {
8662
                std::int32_t len{};
8663
                string_t value;
8664
                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8665
            }
8666
8667
            case 0x03: // object
8668
            {
8669
                return parse_bson_internal();
8670
            }
8671
8672
            case 0x04: // array
8673
            {
8674
                return parse_bson_array();
8675
            }
8676
8677
            case 0x05: // binary
8678
            {
8679
                std::int32_t len{};
8680
                binary_t value;
8681
                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8682
            }
8683
8684
            case 0x08: // boolean
8685
            {
8686
                return sax->boolean(get() != 0);
8687
            }
8688
8689
            case 0x0A: // null
8690
            {
8691
                return sax->null();
8692
            }
8693
8694
            case 0x10: // int32
8695
            {
8696
                std::int32_t value{};
8697
                return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8698
            }
8699
8700
            case 0x12: // int64
8701
            {
8702
                std::int64_t value{};
8703
                return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8704
            }
8705
8706
            default: // anything else not supported (yet)
8707
            {
8708
                std::array<char, 3> cr{{}};
8709
                (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8710
                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()), BasicJsonType()));
8711
            }
8712
        }
8713
    }
8714
8715
    /*!
8716
    @brief Read a BSON element list (as specified in the BSON-spec)
8717
8718
    The same binary layout is used for objects and arrays, hence it must be
8719
    indicated with the argument @a is_array which one is expected
8720
    (true --> array, false --> object).
8721
8722
    @param[in] is_array Determines if the element list being read is to be
8723
                        treated as an object (@a is_array == false), or as an
8724
                        array (@a is_array == true).
8725
    @return whether a valid BSON-object/array was passed to the SAX parser
8726
    */
8727
    bool parse_bson_element_list(const bool is_array)
8728
    {
8729
        string_t key;
8730
8731
        while (auto element_type = get())
8732
        {
8733
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8734
            {
8735
                return false;
8736
            }
8737
8738
            const std::size_t element_type_parse_position = chars_read;
8739
            if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8740
            {
8741
                return false;
8742
            }
8743
8744
            if (!is_array && !sax->key(key))
8745
            {
8746
                return false;
8747
            }
8748
8749
            if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8750
            {
8751
                return false;
8752
            }
8753
8754
            // get_bson_cstr only appends
8755
            key.clear();
8756
        }
8757
8758
        return true;
8759
    }
8760
8761
    /*!
8762
    @brief Reads an array from the BSON input and passes it to the SAX-parser.
8763
    @return whether a valid BSON-array was passed to the SAX parser
8764
    */
8765
    bool parse_bson_array()
8766
    {
8767
        std::int32_t document_size{};
8768
        get_number<std::int32_t, true>(input_format_t::bson, document_size);
8769
8770
        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8771
        {
8772
            return false;
8773
        }
8774
8775
        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8776
        {
8777
            return false;
8778
        }
8779
8780
        return sax->end_array();
8781
    }
8782
8783
    //////////
8784
    // CBOR //
8785
    //////////
8786
8787
    /*!
8788
    @param[in] get_char  whether a new character should be retrieved from the
8789
                         input (true) or whether the last read character should
8790
                         be considered instead (false)
8791
    @param[in] tag_handler how CBOR tags should be treated
8792
8793
    @return whether a valid CBOR value was passed to the SAX parser
8794
    */
8795
    bool parse_cbor_internal(const bool get_char,
8796
                             const cbor_tag_handler_t tag_handler)
8797
    {
8798
        switch (get_char ? get() : current)
8799
        {
8800
            // EOF
8801
            case std::char_traits<char_type>::eof():
8802
                return unexpect_eof(input_format_t::cbor, "value");
8803
8804
            // Integer 0x00..0x17 (0..23)
8805
            case 0x00:
8806
            case 0x01:
8807
            case 0x02:
8808
            case 0x03:
8809
            case 0x04:
8810
            case 0x05:
8811
            case 0x06:
8812
            case 0x07:
8813
            case 0x08:
8814
            case 0x09:
8815
            case 0x0A:
8816
            case 0x0B:
8817
            case 0x0C:
8818
            case 0x0D:
8819
            case 0x0E:
8820
            case 0x0F:
8821
            case 0x10:
8822
            case 0x11:
8823
            case 0x12:
8824
            case 0x13:
8825
            case 0x14:
8826
            case 0x15:
8827
            case 0x16:
8828
            case 0x17:
8829
                return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8830
8831
            case 0x18: // Unsigned integer (one-byte uint8_t follows)
8832
            {
8833
                std::uint8_t number{};
8834
                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8835
            }
8836
8837
            case 0x19: // Unsigned integer (two-byte uint16_t follows)
8838
            {
8839
                std::uint16_t number{};
8840
                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8841
            }
8842
8843
            case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8844
            {
8845
                std::uint32_t number{};
8846
                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8847
            }
8848
8849
            case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8850
            {
8851
                std::uint64_t number{};
8852
                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8853
            }
8854
8855
            // Negative integer -1-0x00..-1-0x17 (-1..-24)
8856
            case 0x20:
8857
            case 0x21:
8858
            case 0x22:
8859
            case 0x23:
8860
            case 0x24:
8861
            case 0x25:
8862
            case 0x26:
8863
            case 0x27:
8864
            case 0x28:
8865
            case 0x29:
8866
            case 0x2A:
8867
            case 0x2B:
8868
            case 0x2C:
8869
            case 0x2D:
8870
            case 0x2E:
8871
            case 0x2F:
8872
            case 0x30:
8873
            case 0x31:
8874
            case 0x32:
8875
            case 0x33:
8876
            case 0x34:
8877
            case 0x35:
8878
            case 0x36:
8879
            case 0x37:
8880
                return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8881
8882
            case 0x38: // Negative integer (one-byte uint8_t follows)
8883
            {
8884
                std::uint8_t number{};
8885
                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8886
            }
8887
8888
            case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8889
            {
8890
                std::uint16_t number{};
8891
                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8892
            }
8893
8894
            case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8895
            {
8896
                std::uint32_t number{};
8897
                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8898
            }
8899
8900
            case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8901
            {
8902
                std::uint64_t number{};
8903
                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8904
                        - static_cast<number_integer_t>(number));
8905
            }
8906
8907
            // Binary data (0x00..0x17 bytes follow)
8908
            case 0x40:
8909
            case 0x41:
8910
            case 0x42:
8911
            case 0x43:
8912
            case 0x44:
8913
            case 0x45:
8914
            case 0x46:
8915
            case 0x47:
8916
            case 0x48:
8917
            case 0x49:
8918
            case 0x4A:
8919
            case 0x4B:
8920
            case 0x4C:
8921
            case 0x4D:
8922
            case 0x4E:
8923
            case 0x4F:
8924
            case 0x50:
8925
            case 0x51:
8926
            case 0x52:
8927
            case 0x53:
8928
            case 0x54:
8929
            case 0x55:
8930
            case 0x56:
8931
            case 0x57:
8932
            case 0x58: // Binary data (one-byte uint8_t for n follows)
8933
            case 0x59: // Binary data (two-byte uint16_t for n follow)
8934
            case 0x5A: // Binary data (four-byte uint32_t for n follow)
8935
            case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8936
            case 0x5F: // Binary data (indefinite length)
8937
            {
8938
                binary_t b;
8939
                return get_cbor_binary(b) && sax->binary(b);
8940
            }
8941
8942
            // UTF-8 string (0x00..0x17 bytes follow)
8943
            case 0x60:
8944
            case 0x61:
8945
            case 0x62:
8946
            case 0x63:
8947
            case 0x64:
8948
            case 0x65:
8949
            case 0x66:
8950
            case 0x67:
8951
            case 0x68:
8952
            case 0x69:
8953
            case 0x6A:
8954
            case 0x6B:
8955
            case 0x6C:
8956
            case 0x6D:
8957
            case 0x6E:
8958
            case 0x6F:
8959
            case 0x70:
8960
            case 0x71:
8961
            case 0x72:
8962
            case 0x73:
8963
            case 0x74:
8964
            case 0x75:
8965
            case 0x76:
8966
            case 0x77:
8967
            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8968
            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8969
            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8970
            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8971
            case 0x7F: // UTF-8 string (indefinite length)
8972
            {
8973
                string_t s;
8974
                return get_cbor_string(s) && sax->string(s);
8975
            }
8976
8977
            // array (0x00..0x17 data items follow)
8978
            case 0x80:
8979
            case 0x81:
8980
            case 0x82:
8981
            case 0x83:
8982
            case 0x84:
8983
            case 0x85:
8984
            case 0x86:
8985
            case 0x87:
8986
            case 0x88:
8987
            case 0x89:
8988
            case 0x8A:
8989
            case 0x8B:
8990
            case 0x8C:
8991
            case 0x8D:
8992
            case 0x8E:
8993
            case 0x8F:
8994
            case 0x90:
8995
            case 0x91:
8996
            case 0x92:
8997
            case 0x93:
8998
            case 0x94:
8999
            case 0x95:
9000
            case 0x96:
9001
            case 0x97:
9002
                return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9003
9004
            case 0x98: // array (one-byte uint8_t for n follows)
9005
            {
9006
                std::uint8_t len{};
9007
                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9008
            }
9009
9010
            case 0x99: // array (two-byte uint16_t for n follow)
9011
            {
9012
                std::uint16_t len{};
9013
                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9014
            }
9015
9016
            case 0x9A: // array (four-byte uint32_t for n follow)
9017
            {
9018
                std::uint32_t len{};
9019
                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9020
            }
9021
9022
            case 0x9B: // array (eight-byte uint64_t for n follow)
9023
            {
9024
                std::uint64_t len{};
9025
                return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9026
            }
9027
9028
            case 0x9F: // array (indefinite length)
9029
                return get_cbor_array(std::size_t(-1), tag_handler);
9030
9031
            // map (0x00..0x17 pairs of data items follow)
9032
            case 0xA0:
9033
            case 0xA1:
9034
            case 0xA2:
9035
            case 0xA3:
9036
            case 0xA4:
9037
            case 0xA5:
9038
            case 0xA6:
9039
            case 0xA7:
9040
            case 0xA8:
9041
            case 0xA9:
9042
            case 0xAA:
9043
            case 0xAB:
9044
            case 0xAC:
9045
            case 0xAD:
9046
            case 0xAE:
9047
            case 0xAF:
9048
            case 0xB0:
9049
            case 0xB1:
9050
            case 0xB2:
9051
            case 0xB3:
9052
            case 0xB4:
9053
            case 0xB5:
9054
            case 0xB6:
9055
            case 0xB7:
9056
                return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9057
9058
            case 0xB8: // map (one-byte uint8_t for n follows)
9059
            {
9060
                std::uint8_t len{};
9061
                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9062
            }
9063
9064
            case 0xB9: // map (two-byte uint16_t for n follow)
9065
            {
9066
                std::uint16_t len{};
9067
                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9068
            }
9069
9070
            case 0xBA: // map (four-byte uint32_t for n follow)
9071
            {
9072
                std::uint32_t len{};
9073
                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9074
            }
9075
9076
            case 0xBB: // map (eight-byte uint64_t for n follow)
9077
            {
9078
                std::uint64_t len{};
9079
                return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9080
            }
9081
9082
            case 0xBF: // map (indefinite length)
9083
                return get_cbor_object(std::size_t(-1), tag_handler);
9084
9085
            case 0xC6: // tagged item
9086
            case 0xC7:
9087
            case 0xC8:
9088
            case 0xC9:
9089
            case 0xCA:
9090
            case 0xCB:
9091
            case 0xCC:
9092
            case 0xCD:
9093
            case 0xCE:
9094
            case 0xCF:
9095
            case 0xD0:
9096
            case 0xD1:
9097
            case 0xD2:
9098
            case 0xD3:
9099
            case 0xD4:
9100
            case 0xD8: // tagged item (1 bytes follow)
9101
            case 0xD9: // tagged item (2 bytes follow)
9102
            case 0xDA: // tagged item (4 bytes follow)
9103
            case 0xDB: // tagged item (8 bytes follow)
9104
            {
9105
                switch (tag_handler)
9106
                {
9107
                    case cbor_tag_handler_t::error:
9108
                    {
9109
                        auto last_token = get_token_string();
9110
                        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"), BasicJsonType()));
9111
                    }
9112
9113
                    case cbor_tag_handler_t::ignore:
9114
                    {
9115
                        // ignore binary subtype
9116
                        switch (current)
9117
                        {
9118
                            case 0xD8:
9119
                            {
9120
                                std::uint8_t subtype_to_ignore{};
9121
                                get_number(input_format_t::cbor, subtype_to_ignore);
9122
                                break;
9123
                            }
9124
                            case 0xD9:
9125
                            {
9126
                                std::uint16_t subtype_to_ignore{};
9127
                                get_number(input_format_t::cbor, subtype_to_ignore);
9128
                                break;
9129
                            }
9130
                            case 0xDA:
9131
                            {
9132
                                std::uint32_t subtype_to_ignore{};
9133
                                get_number(input_format_t::cbor, subtype_to_ignore);
9134
                                break;
9135
                            }
9136
                            case 0xDB:
9137
                            {
9138
                                std::uint64_t subtype_to_ignore{};
9139
                                get_number(input_format_t::cbor, subtype_to_ignore);
9140
                                break;
9141
                            }
9142
                            default:
9143
                                break;
9144
                        }
9145
                        return parse_cbor_internal(true, tag_handler);
9146
                    }
9147
9148
                    case cbor_tag_handler_t::store:
9149
                    {
9150
                        binary_t b;
9151
                        // use binary subtype and store in binary container
9152
                        switch (current)
9153
                        {
9154
                            case 0xD8:
9155
                            {
9156
                                std::uint8_t subtype{};
9157
                                get_number(input_format_t::cbor, subtype);
9158
                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9159
                                break;
9160
                            }
9161
                            case 0xD9:
9162
                            {
9163
                                std::uint16_t subtype{};
9164
                                get_number(input_format_t::cbor, subtype);
9165
                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9166
                                break;
9167
                            }
9168
                            case 0xDA:
9169
                            {
9170
                                std::uint32_t subtype{};
9171
                                get_number(input_format_t::cbor, subtype);
9172
                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9173
                                break;
9174
                            }
9175
                            case 0xDB:
9176
                            {
9177
                                std::uint64_t subtype{};
9178
                                get_number(input_format_t::cbor, subtype);
9179
                                b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9180
                                break;
9181
                            }
9182
                            default:
9183
                                return parse_cbor_internal(true, tag_handler);
9184
                        }
9185
                        get();
9186
                        return get_cbor_binary(b) && sax->binary(b);
9187
                    }
9188
9189
                    default:                 // LCOV_EXCL_LINE
9190
                        JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9191
                        return false;        // LCOV_EXCL_LINE
9192
                }
9193
            }
9194
9195
            case 0xF4: // false
9196
                return sax->boolean(false);
9197
9198
            case 0xF5: // true
9199
                return sax->boolean(true);
9200
9201
            case 0xF6: // null
9202
                return sax->null();
9203
9204
            case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9205
            {
9206
                const auto byte1_raw = get();
9207
                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9208
                {
9209
                    return false;
9210
                }
9211
                const auto byte2_raw = get();
9212
                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9213
                {
9214
                    return false;
9215
                }
9216
9217
                const auto byte1 = static_cast<unsigned char>(byte1_raw);
9218
                const auto byte2 = static_cast<unsigned char>(byte2_raw);
9219
9220
                // code from RFC 7049, Appendix D, Figure 3:
9221
                // As half-precision floating-point numbers were only added
9222
                // to IEEE 754 in 2008, today's programming platforms often
9223
                // still only have limited support for them. It is very
9224
                // easy to include at least decoding support for them even
9225
                // without such support. An example of a small decoder for
9226
                // half-precision floating-point numbers in the C language
9227
                // is shown in Fig. 3.
9228
                const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9229
                const double val = [&half]
9230
                {
9231
                    const int exp = (half >> 10u) & 0x1Fu;
9232
                    const unsigned int mant = half & 0x3FFu;
9233
                    JSON_ASSERT(0 <= exp&& exp <= 32);
9234
                    JSON_ASSERT(mant <= 1024);
9235
                    switch (exp)
9236
                    {
9237
                        case 0:
9238
                            return std::ldexp(mant, -24);
9239
                        case 31:
9240
                            return (mant == 0)
9241
                            ? std::numeric_limits<double>::infinity()
9242
                            : std::numeric_limits<double>::quiet_NaN();
9243
                        default:
9244
                            return std::ldexp(mant + 1024, exp - 25);
9245
                    }
9246
                }();
9247
                return sax->number_float((half & 0x8000u) != 0
9248
                                         ? static_cast<number_float_t>(-val)
9249
                                         : static_cast<number_float_t>(val), "");
9250
            }
9251
9252
            case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9253
            {
9254
                float number{};
9255
                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9256
            }
9257
9258
            case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9259
            {
9260
                double number{};
9261
                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9262
            }
9263
9264
            default: // anything else (0xFF is handled inside the other types)
9265
            {
9266
                auto last_token = get_token_string();
9267
                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"), BasicJsonType()));
9268
            }
9269
        }
9270
    }
9271
9272
    /*!
9273
    @brief reads a CBOR string
9274
9275
    This function first reads starting bytes to determine the expected
9276
    string length and then copies this number of bytes into a string.
9277
    Additionally, CBOR's strings with indefinite lengths are supported.
9278
9279
    @param[out] result  created string
9280
9281
    @return whether string creation completed
9282
    */
9283
    bool get_cbor_string(string_t& result)
9284
    {
9285
        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9286
        {
9287
            return false;
9288
        }
9289
9290
        switch (current)
9291
        {
9292
            // UTF-8 string (0x00..0x17 bytes follow)
9293
            case 0x60:
9294
            case 0x61:
9295
            case 0x62:
9296
            case 0x63:
9297
            case 0x64:
9298
            case 0x65:
9299
            case 0x66:
9300
            case 0x67:
9301
            case 0x68:
9302
            case 0x69:
9303
            case 0x6A:
9304
            case 0x6B:
9305
            case 0x6C:
9306
            case 0x6D:
9307
            case 0x6E:
9308
            case 0x6F:
9309
            case 0x70:
9310
            case 0x71:
9311
            case 0x72:
9312
            case 0x73:
9313
            case 0x74:
9314
            case 0x75:
9315
            case 0x76:
9316
            case 0x77:
9317
            {
9318
                return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9319
            }
9320
9321
            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9322
            {
9323
                std::uint8_t len{};
9324
                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9325
            }
9326
9327
            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9328
            {
9329
                std::uint16_t len{};
9330
                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9331
            }
9332
9333
            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9334
            {
9335
                std::uint32_t len{};
9336
                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9337
            }
9338
9339
            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9340
            {
9341
                std::uint64_t len{};
9342
                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9343
            }
9344
9345
            case 0x7F: // UTF-8 string (indefinite length)
9346
            {
9347
                while (get() != 0xFF)
9348
                {
9349
                    string_t chunk;
9350
                    if (!get_cbor_string(chunk))
9351
                    {
9352
                        return false;
9353
                    }
9354
                    result.append(chunk);
9355
                }
9356
                return true;
9357
            }
9358
9359
            default:
9360
            {
9361
                auto last_token = get_token_string();
9362
                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"), BasicJsonType()));
9363
            }
9364
        }
9365
    }
9366
9367
    /*!
9368
    @brief reads a CBOR byte array
9369
9370
    This function first reads starting bytes to determine the expected
9371
    byte array length and then copies this number of bytes into the byte array.
9372
    Additionally, CBOR's byte arrays with indefinite lengths are supported.
9373
9374
    @param[out] result  created byte array
9375
9376
    @return whether byte array creation completed
9377
    */
9378
    bool get_cbor_binary(binary_t& result)
9379
    {
9380
        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9381
        {
9382
            return false;
9383
        }
9384
9385
        switch (current)
9386
        {
9387
            // Binary data (0x00..0x17 bytes follow)
9388
            case 0x40:
9389
            case 0x41:
9390
            case 0x42:
9391
            case 0x43:
9392
            case 0x44:
9393
            case 0x45:
9394
            case 0x46:
9395
            case 0x47:
9396
            case 0x48:
9397
            case 0x49:
9398
            case 0x4A:
9399
            case 0x4B:
9400
            case 0x4C:
9401
            case 0x4D:
9402
            case 0x4E:
9403
            case 0x4F:
9404
            case 0x50:
9405
            case 0x51:
9406
            case 0x52:
9407
            case 0x53:
9408
            case 0x54:
9409
            case 0x55:
9410
            case 0x56:
9411
            case 0x57:
9412
            {
9413
                return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9414
            }
9415
9416
            case 0x58: // Binary data (one-byte uint8_t for n follows)
9417
            {
9418
                std::uint8_t len{};
9419
                return get_number(input_format_t::cbor, len) &&
9420
                       get_binary(input_format_t::cbor, len, result);
9421
            }
9422
9423
            case 0x59: // Binary data (two-byte uint16_t for n follow)
9424
            {
9425
                std::uint16_t len{};
9426
                return get_number(input_format_t::cbor, len) &&
9427
                       get_binary(input_format_t::cbor, len, result);
9428
            }
9429
9430
            case 0x5A: // Binary data (four-byte uint32_t for n follow)
9431
            {
9432
                std::uint32_t len{};
9433
                return get_number(input_format_t::cbor, len) &&
9434
                       get_binary(input_format_t::cbor, len, result);
9435
            }
9436
9437
            case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9438
            {
9439
                std::uint64_t len{};
9440
                return get_number(input_format_t::cbor, len) &&
9441
                       get_binary(input_format_t::cbor, len, result);
9442
            }
9443
9444
            case 0x5F: // Binary data (indefinite length)
9445
            {
9446
                while (get() != 0xFF)
9447
                {
9448
                    binary_t chunk;
9449
                    if (!get_cbor_binary(chunk))
9450
                    {
9451
                        return false;
9452
                    }
9453
                    result.insert(result.end(), chunk.begin(), chunk.end());
9454
                }
9455
                return true;
9456
            }
9457
9458
            default:
9459
            {
9460
                auto last_token = get_token_string();
9461
                return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType()));
9462
            }
9463
        }
9464
    }
9465
9466
    /*!
9467
    @param[in] len  the length of the array or std::size_t(-1) for an
9468
                    array of indefinite size
9469
    @param[in] tag_handler how CBOR tags should be treated
9470
    @return whether array creation completed
9471
    */
9472
    bool get_cbor_array(const std::size_t len,
9473
                        const cbor_tag_handler_t tag_handler)
9474
    {
9475
        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9476
        {
9477
            return false;
9478
        }
9479
9480
        if (len != std::size_t(-1))
9481
        {
9482
            for (std::size_t i = 0; i < len; ++i)
9483
            {
9484
                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9485
                {
9486
                    return false;
9487
                }
9488
            }
9489
        }
9490
        else
9491
        {
9492
            while (get() != 0xFF)
9493
            {
9494
                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9495
                {
9496
                    return false;
9497
                }
9498
            }
9499
        }
9500
9501
        return sax->end_array();
9502
    }
9503
9504
    /*!
9505
    @param[in] len  the length of the object or std::size_t(-1) for an
9506
                    object of indefinite size
9507
    @param[in] tag_handler how CBOR tags should be treated
9508
    @return whether object creation completed
9509
    */
9510
    bool get_cbor_object(const std::size_t len,
9511
                         const cbor_tag_handler_t tag_handler)
9512
    {
9513
        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9514
        {
9515
            return false;
9516
        }
9517
9518
        if (len != 0)
9519
        {
9520
            string_t key;
9521
            if (len != std::size_t(-1))
9522
            {
9523
                for (std::size_t i = 0; i < len; ++i)
9524
                {
9525
                    get();
9526
                    if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9527
                    {
9528
                        return false;
9529
                    }
9530
9531
                    if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9532
                    {
9533
                        return false;
9534
                    }
9535
                    key.clear();
9536
                }
9537
            }
9538
            else
9539
            {
9540
                while (get() != 0xFF)
9541
                {
9542
                    if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9543
                    {
9544
                        return false;
9545
                    }
9546
9547
                    if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9548
                    {
9549
                        return false;
9550
                    }
9551
                    key.clear();
9552
                }
9553
            }
9554
        }
9555
9556
        return sax->end_object();
9557
    }
9558
9559
    /////////////
9560
    // MsgPack //
9561
    /////////////
9562
9563
    /*!
9564
    @return whether a valid MessagePack value was passed to the SAX parser
9565
    */
9566
    bool parse_msgpack_internal()
9567
    {
9568
        switch (get())
9569
        {
9570
            // EOF
9571
            case std::char_traits<char_type>::eof():
9572
                return unexpect_eof(input_format_t::msgpack, "value");
9573
9574
            // positive fixint
9575
            case 0x00:
9576
            case 0x01:
9577
            case 0x02:
9578
            case 0x03:
9579
            case 0x04:
9580
            case 0x05:
9581
            case 0x06:
9582
            case 0x07:
9583
            case 0x08:
9584
            case 0x09:
9585
            case 0x0A:
9586
            case 0x0B:
9587
            case 0x0C:
9588
            case 0x0D:
9589
            case 0x0E:
9590
            case 0x0F:
9591
            case 0x10:
9592
            case 0x11:
9593
            case 0x12:
9594
            case 0x13:
9595
            case 0x14:
9596
            case 0x15:
9597
            case 0x16:
9598
            case 0x17:
9599
            case 0x18:
9600
            case 0x19:
9601
            case 0x1A:
9602
            case 0x1B:
9603
            case 0x1C:
9604
            case 0x1D:
9605
            case 0x1E:
9606
            case 0x1F:
9607
            case 0x20:
9608
            case 0x21:
9609
            case 0x22:
9610
            case 0x23:
9611
            case 0x24:
9612
            case 0x25:
9613
            case 0x26:
9614
            case 0x27:
9615
            case 0x28:
9616
            case 0x29:
9617
            case 0x2A:
9618
            case 0x2B:
9619
            case 0x2C:
9620
            case 0x2D:
9621
            case 0x2E:
9622
            case 0x2F:
9623
            case 0x30:
9624
            case 0x31:
9625
            case 0x32:
9626
            case 0x33:
9627
            case 0x34:
9628
            case 0x35:
9629
            case 0x36:
9630
            case 0x37:
9631
            case 0x38:
9632
            case 0x39:
9633
            case 0x3A:
9634
            case 0x3B:
9635
            case 0x3C:
9636
            case 0x3D:
9637
            case 0x3E:
9638
            case 0x3F:
9639
            case 0x40:
9640
            case 0x41:
9641
            case 0x42:
9642
            case 0x43:
9643
            case 0x44:
9644
            case 0x45:
9645
            case 0x46:
9646
            case 0x47:
9647
            case 0x48:
9648
            case 0x49:
9649
            case 0x4A:
9650
            case 0x4B:
9651
            case 0x4C:
9652
            case 0x4D:
9653
            case 0x4E:
9654
            case 0x4F:
9655
            case 0x50:
9656
            case 0x51:
9657
            case 0x52:
9658
            case 0x53:
9659
            case 0x54:
9660
            case 0x55:
9661
            case 0x56:
9662
            case 0x57:
9663
            case 0x58:
9664
            case 0x59:
9665
            case 0x5A:
9666
            case 0x5B:
9667
            case 0x5C:
9668
            case 0x5D:
9669
            case 0x5E:
9670
            case 0x5F:
9671
            case 0x60:
9672
            case 0x61:
9673
            case 0x62:
9674
            case 0x63:
9675
            case 0x64:
9676
            case 0x65:
9677
            case 0x66:
9678
            case 0x67:
9679
            case 0x68:
9680
            case 0x69:
9681
            case 0x6A:
9682
            case 0x6B:
9683
            case 0x6C:
9684
            case 0x6D:
9685
            case 0x6E:
9686
            case 0x6F:
9687
            case 0x70:
9688
            case 0x71:
9689
            case 0x72:
9690
            case 0x73:
9691
            case 0x74:
9692
            case 0x75:
9693
            case 0x76:
9694
            case 0x77:
9695
            case 0x78:
9696
            case 0x79:
9697
            case 0x7A:
9698
            case 0x7B:
9699
            case 0x7C:
9700
            case 0x7D:
9701
            case 0x7E:
9702
            case 0x7F:
9703
                return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9704
9705
            // fixmap
9706
            case 0x80:
9707
            case 0x81:
9708
            case 0x82:
9709
            case 0x83:
9710
            case 0x84:
9711
            case 0x85:
9712
            case 0x86:
9713
            case 0x87:
9714
            case 0x88:
9715
            case 0x89:
9716
            case 0x8A:
9717
            case 0x8B:
9718
            case 0x8C:
9719
            case 0x8D:
9720
            case 0x8E:
9721
            case 0x8F:
9722
                return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9723
9724
            // fixarray
9725
            case 0x90:
9726
            case 0x91:
9727
            case 0x92:
9728
            case 0x93:
9729
            case 0x94:
9730
            case 0x95:
9731
            case 0x96:
9732
            case 0x97:
9733
            case 0x98:
9734
            case 0x99:
9735
            case 0x9A:
9736
            case 0x9B:
9737
            case 0x9C:
9738
            case 0x9D:
9739
            case 0x9E:
9740
            case 0x9F:
9741
                return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9742
9743
            // fixstr
9744
            case 0xA0:
9745
            case 0xA1:
9746
            case 0xA2:
9747
            case 0xA3:
9748
            case 0xA4:
9749
            case 0xA5:
9750
            case 0xA6:
9751
            case 0xA7:
9752
            case 0xA8:
9753
            case 0xA9:
9754
            case 0xAA:
9755
            case 0xAB:
9756
            case 0xAC:
9757
            case 0xAD:
9758
            case 0xAE:
9759
            case 0xAF:
9760
            case 0xB0:
9761
            case 0xB1:
9762
            case 0xB2:
9763
            case 0xB3:
9764
            case 0xB4:
9765
            case 0xB5:
9766
            case 0xB6:
9767
            case 0xB7:
9768
            case 0xB8:
9769
            case 0xB9:
9770
            case 0xBA:
9771
            case 0xBB:
9772
            case 0xBC:
9773
            case 0xBD:
9774
            case 0xBE:
9775
            case 0xBF:
9776
            case 0xD9: // str 8
9777
            case 0xDA: // str 16
9778
            case 0xDB: // str 32
9779
            {
9780
                string_t s;
9781
                return get_msgpack_string(s) && sax->string(s);
9782
            }
9783
9784
            case 0xC0: // nil
9785
                return sax->null();
9786
9787
            case 0xC2: // false
9788
                return sax->boolean(false);
9789
9790
            case 0xC3: // true
9791
                return sax->boolean(true);
9792
9793
            case 0xC4: // bin 8
9794
            case 0xC5: // bin 16
9795
            case 0xC6: // bin 32
9796
            case 0xC7: // ext 8
9797
            case 0xC8: // ext 16
9798
            case 0xC9: // ext 32
9799
            case 0xD4: // fixext 1
9800
            case 0xD5: // fixext 2
9801
            case 0xD6: // fixext 4
9802
            case 0xD7: // fixext 8
9803
            case 0xD8: // fixext 16
9804
            {
9805
                binary_t b;
9806
                return get_msgpack_binary(b) && sax->binary(b);
9807
            }
9808
9809
            case 0xCA: // float 32
9810
            {
9811
                float number{};
9812
                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9813
            }
9814
9815
            case 0xCB: // float 64
9816
            {
9817
                double number{};
9818
                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9819
            }
9820
9821
            case 0xCC: // uint 8
9822
            {
9823
                std::uint8_t number{};
9824
                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9825
            }
9826
9827
            case 0xCD: // uint 16
9828
            {
9829
                std::uint16_t number{};
9830
                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9831
            }
9832
9833
            case 0xCE: // uint 32
9834
            {
9835
                std::uint32_t number{};
9836
                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9837
            }
9838
9839
            case 0xCF: // uint 64
9840
            {
9841
                std::uint64_t number{};
9842
                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9843
            }
9844
9845
            case 0xD0: // int 8
9846
            {
9847
                std::int8_t number{};
9848
                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9849
            }
9850
9851
            case 0xD1: // int 16
9852
            {
9853
                std::int16_t number{};
9854
                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9855
            }
9856
9857
            case 0xD2: // int 32
9858
            {
9859
                std::int32_t number{};
9860
                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9861
            }
9862
9863
            case 0xD3: // int 64
9864
            {
9865
                std::int64_t number{};
9866
                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9867
            }
9868
9869
            case 0xDC: // array 16
9870
            {
9871
                std::uint16_t len{};
9872
                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9873
            }
9874
9875
            case 0xDD: // array 32
9876
            {
9877
                std::uint32_t len{};
9878
                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9879
            }
9880
9881
            case 0xDE: // map 16
9882
            {
9883
                std::uint16_t len{};
9884
                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9885
            }
9886
9887
            case 0xDF: // map 32
9888
            {
9889
                std::uint32_t len{};
9890
                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9891
            }
9892
9893
            // negative fixint
9894
            case 0xE0:
9895
            case 0xE1:
9896
            case 0xE2:
9897
            case 0xE3:
9898
            case 0xE4:
9899
            case 0xE5:
9900
            case 0xE6:
9901
            case 0xE7:
9902
            case 0xE8:
9903
            case 0xE9:
9904
            case 0xEA:
9905
            case 0xEB:
9906
            case 0xEC:
9907
            case 0xED:
9908
            case 0xEE:
9909
            case 0xEF:
9910
            case 0xF0:
9911
            case 0xF1:
9912
            case 0xF2:
9913
            case 0xF3:
9914
            case 0xF4:
9915
            case 0xF5:
9916
            case 0xF6:
9917
            case 0xF7:
9918
            case 0xF8:
9919
            case 0xF9:
9920
            case 0xFA:
9921
            case 0xFB:
9922
            case 0xFC:
9923
            case 0xFD:
9924
            case 0xFE:
9925
            case 0xFF:
9926
                return sax->number_integer(static_cast<std::int8_t>(current));
9927
9928
            default: // anything else
9929
            {
9930
                auto last_token = get_token_string();
9931
                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"), BasicJsonType()));
9932
            }
9933
        }
9934
    }
9935
9936
    /*!
9937
    @brief reads a MessagePack string
9938
9939
    This function first reads starting bytes to determine the expected
9940
    string length and then copies this number of bytes into a string.
9941
9942
    @param[out] result  created string
9943
9944
    @return whether string creation completed
9945
    */
9946
    bool get_msgpack_string(string_t& result)
9947
    {
9948
        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9949
        {
9950
            return false;
9951
        }
9952
9953
        switch (current)
9954
        {
9955
            // fixstr
9956
            case 0xA0:
9957
            case 0xA1:
9958
            case 0xA2:
9959
            case 0xA3:
9960
            case 0xA4:
9961
            case 0xA5:
9962
            case 0xA6:
9963
            case 0xA7:
9964
            case 0xA8:
9965
            case 0xA9:
9966
            case 0xAA:
9967
            case 0xAB:
9968
            case 0xAC:
9969
            case 0xAD:
9970
            case 0xAE:
9971
            case 0xAF:
9972
            case 0xB0:
9973
            case 0xB1:
9974
            case 0xB2:
9975
            case 0xB3:
9976
            case 0xB4:
9977
            case 0xB5:
9978
            case 0xB6:
9979
            case 0xB7:
9980
            case 0xB8:
9981
            case 0xB9:
9982
            case 0xBA:
9983
            case 0xBB:
9984
            case 0xBC:
9985
            case 0xBD:
9986
            case 0xBE:
9987
            case 0xBF:
9988
            {
9989
                return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9990
            }
9991
9992
            case 0xD9: // str 8
9993
            {
9994
                std::uint8_t len{};
9995
                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9996
            }
9997
9998
            case 0xDA: // str 16
9999
            {
10000
                std::uint16_t len{};
10001
                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10002
            }
10003
10004
            case 0xDB: // str 32
10005
            {
10006
                std::uint32_t len{};
10007
                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10008
            }
10009
10010
            default:
10011
            {
10012
                auto last_token = get_token_string();
10013
                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"), BasicJsonType()));
10014
            }
10015
        }
10016
    }
10017
10018
    /*!
10019
    @brief reads a MessagePack byte array
10020
10021
    This function first reads starting bytes to determine the expected
10022
    byte array length and then copies this number of bytes into a byte array.
10023
10024
    @param[out] result  created byte array
10025
10026
    @return whether byte array creation completed
10027
    */
10028
    bool get_msgpack_binary(binary_t& result)
10029
    {
10030
        // helper function to set the subtype
10031
        auto assign_and_return_true = [&result](std::int8_t subtype)
10032
        {
10033
            result.set_subtype(static_cast<std::uint8_t>(subtype));
10034
            return true;
10035
        };
10036
10037
        switch (current)
10038
        {
10039
            case 0xC4: // bin 8
10040
            {
10041
                std::uint8_t len{};
10042
                return get_number(input_format_t::msgpack, len) &&
10043
                       get_binary(input_format_t::msgpack, len, result);
10044
            }
10045
10046
            case 0xC5: // bin 16
10047
            {
10048
                std::uint16_t len{};
10049
                return get_number(input_format_t::msgpack, len) &&
10050
                       get_binary(input_format_t::msgpack, len, result);
10051
            }
10052
10053
            case 0xC6: // bin 32
10054
            {
10055
                std::uint32_t len{};
10056
                return get_number(input_format_t::msgpack, len) &&
10057
                       get_binary(input_format_t::msgpack, len, result);
10058
            }
10059
10060
            case 0xC7: // ext 8
10061
            {
10062
                std::uint8_t len{};
10063
                std::int8_t subtype{};
10064
                return get_number(input_format_t::msgpack, len) &&
10065
                       get_number(input_format_t::msgpack, subtype) &&
10066
                       get_binary(input_format_t::msgpack, len, result) &&
10067
                       assign_and_return_true(subtype);
10068
            }
10069
10070
            case 0xC8: // ext 16
10071
            {
10072
                std::uint16_t len{};
10073
                std::int8_t subtype{};
10074
                return get_number(input_format_t::msgpack, len) &&
10075
                       get_number(input_format_t::msgpack, subtype) &&
10076
                       get_binary(input_format_t::msgpack, len, result) &&
10077
                       assign_and_return_true(subtype);
10078
            }
10079
10080
            case 0xC9: // ext 32
10081
            {
10082
                std::uint32_t len{};
10083
                std::int8_t subtype{};
10084
                return get_number(input_format_t::msgpack, len) &&
10085
                       get_number(input_format_t::msgpack, subtype) &&
10086
                       get_binary(input_format_t::msgpack, len, result) &&
10087
                       assign_and_return_true(subtype);
10088
            }
10089
10090
            case 0xD4: // fixext 1
10091
            {
10092
                std::int8_t subtype{};
10093
                return get_number(input_format_t::msgpack, subtype) &&
10094
                       get_binary(input_format_t::msgpack, 1, result) &&
10095
                       assign_and_return_true(subtype);
10096
            }
10097
10098
            case 0xD5: // fixext 2
10099
            {
10100
                std::int8_t subtype{};
10101
                return get_number(input_format_t::msgpack, subtype) &&
10102
                       get_binary(input_format_t::msgpack, 2, result) &&
10103
                       assign_and_return_true(subtype);
10104
            }
10105
10106
            case 0xD6: // fixext 4
10107
            {
10108
                std::int8_t subtype{};
10109
                return get_number(input_format_t::msgpack, subtype) &&
10110
                       get_binary(input_format_t::msgpack, 4, result) &&
10111
                       assign_and_return_true(subtype);
10112
            }
10113
10114
            case 0xD7: // fixext 8
10115
            {
10116
                std::int8_t subtype{};
10117
                return get_number(input_format_t::msgpack, subtype) &&
10118
                       get_binary(input_format_t::msgpack, 8, result) &&
10119
                       assign_and_return_true(subtype);
10120
            }
10121
10122
            case 0xD8: // fixext 16
10123
            {
10124
                std::int8_t subtype{};
10125
                return get_number(input_format_t::msgpack, subtype) &&
10126
                       get_binary(input_format_t::msgpack, 16, result) &&
10127
                       assign_and_return_true(subtype);
10128
            }
10129
10130
            default:           // LCOV_EXCL_LINE
10131
                return false;  // LCOV_EXCL_LINE
10132
        }
10133
    }
10134
10135
    /*!
10136
    @param[in] len  the length of the array
10137
    @return whether array creation completed
10138
    */
10139
    bool get_msgpack_array(const std::size_t len)
10140
    {
10141
        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10142
        {
10143
            return false;
10144
        }
10145
10146
        for (std::size_t i = 0; i < len; ++i)
10147
        {
10148
            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10149
            {
10150
                return false;
10151
            }
10152
        }
10153
10154
        return sax->end_array();
10155
    }
10156
10157
    /*!
10158
    @param[in] len  the length of the object
10159
    @return whether object creation completed
10160
    */
10161
    bool get_msgpack_object(const std::size_t len)
10162
    {
10163
        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10164
        {
10165
            return false;
10166
        }
10167
10168
        string_t key;
10169
        for (std::size_t i = 0; i < len; ++i)
10170
        {
10171
            get();
10172
            if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10173
            {
10174
                return false;
10175
            }
10176
10177
            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10178
            {
10179
                return false;
10180
            }
10181
            key.clear();
10182
        }
10183
10184
        return sax->end_object();
10185
    }
10186
10187
    ////////////
10188
    // UBJSON //
10189
    ////////////
10190
10191
    /*!
10192
    @param[in] get_char  whether a new character should be retrieved from the
10193
                         input (true, default) or whether the last read
10194
                         character should be considered instead
10195
10196
    @return whether a valid UBJSON value was passed to the SAX parser
10197
    */
10198
    bool parse_ubjson_internal(const bool get_char = true)
10199
    {
10200
        return get_ubjson_value(get_char ? get_ignore_noop() : current);
10201
    }
10202
10203
    /*!
10204
    @brief reads a UBJSON string
10205
10206
    This function is either called after reading the 'S' byte explicitly
10207
    indicating a string, or in case of an object key where the 'S' byte can be
10208
    left out.
10209
10210
    @param[out] result   created string
10211
    @param[in] get_char  whether a new character should be retrieved from the
10212
                         input (true, default) or whether the last read
10213
                         character should be considered instead
10214
10215
    @return whether string creation completed
10216
    */
10217
    bool get_ubjson_string(string_t& result, const bool get_char = true)
10218
    {
10219
        if (get_char)
10220
        {
10221
            get();  // TODO(niels): may we ignore N here?
10222
        }
10223
10224
        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10225
        {
10226
            return false;
10227
        }
10228
10229
        switch (current)
10230
        {
10231
            case 'U':
10232
            {
10233
                std::uint8_t len{};
10234
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10235
            }
10236
10237
            case 'i':
10238
            {
10239
                std::int8_t len{};
10240
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10241
            }
10242
10243
            case 'I':
10244
            {
10245
                std::int16_t len{};
10246
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10247
            }
10248
10249
            case 'l':
10250
            {
10251
                std::int32_t len{};
10252
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10253
            }
10254
10255
            case 'L':
10256
            {
10257
                std::int64_t len{};
10258
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10259
            }
10260
10261
            default:
10262
                auto last_token = get_token_string();
10263
                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"), BasicJsonType()));
10264
        }
10265
    }
10266
10267
    /*!
10268
    @param[out] result  determined size
10269
    @return whether size determination completed
10270
    */
10271
    bool get_ubjson_size_value(std::size_t& result)
10272
    {
10273
        switch (get_ignore_noop())
10274
        {
10275
            case 'U':
10276
            {
10277
                std::uint8_t number{};
10278
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10279
                {
10280
                    return false;
10281
                }
10282
                result = static_cast<std::size_t>(number);
10283
                return true;
10284
            }
10285
10286
            case 'i':
10287
            {
10288
                std::int8_t number{};
10289
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10290
                {
10291
                    return false;
10292
                }
10293
                result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10294
                return true;
10295
            }
10296
10297
            case 'I':
10298
            {
10299
                std::int16_t number{};
10300
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10301
                {
10302
                    return false;
10303
                }
10304
                result = static_cast<std::size_t>(number);
10305
                return true;
10306
            }
10307
10308
            case 'l':
10309
            {
10310
                std::int32_t number{};
10311
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10312
                {
10313
                    return false;
10314
                }
10315
                result = static_cast<std::size_t>(number);
10316
                return true;
10317
            }
10318
10319
            case 'L':
10320
            {
10321
                std::int64_t number{};
10322
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10323
                {
10324
                    return false;
10325
                }
10326
                result = static_cast<std::size_t>(number);
10327
                return true;
10328
            }
10329
10330
            default:
10331
            {
10332
                auto last_token = get_token_string();
10333
                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"), BasicJsonType()));
10334
            }
10335
        }
10336
    }
10337
10338
    /*!
10339
    @brief determine the type and size for a container
10340
10341
    In the optimized UBJSON format, a type and a size can be provided to allow
10342
    for a more compact representation.
10343
10344
    @param[out] result  pair of the size and the type
10345
10346
    @return whether pair creation completed
10347
    */
10348
    bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10349
    {
10350
        result.first = string_t::npos; // size
10351
        result.second = 0; // type
10352
10353
        get_ignore_noop();
10354
10355
        if (current == '$')
10356
        {
10357
            result.second = get();  // must not ignore 'N', because 'N' maybe the type
10358
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10359
            {
10360
                return false;
10361
            }
10362
10363
            get_ignore_noop();
10364
            if (JSON_HEDLEY_UNLIKELY(current != '#'))
10365
            {
10366
                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10367
                {
10368
                    return false;
10369
                }
10370
                auto last_token = get_token_string();
10371
                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"), BasicJsonType()));
10372
            }
10373
10374
            return get_ubjson_size_value(result.first);
10375
        }
10376
10377
        if (current == '#')
10378
        {
10379
            return get_ubjson_size_value(result.first);
10380
        }
10381
10382
        return true;
10383
    }
10384
10385
    /*!
10386
    @param prefix  the previously read or set type prefix
10387
    @return whether value creation completed
10388
    */
10389
    bool get_ubjson_value(const char_int_type prefix)
10390
    {
10391
        switch (prefix)
10392
        {
10393
            case std::char_traits<char_type>::eof():  // EOF
10394
                return unexpect_eof(input_format_t::ubjson, "value");
10395
10396
            case 'T':  // true
10397
                return sax->boolean(true);
10398
            case 'F':  // false
10399
                return sax->boolean(false);
10400
10401
            case 'Z':  // null
10402
                return sax->null();
10403
10404
            case 'U':
10405
            {
10406
                std::uint8_t number{};
10407
                return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10408
            }
10409
10410
            case 'i':
10411
            {
10412
                std::int8_t number{};
10413
                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10414
            }
10415
10416
            case 'I':
10417
            {
10418
                std::int16_t number{};
10419
                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10420
            }
10421
10422
            case 'l':
10423
            {
10424
                std::int32_t number{};
10425
                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10426
            }
10427
10428
            case 'L':
10429
            {
10430
                std::int64_t number{};
10431
                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10432
            }
10433
10434
            case 'd':
10435
            {
10436
                float number{};
10437
                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10438
            }
10439
10440
            case 'D':
10441
            {
10442
                double number{};
10443
                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10444
            }
10445
10446
            case 'H':
10447
            {
10448
                return get_ubjson_high_precision_number();
10449
            }
10450
10451
            case 'C':  // char
10452
            {
10453
                get();
10454
                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10455
                {
10456
                    return false;
10457
                }
10458
                if (JSON_HEDLEY_UNLIKELY(current > 127))
10459
                {
10460
                    auto last_token = get_token_string();
10461
                    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"), BasicJsonType()));
10462
                }
10463
                string_t s(1, static_cast<typename string_t::value_type>(current));
10464
                return sax->string(s);
10465
            }
10466
10467
            case 'S':  // string
10468
            {
10469
                string_t s;
10470
                return get_ubjson_string(s) && sax->string(s);
10471
            }
10472
10473
            case '[':  // array
10474
                return get_ubjson_array();
10475
10476
            case '{':  // object
10477
                return get_ubjson_object();
10478
10479
            default: // anything else
10480
            {
10481
                auto last_token = get_token_string();
10482
                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"), BasicJsonType()));
10483
            }
10484
        }
10485
    }
10486
10487
    /*!
10488
    @return whether array creation completed
10489
    */
10490
    bool get_ubjson_array()
10491
    {
10492
        std::pair<std::size_t, char_int_type> size_and_type;
10493
        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10494
        {
10495
            return false;
10496
        }
10497
10498
        if (size_and_type.first != string_t::npos)
10499
        {
10500
            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10501
            {
10502
                return false;
10503
            }
10504
10505
            if (size_and_type.second != 0)
10506
            {
10507
                if (size_and_type.second != 'N')
10508
                {
10509
                    for (std::size_t i = 0; i < size_and_type.first; ++i)
10510
                    {
10511
                        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10512
                        {
10513
                            return false;
10514
                        }
10515
                    }
10516
                }
10517
            }
10518
            else
10519
            {
10520
                for (std::size_t i = 0; i < size_and_type.first; ++i)
10521
                {
10522
                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10523
                    {
10524
                        return false;
10525
                    }
10526
                }
10527
            }
10528
        }
10529
        else
10530
        {
10531
            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10532
            {
10533
                return false;
10534
            }
10535
10536
            while (current != ']')
10537
            {
10538
                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10539
                {
10540
                    return false;
10541
                }
10542
                get_ignore_noop();
10543
            }
10544
        }
10545
10546
        return sax->end_array();
10547
    }
10548
10549
    /*!
10550
    @return whether object creation completed
10551
    */
10552
    bool get_ubjson_object()
10553
    {
10554
        std::pair<std::size_t, char_int_type> size_and_type;
10555
        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10556
        {
10557
            return false;
10558
        }
10559
10560
        string_t key;
10561
        if (size_and_type.first != string_t::npos)
10562
        {
10563
            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10564
            {
10565
                return false;
10566
            }
10567
10568
            if (size_and_type.second != 0)
10569
            {
10570
                for (std::size_t i = 0; i < size_and_type.first; ++i)
10571
                {
10572
                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10573
                    {
10574
                        return false;
10575
                    }
10576
                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10577
                    {
10578
                        return false;
10579
                    }
10580
                    key.clear();
10581
                }
10582
            }
10583
            else
10584
            {
10585
                for (std::size_t i = 0; i < size_and_type.first; ++i)
10586
                {
10587
                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10588
                    {
10589
                        return false;
10590
                    }
10591
                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10592
                    {
10593
                        return false;
10594
                    }
10595
                    key.clear();
10596
                }
10597
            }
10598
        }
10599
        else
10600
        {
10601
            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10602
            {
10603
                return false;
10604
            }
10605
10606
            while (current != '}')
10607
            {
10608
                if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10609
                {
10610
                    return false;
10611
                }
10612
                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10613
                {
10614
                    return false;
10615
                }
10616
                get_ignore_noop();
10617
                key.clear();
10618
            }
10619
        }
10620
10621
        return sax->end_object();
10622
    }
10623
10624
    // Note, no reader for UBJSON binary types is implemented because they do
10625
    // not exist
10626
10627
    bool get_ubjson_high_precision_number()
10628
    {
10629
        // get size of following number string
10630
        std::size_t size{};
10631
        auto res = get_ubjson_size_value(size);
10632
        if (JSON_HEDLEY_UNLIKELY(!res))
10633
        {
10634
            return res;
10635
        }
10636
10637
        // get number string
10638
        std::vector<char> number_vector;
10639
        for (std::size_t i = 0; i < size; ++i)
10640
        {
10641
            get();
10642
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10643
            {
10644
                return false;
10645
            }
10646
            number_vector.push_back(static_cast<char>(current));
10647
        }
10648
10649
        // parse number string
10650
        using ia_type = decltype(detail::input_adapter(number_vector));
10651
        auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10652
        const auto result_number = number_lexer.scan();
10653
        const auto number_string = number_lexer.get_token_string();
10654
        const auto result_remainder = number_lexer.scan();
10655
10656
        using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10657
10658
        if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10659
        {
10660
            return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10661
        }
10662
10663
        switch (result_number)
10664
        {
10665
            case token_type::value_integer:
10666
                return sax->number_integer(number_lexer.get_number_integer());
10667
            case token_type::value_unsigned:
10668
                return sax->number_unsigned(number_lexer.get_number_unsigned());
10669
            case token_type::value_float:
10670
                return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10671
            case token_type::uninitialized:
10672
            case token_type::literal_true:
10673
            case token_type::literal_false:
10674
            case token_type::literal_null:
10675
            case token_type::value_string:
10676
            case token_type::begin_array:
10677
            case token_type::begin_object:
10678
            case token_type::end_array:
10679
            case token_type::end_object:
10680
            case token_type::name_separator:
10681
            case token_type::value_separator:
10682
            case token_type::parse_error:
10683
            case token_type::end_of_input:
10684
            case token_type::literal_or_value:
10685
            default:
10686
                return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10687
        }
10688
    }
10689
10690
    ///////////////////////
10691
    // Utility functions //
10692
    ///////////////////////
10693
10694
    /*!
10695
    @brief get next character from the input
10696
10697
    This function provides the interface to the used input adapter. It does
10698
    not throw in case the input reached EOF, but returns a -'ve valued
10699
    `std::char_traits<char_type>::eof()` in that case.
10700
10701
    @return character read from the input
10702
    */
10703
    char_int_type get()
10704
    {
10705
        ++chars_read;
10706
        return current = ia.get_character();
10707
    }
10708
10709
    /*!
10710
    @return character read from the input after ignoring all 'N' entries
10711
    */
10712
    char_int_type get_ignore_noop()
10713
    {
10714
        do
10715
        {
10716
            get();
10717
        }
10718
        while (current == 'N');
10719
10720
        return current;
10721
    }
10722
10723
    /*
10724
    @brief read a number from the input
10725
10726
    @tparam NumberType the type of the number
10727
    @param[in] format   the current format (for diagnostics)
10728
    @param[out] result  number of type @a NumberType
10729
10730
    @return whether conversion completed
10731
10732
    @note This function needs to respect the system's endianess, because
10733
          bytes in CBOR, MessagePack, and UBJSON are stored in network order
10734
          (big endian) and therefore need reordering on little endian systems.
10735
    */
10736
    template<typename NumberType, bool InputIsLittleEndian = false>
10737
    bool get_number(const input_format_t format, NumberType& result)
10738
    {
10739
        // step 1: read input into array with system's byte order
10740
        std::array<std::uint8_t, sizeof(NumberType)> vec{};
10741
        for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10742
        {
10743
            get();
10744
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10745
            {
10746
                return false;
10747
            }
10748
10749
            // reverse byte order prior to conversion if necessary
10750
            if (is_little_endian != InputIsLittleEndian)
10751
            {
10752
                vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10753
            }
10754
            else
10755
            {
10756
                vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10757
            }
10758
        }
10759
10760
        // step 2: convert array into number of type T and return
10761
        std::memcpy(&result, vec.data(), sizeof(NumberType));
10762
        return true;
10763
    }
10764
10765
    /*!
10766
    @brief create a string by reading characters from the input
10767
10768
    @tparam NumberType the type of the number
10769
    @param[in] format the current format (for diagnostics)
10770
    @param[in] len number of characters to read
10771
    @param[out] result string created by reading @a len bytes
10772
10773
    @return whether string creation completed
10774
10775
    @note We can not reserve @a len bytes for the result, because @a len
10776
          may be too large. Usually, @ref unexpect_eof() detects the end of
10777
          the input before we run out of string memory.
10778
    */
10779
    template<typename NumberType>
10780
    bool get_string(const input_format_t format,
10781
                    const NumberType len,
10782
                    string_t& result)
10783
    {
10784
        bool success = true;
10785
        for (NumberType i = 0; i < len; i++)
10786
        {
10787
            get();
10788
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10789
            {
10790
                success = false;
10791
                break;
10792
            }
10793
            result.push_back(static_cast<typename string_t::value_type>(current));
10794
        }
10795
        return success;
10796
    }
10797
10798
    /*!
10799
    @brief create a byte array by reading bytes from the input
10800
10801
    @tparam NumberType the type of the number
10802
    @param[in] format the current format (for diagnostics)
10803
    @param[in] len number of bytes to read
10804
    @param[out] result byte array created by reading @a len bytes
10805
10806
    @return whether byte array creation completed
10807
10808
    @note We can not reserve @a len bytes for the result, because @a len
10809
          may be too large. Usually, @ref unexpect_eof() detects the end of
10810
          the input before we run out of memory.
10811
    */
10812
    template<typename NumberType>
10813
    bool get_binary(const input_format_t format,
10814
                    const NumberType len,
10815
                    binary_t& result)
10816
    {
10817
        bool success = true;
10818
        for (NumberType i = 0; i < len; i++)
10819
        {
10820
            get();
10821
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10822
            {
10823
                success = false;
10824
                break;
10825
            }
10826
            result.push_back(static_cast<std::uint8_t>(current));
10827
        }
10828
        return success;
10829
    }
10830
10831
    /*!
10832
    @param[in] format   the current format (for diagnostics)
10833
    @param[in] context  further context information (for diagnostics)
10834
    @return whether the last read character is not EOF
10835
    */
10836
    JSON_HEDLEY_NON_NULL(3)
10837
    bool unexpect_eof(const input_format_t format, const char* context) const
10838
    {
10839
        if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10840
        {
10841
            return sax->parse_error(chars_read, "<end of file>",
10842
                                    parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10843
        }
10844
        return true;
10845
    }
10846
10847
    /*!
10848
    @return a string representation of the last read byte
10849
    */
10850
    std::string get_token_string() const
10851
    {
10852
        std::array<char, 3> cr{{}};
10853
        (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10854
        return std::string{cr.data()};
10855
    }
10856
10857
    /*!
10858
    @param[in] format   the current format
10859
    @param[in] detail   a detailed error message
10860
    @param[in] context  further context information
10861
    @return a message string to use in the parse_error exceptions
10862
    */
10863
    std::string exception_message(const input_format_t format,
10864
                                  const std::string& detail,
10865
                                  const std::string& context) const
10866
    {
10867
        std::string error_msg = "syntax error while parsing ";
10868
10869
        switch (format)
10870
        {
10871
            case input_format_t::cbor:
10872
                error_msg += "CBOR";
10873
                break;
10874
10875
            case input_format_t::msgpack:
10876
                error_msg += "MessagePack";
10877
                break;
10878
10879
            case input_format_t::ubjson:
10880
                error_msg += "UBJSON";
10881
                break;
10882
10883
            case input_format_t::bson:
10884
                error_msg += "BSON";
10885
                break;
10886
10887
            case input_format_t::json: // LCOV_EXCL_LINE
10888
            default:            // LCOV_EXCL_LINE
10889
                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10890
        }
10891
10892
        return error_msg + " " + context + ": " + detail;
10893
    }
10894
10895
  private:
10896
    /// input adapter
10897
    InputAdapterType ia;
10898
10899
    /// the current character
10900
    char_int_type current = std::char_traits<char_type>::eof();
10901
10902
    /// the number of characters read
10903
    std::size_t chars_read = 0;
10904
10905
    /// whether we can assume little endianess
10906
    const bool is_little_endian = little_endianess();
10907
10908
    /// the SAX parser
10909
    json_sax_t* sax = nullptr;
10910
};
10911
}  // namespace detail
10912
}  // namespace nlohmann
10913
10914
// #include <nlohmann/detail/input/input_adapters.hpp>
10915
10916
// #include <nlohmann/detail/input/lexer.hpp>
10917
10918
// #include <nlohmann/detail/input/parser.hpp>
10919
10920
10921
#include <cmath> // isfinite
10922
#include <cstdint> // uint8_t
10923
#include <functional> // function
10924
#include <string> // string
10925
#include <utility> // move
10926
#include <vector> // vector
10927
10928
// #include <nlohmann/detail/exceptions.hpp>
10929
10930
// #include <nlohmann/detail/input/input_adapters.hpp>
10931
10932
// #include <nlohmann/detail/input/json_sax.hpp>
10933
10934
// #include <nlohmann/detail/input/lexer.hpp>
10935
10936
// #include <nlohmann/detail/macro_scope.hpp>
10937
10938
// #include <nlohmann/detail/meta/is_sax.hpp>
10939
10940
// #include <nlohmann/detail/value_t.hpp>
10941
10942
10943
namespace nlohmann
10944
{
10945
namespace detail
10946
{
10947
////////////
10948
// parser //
10949
////////////
10950
10951
enum class parse_event_t : std::uint8_t
10952
{
10953
    /// the parser read `{` and started to process a JSON object
10954
    object_start,
10955
    /// the parser read `}` and finished processing a JSON object
10956
    object_end,
10957
    /// the parser read `[` and started to process a JSON array
10958
    array_start,
10959
    /// the parser read `]` and finished processing a JSON array
10960
    array_end,
10961
    /// the parser read a key of a value in an object
10962
    key,
10963
    /// the parser finished reading a JSON value
10964
    value
10965
};
10966
10967
template<typename BasicJsonType>
10968
using parser_callback_t =
10969
    std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10970
10971
/*!
10972
@brief syntax analysis
10973
10974
This class implements a recursive descent parser.
10975
*/
10976
template<typename BasicJsonType, typename InputAdapterType>
10977
class parser
10978
{
10979
    using number_integer_t = typename BasicJsonType::number_integer_t;
10980
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10981
    using number_float_t = typename BasicJsonType::number_float_t;
10982
    using string_t = typename BasicJsonType::string_t;
10983
    using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10984
    using token_type = typename lexer_t::token_type;
10985
10986
  public:
10987
    /// a parser reading from an input adapter
10988
    explicit parser(InputAdapterType&& adapter,
10989
                    const parser_callback_t<BasicJsonType> cb = nullptr,
10990
                    const bool allow_exceptions_ = true,
10991
                    const bool skip_comments = false)
10992
        : callback(cb)
10993
        , m_lexer(std::move(adapter), skip_comments)
10994
        , allow_exceptions(allow_exceptions_)
10995
1.82k
    {
10996
        // read first token
10997
1.82k
        get_token();
10998
1.82k
    }
10999
11000
    /*!
11001
    @brief public parser interface
11002
11003
    @param[in] strict      whether to expect the last token to be EOF
11004
    @param[in,out] result  parsed JSON value
11005
11006
    @throw parse_error.101 in case of an unexpected token
11007
    @throw parse_error.102 if to_unicode fails or surrogate error
11008
    @throw parse_error.103 if to_unicode fails
11009
    */
11010
    void parse(const bool strict, BasicJsonType& result)
11011
1.82k
    {
11012
1.82k
        if (callback)
11013
0
        {
11014
0
            json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
11015
0
            sax_parse_internal(&sdp);
11016
11017
            // in strict mode, input must be completely read
11018
0
            if (strict && (get_token() != token_type::end_of_input))
11019
0
            {
11020
0
                sdp.parse_error(m_lexer.get_position(),
11021
0
                                m_lexer.get_token_string(),
11022
0
                                parse_error::create(101, m_lexer.get_position(),
11023
0
                                                    exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11024
0
            }
11025
11026
            // in case of an error, return discarded value
11027
0
            if (sdp.is_errored())
11028
0
            {
11029
0
                result = value_t::discarded;
11030
0
                return;
11031
0
            }
11032
11033
            // set top-level value to null if it was discarded by the callback
11034
            // function
11035
0
            if (result.is_discarded())
11036
0
            {
11037
0
                result = nullptr;
11038
0
            }
11039
0
        }
11040
1.82k
        else
11041
1.82k
        {
11042
1.82k
            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
11043
1.82k
            sax_parse_internal(&sdp);
11044
11045
            // in strict mode, input must be completely read
11046
1.82k
            if (strict && (get_token() != token_type::end_of_input))
11047
1
            {
11048
1
                sdp.parse_error(m_lexer.get_position(),
11049
1
                                m_lexer.get_token_string(),
11050
1
                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11051
1
            }
11052
11053
            // in case of an error, return discarded value
11054
1.82k
            if (sdp.is_errored())
11055
0
            {
11056
0
                result = value_t::discarded;
11057
0
                return;
11058
0
            }
11059
1.82k
        }
11060
11061
1.82k
        result.assert_invariant();
11062
1.82k
    }
11063
11064
    /*!
11065
    @brief public accept interface
11066
11067
    @param[in] strict  whether to expect the last token to be EOF
11068
    @return whether the input is a proper JSON text
11069
    */
11070
    bool accept(const bool strict = true)
11071
    {
11072
        json_sax_acceptor<BasicJsonType> sax_acceptor;
11073
        return sax_parse(&sax_acceptor, strict);
11074
    }
11075
11076
    template<typename SAX>
11077
    JSON_HEDLEY_NON_NULL(2)
11078
    bool sax_parse(SAX* sax, const bool strict = true)
11079
    {
11080
        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
11081
        const bool result = sax_parse_internal(sax);
11082
11083
        // strict mode: next byte must be EOF
11084
        if (result && strict && (get_token() != token_type::end_of_input))
11085
        {
11086
            return sax->parse_error(m_lexer.get_position(),
11087
                                    m_lexer.get_token_string(),
11088
                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11089
        }
11090
11091
        return result;
11092
    }
11093
11094
  private:
11095
    template<typename SAX>
11096
    JSON_HEDLEY_NON_NULL(2)
11097
    bool sax_parse_internal(SAX* sax)
11098
1.82k
    {
11099
        // stack to remember the hierarchy of structured values we are parsing
11100
        // true = array; false = object
11101
1.82k
        std::vector<bool> states;
11102
        // value to avoid a goto (see comment where set to true)
11103
1.82k
        bool skip_to_state_evaluation = false;
11104
11105
13.8M
        while (true)
11106
13.8M
        {
11107
13.8M
            if (!skip_to_state_evaluation)
11108
13.5M
            {
11109
                // invariant: get_token() was called before each iteration
11110
13.5M
                switch (last_token)
11111
13.5M
                {
11112
1.55M
                    case token_type::begin_object:
11113
1.55M
                    {
11114
1.55M
                        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11115
0
                        {
11116
0
                            return false;
11117
0
                        }
11118
11119
                        // closing } -> we are done
11120
1.55M
                        if (get_token() == token_type::end_object)
11121
1.11M
                        {
11122
1.11M
                            if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11123
0
                            {
11124
0
                                return false;
11125
0
                            }
11126
1.11M
                            break;
11127
1.11M
                        }
11128
11129
                        // parse key
11130
435k
                        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11131
11
                        {
11132
11
                            return sax->parse_error(m_lexer.get_position(),
11133
11
                                                    m_lexer.get_token_string(),
11134
11
                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11135
11
                        }
11136
435k
                        if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11137
0
                        {
11138
0
                            return false;
11139
0
                        }
11140
11141
                        // parse separator (:)
11142
435k
                        if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11143
8
                        {
11144
8
                            return sax->parse_error(m_lexer.get_position(),
11145
8
                                                    m_lexer.get_token_string(),
11146
8
                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11147
8
                        }
11148
11149
                        // remember we are now inside an object
11150
435k
                        states.push_back(false);
11151
11152
                        // parse values
11153
435k
                        get_token();
11154
435k
                        continue;
11155
435k
                    }
11156
11157
5.67M
                    case token_type::begin_array:
11158
5.67M
                    {
11159
5.67M
                        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11160
0
                        {
11161
0
                            return false;
11162
0
                        }
11163
11164
                        // closing ] -> we are done
11165
5.67M
                        if (get_token() == token_type::end_array)
11166
5.90k
                        {
11167
5.90k
                            if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11168
0
                            {
11169
0
                                return false;
11170
0
                            }
11171
5.90k
                            break;
11172
5.90k
                        }
11173
11174
                        // remember we are now inside an array
11175
5.67M
                        states.push_back(true);
11176
11177
                        // parse values (no need to call get_token)
11178
5.67M
                        continue;
11179
5.67M
                    }
11180
11181
50.0k
                    case token_type::value_float:
11182
50.0k
                    {
11183
50.0k
                        const auto res = m_lexer.get_number_float();
11184
11185
50.0k
                        if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11186
4
                        {
11187
4
                            return sax->parse_error(m_lexer.get_position(),
11188
4
                                                    m_lexer.get_token_string(),
11189
4
                                                    out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11190
4
                        }
11191
11192
50.0k
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11193
0
                        {
11194
0
                            return false;
11195
0
                        }
11196
11197
50.0k
                        break;
11198
50.0k
                    }
11199
11200
50.0k
                    case token_type::literal_false:
11201
137
                    {
11202
137
                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11203
0
                        {
11204
0
                            return false;
11205
0
                        }
11206
137
                        break;
11207
137
                    }
11208
11209
23.6k
                    case token_type::literal_null:
11210
23.6k
                    {
11211
23.6k
                        if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11212
0
                        {
11213
0
                            return false;
11214
0
                        }
11215
23.6k
                        break;
11216
23.6k
                    }
11217
11218
23.6k
                    case token_type::literal_true:
11219
22.6k
                    {
11220
22.6k
                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11221
0
                        {
11222
0
                            return false;
11223
0
                        }
11224
22.6k
                        break;
11225
22.6k
                    }
11226
11227
22.6k
                    case token_type::value_integer:
11228
20.4k
                    {
11229
20.4k
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11230
0
                        {
11231
0
                            return false;
11232
0
                        }
11233
20.4k
                        break;
11234
20.4k
                    }
11235
11236
71.5k
                    case token_type::value_string:
11237
71.5k
                    {
11238
71.5k
                        if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11239
0
                        {
11240
0
                            return false;
11241
0
                        }
11242
71.5k
                        break;
11243
71.5k
                    }
11244
11245
6.13M
                    case token_type::value_unsigned:
11246
6.13M
                    {
11247
6.13M
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11248
0
                        {
11249
0
                            return false;
11250
0
                        }
11251
6.13M
                        break;
11252
6.13M
                    }
11253
11254
6.13M
                    case token_type::parse_error:
11255
42
                    {
11256
                        // using "uninitialized" to avoid "expected" message
11257
42
                        return sax->parse_error(m_lexer.get_position(),
11258
42
                                                m_lexer.get_token_string(),
11259
42
                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11260
6.13M
                    }
11261
11262
0
                    case token_type::uninitialized:
11263
0
                    case token_type::end_array:
11264
0
                    case token_type::end_object:
11265
0
                    case token_type::name_separator:
11266
3
                    case token_type::value_separator:
11267
29
                    case token_type::end_of_input:
11268
29
                    case token_type::literal_or_value:
11269
29
                    default: // the last token was unexpected
11270
29
                    {
11271
29
                        return sax->parse_error(m_lexer.get_position(),
11272
29
                                                m_lexer.get_token_string(),
11273
29
                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11274
29
                    }
11275
13.5M
                }
11276
13.5M
            }
11277
265k
            else
11278
265k
            {
11279
265k
                skip_to_state_evaluation = false;
11280
265k
            }
11281
11282
            // we reached this line after we successfully parsed a value
11283
7.70M
            if (states.empty())
11284
1.60k
            {
11285
                // empty stack: we reached the end of the hierarchy: done
11286
1.60k
                return true;
11287
1.60k
            }
11288
11289
7.70M
            if (states.back())  // array
11290
7.43M
            {
11291
                // comma -> next value
11292
7.43M
                if (get_token() == token_type::value_separator)
11293
7.38M
                {
11294
                    // parse a new value
11295
7.38M
                    get_token();
11296
7.38M
                    continue;
11297
7.38M
                }
11298
11299
                // closing ]
11300
51.9k
                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11301
51.9k
                {
11302
51.9k
                    if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11303
0
                    {
11304
0
                        return false;
11305
0
                    }
11306
11307
                    // We are done with this array. Before we can parse a
11308
                    // new value, we need to evaluate the new state first.
11309
                    // By setting skip_to_state_evaluation to false, we
11310
                    // are effectively jumping to the beginning of this if.
11311
51.9k
                    JSON_ASSERT(!states.empty());
11312
0
                    states.pop_back();
11313
51.9k
                    skip_to_state_evaluation = true;
11314
51.9k
                    continue;
11315
51.9k
                }
11316
11317
73
                return sax->parse_error(m_lexer.get_position(),
11318
73
                                        m_lexer.get_token_string(),
11319
73
                                        parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11320
51.9k
            }
11321
11322
            // states.back() is false -> object
11323
11324
            // comma -> next value
11325
266k
            if (get_token() == token_type::value_separator)
11326
53.0k
            {
11327
                // parse key
11328
53.0k
                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11329
4
                {
11330
4
                    return sax->parse_error(m_lexer.get_position(),
11331
4
                                            m_lexer.get_token_string(),
11332
4
                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11333
4
                }
11334
11335
53.0k
                if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11336
0
                {
11337
0
                    return false;
11338
0
                }
11339
11340
                // parse separator (:)
11341
53.0k
                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11342
33
                {
11343
33
                    return sax->parse_error(m_lexer.get_position(),
11344
33
                                            m_lexer.get_token_string(),
11345
33
                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11346
33
                }
11347
11348
                // parse values
11349
53.0k
                get_token();
11350
53.0k
                continue;
11351
53.0k
            }
11352
11353
            // closing }
11354
213k
            if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11355
213k
            {
11356
213k
                if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11357
0
                {
11358
0
                    return false;
11359
0
                }
11360
11361
                // We are done with this object. Before we can parse a
11362
                // new value, we need to evaluate the new state first.
11363
                // By setting skip_to_state_evaluation to false, we
11364
                // are effectively jumping to the beginning of this if.
11365
213k
                JSON_ASSERT(!states.empty());
11366
0
                states.pop_back();
11367
213k
                skip_to_state_evaluation = true;
11368
213k
                continue;
11369
213k
            }
11370
11371
9
            return sax->parse_error(m_lexer.get_position(),
11372
9
                                    m_lexer.get_token_string(),
11373
9
                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11374
213k
        }
11375
1.82k
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<char const*> >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >(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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >*)
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::detail::iterator_input_adapter<char const*> >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >(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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >*)
Line
Count
Source
11098
1.82k
    {
11099
        // stack to remember the hierarchy of structured values we are parsing
11100
        // true = array; false = object
11101
1.82k
        std::vector<bool> states;
11102
        // value to avoid a goto (see comment where set to true)
11103
1.82k
        bool skip_to_state_evaluation = false;
11104
11105
13.8M
        while (true)
11106
13.8M
        {
11107
13.8M
            if (!skip_to_state_evaluation)
11108
13.5M
            {
11109
                // invariant: get_token() was called before each iteration
11110
13.5M
                switch (last_token)
11111
13.5M
                {
11112
1.55M
                    case token_type::begin_object:
11113
1.55M
                    {
11114
1.55M
                        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11115
0
                        {
11116
0
                            return false;
11117
0
                        }
11118
11119
                        // closing } -> we are done
11120
1.55M
                        if (get_token() == token_type::end_object)
11121
1.11M
                        {
11122
1.11M
                            if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11123
0
                            {
11124
0
                                return false;
11125
0
                            }
11126
1.11M
                            break;
11127
1.11M
                        }
11128
11129
                        // parse key
11130
435k
                        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11131
11
                        {
11132
11
                            return sax->parse_error(m_lexer.get_position(),
11133
11
                                                    m_lexer.get_token_string(),
11134
11
                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11135
11
                        }
11136
435k
                        if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11137
0
                        {
11138
0
                            return false;
11139
0
                        }
11140
11141
                        // parse separator (:)
11142
435k
                        if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11143
8
                        {
11144
8
                            return sax->parse_error(m_lexer.get_position(),
11145
8
                                                    m_lexer.get_token_string(),
11146
8
                                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11147
8
                        }
11148
11149
                        // remember we are now inside an object
11150
435k
                        states.push_back(false);
11151
11152
                        // parse values
11153
435k
                        get_token();
11154
435k
                        continue;
11155
435k
                    }
11156
11157
5.67M
                    case token_type::begin_array:
11158
5.67M
                    {
11159
5.67M
                        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11160
0
                        {
11161
0
                            return false;
11162
0
                        }
11163
11164
                        // closing ] -> we are done
11165
5.67M
                        if (get_token() == token_type::end_array)
11166
5.90k
                        {
11167
5.90k
                            if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11168
0
                            {
11169
0
                                return false;
11170
0
                            }
11171
5.90k
                            break;
11172
5.90k
                        }
11173
11174
                        // remember we are now inside an array
11175
5.67M
                        states.push_back(true);
11176
11177
                        // parse values (no need to call get_token)
11178
5.67M
                        continue;
11179
5.67M
                    }
11180
11181
50.0k
                    case token_type::value_float:
11182
50.0k
                    {
11183
50.0k
                        const auto res = m_lexer.get_number_float();
11184
11185
50.0k
                        if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11186
4
                        {
11187
4
                            return sax->parse_error(m_lexer.get_position(),
11188
4
                                                    m_lexer.get_token_string(),
11189
4
                                                    out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11190
4
                        }
11191
11192
50.0k
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11193
0
                        {
11194
0
                            return false;
11195
0
                        }
11196
11197
50.0k
                        break;
11198
50.0k
                    }
11199
11200
50.0k
                    case token_type::literal_false:
11201
137
                    {
11202
137
                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11203
0
                        {
11204
0
                            return false;
11205
0
                        }
11206
137
                        break;
11207
137
                    }
11208
11209
23.6k
                    case token_type::literal_null:
11210
23.6k
                    {
11211
23.6k
                        if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11212
0
                        {
11213
0
                            return false;
11214
0
                        }
11215
23.6k
                        break;
11216
23.6k
                    }
11217
11218
23.6k
                    case token_type::literal_true:
11219
22.6k
                    {
11220
22.6k
                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11221
0
                        {
11222
0
                            return false;
11223
0
                        }
11224
22.6k
                        break;
11225
22.6k
                    }
11226
11227
22.6k
                    case token_type::value_integer:
11228
20.4k
                    {
11229
20.4k
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11230
0
                        {
11231
0
                            return false;
11232
0
                        }
11233
20.4k
                        break;
11234
20.4k
                    }
11235
11236
71.5k
                    case token_type::value_string:
11237
71.5k
                    {
11238
71.5k
                        if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11239
0
                        {
11240
0
                            return false;
11241
0
                        }
11242
71.5k
                        break;
11243
71.5k
                    }
11244
11245
6.13M
                    case token_type::value_unsigned:
11246
6.13M
                    {
11247
6.13M
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11248
0
                        {
11249
0
                            return false;
11250
0
                        }
11251
6.13M
                        break;
11252
6.13M
                    }
11253
11254
6.13M
                    case token_type::parse_error:
11255
42
                    {
11256
                        // using "uninitialized" to avoid "expected" message
11257
42
                        return sax->parse_error(m_lexer.get_position(),
11258
42
                                                m_lexer.get_token_string(),
11259
42
                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11260
6.13M
                    }
11261
11262
0
                    case token_type::uninitialized:
11263
0
                    case token_type::end_array:
11264
0
                    case token_type::end_object:
11265
0
                    case token_type::name_separator:
11266
3
                    case token_type::value_separator:
11267
29
                    case token_type::end_of_input:
11268
29
                    case token_type::literal_or_value:
11269
29
                    default: // the last token was unexpected
11270
29
                    {
11271
29
                        return sax->parse_error(m_lexer.get_position(),
11272
29
                                                m_lexer.get_token_string(),
11273
29
                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11274
29
                    }
11275
13.5M
                }
11276
13.5M
            }
11277
265k
            else
11278
265k
            {
11279
265k
                skip_to_state_evaluation = false;
11280
265k
            }
11281
11282
            // we reached this line after we successfully parsed a value
11283
7.70M
            if (states.empty())
11284
1.60k
            {
11285
                // empty stack: we reached the end of the hierarchy: done
11286
1.60k
                return true;
11287
1.60k
            }
11288
11289
7.70M
            if (states.back())  // array
11290
7.43M
            {
11291
                // comma -> next value
11292
7.43M
                if (get_token() == token_type::value_separator)
11293
7.38M
                {
11294
                    // parse a new value
11295
7.38M
                    get_token();
11296
7.38M
                    continue;
11297
7.38M
                }
11298
11299
                // closing ]
11300
51.9k
                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11301
51.9k
                {
11302
51.9k
                    if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11303
0
                    {
11304
0
                        return false;
11305
0
                    }
11306
11307
                    // We are done with this array. Before we can parse a
11308
                    // new value, we need to evaluate the new state first.
11309
                    // By setting skip_to_state_evaluation to false, we
11310
                    // are effectively jumping to the beginning of this if.
11311
51.9k
                    JSON_ASSERT(!states.empty());
11312
0
                    states.pop_back();
11313
51.9k
                    skip_to_state_evaluation = true;
11314
51.9k
                    continue;
11315
51.9k
                }
11316
11317
73
                return sax->parse_error(m_lexer.get_position(),
11318
73
                                        m_lexer.get_token_string(),
11319
73
                                        parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11320
51.9k
            }
11321
11322
            // states.back() is false -> object
11323
11324
            // comma -> next value
11325
266k
            if (get_token() == token_type::value_separator)
11326
53.0k
            {
11327
                // parse key
11328
53.0k
                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11329
4
                {
11330
4
                    return sax->parse_error(m_lexer.get_position(),
11331
4
                                            m_lexer.get_token_string(),
11332
4
                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11333
4
                }
11334
11335
53.0k
                if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11336
0
                {
11337
0
                    return false;
11338
0
                }
11339
11340
                // parse separator (:)
11341
53.0k
                if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11342
33
                {
11343
33
                    return sax->parse_error(m_lexer.get_position(),
11344
33
                                            m_lexer.get_token_string(),
11345
33
                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11346
33
                }
11347
11348
                // parse values
11349
53.0k
                get_token();
11350
53.0k
                continue;
11351
53.0k
            }
11352
11353
            // closing }
11354
213k
            if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11355
213k
            {
11356
213k
                if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11357
0
                {
11358
0
                    return false;
11359
0
                }
11360
11361
                // We are done with this object. Before we can parse a
11362
                // new value, we need to evaluate the new state first.
11363
                // By setting skip_to_state_evaluation to false, we
11364
                // are effectively jumping to the beginning of this if.
11365
213k
                JSON_ASSERT(!states.empty());
11366
0
                states.pop_back();
11367
213k
                skip_to_state_evaluation = true;
11368
213k
                continue;
11369
213k
            }
11370
11371
9
            return sax->parse_error(m_lexer.get_position(),
11372
9
                                    m_lexer.get_token_string(),
11373
9
                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11374
213k
        }
11375
1.82k
    }
11376
11377
    /// get next token from lexer
11378
    token_type get_token()
11379
23.3M
    {
11380
23.3M
        return last_token = m_lexer.scan();
11381
23.3M
    }
11382
11383
    std::string exception_message(const token_type expected, const std::string& context)
11384
210
    {
11385
210
        std::string error_msg = "syntax error ";
11386
11387
210
        if (!context.empty())
11388
210
        {
11389
210
            error_msg += "while parsing " + context + " ";
11390
210
        }
11391
11392
210
        error_msg += "- ";
11393
11394
210
        if (last_token == token_type::parse_error)
11395
110
        {
11396
110
            error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11397
110
                         m_lexer.get_token_string() + "'";
11398
110
        }
11399
100
        else
11400
100
        {
11401
100
            error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11402
100
        }
11403
11404
210
        if (expected != token_type::uninitialized)
11405
168
        {
11406
168
            error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11407
168
        }
11408
11409
210
        return error_msg;
11410
210
    }
11411
11412
  private:
11413
    /// callback function
11414
    const parser_callback_t<BasicJsonType> callback = nullptr;
11415
    /// the type of the last read token
11416
    token_type last_token = token_type::uninitialized;
11417
    /// the lexer
11418
    lexer_t m_lexer;
11419
    /// whether to throw exceptions in case of errors
11420
    const bool allow_exceptions = true;
11421
};
11422
11423
}  // namespace detail
11424
}  // namespace nlohmann
11425
11426
// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11427
11428
11429
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11430
11431
11432
#include <cstddef> // ptrdiff_t
11433
#include <limits>  // numeric_limits
11434
11435
// #include <nlohmann/detail/macro_scope.hpp>
11436
11437
11438
namespace nlohmann
11439
{
11440
namespace detail
11441
{
11442
/*
11443
@brief an iterator for primitive JSON types
11444
11445
This class models an iterator for primitive JSON types (boolean, number,
11446
string). It's only purpose is to allow the iterator/const_iterator classes
11447
to "iterate" over primitive values. Internally, the iterator is modeled by
11448
a `difference_type` variable. Value begin_value (`0`) models the begin,
11449
end_value (`1`) models past the end.
11450
*/
11451
class primitive_iterator_t
11452
{
11453
  private:
11454
    using difference_type = std::ptrdiff_t;
11455
    static constexpr difference_type begin_value = 0;
11456
    static constexpr difference_type end_value = begin_value + 1;
11457
11458
  JSON_PRIVATE_UNLESS_TESTED:
11459
    /// iterator as signed integer type
11460
    difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11461
11462
  public:
11463
    constexpr difference_type get_value() const noexcept
11464
0
    {
11465
0
        return m_it;
11466
0
    }
11467
11468
    /// set iterator to a defined beginning
11469
    void set_begin() noexcept
11470
0
    {
11471
0
        m_it = begin_value;
11472
0
    }
11473
11474
    /// set iterator to a defined past the end
11475
    void set_end() noexcept
11476
9.21M
    {
11477
9.21M
        m_it = end_value;
11478
9.21M
    }
11479
11480
    /// return whether the iterator can be dereferenced
11481
    constexpr bool is_begin() const noexcept
11482
0
    {
11483
0
        return m_it == begin_value;
11484
0
    }
11485
11486
    /// return whether the iterator is at end
11487
    constexpr bool is_end() const noexcept
11488
0
    {
11489
0
        return m_it == end_value;
11490
0
    }
11491
11492
    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11493
4.60M
    {
11494
4.60M
        return lhs.m_it == rhs.m_it;
11495
4.60M
    }
11496
11497
    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11498
0
    {
11499
0
        return lhs.m_it < rhs.m_it;
11500
0
    }
11501
11502
    primitive_iterator_t operator+(difference_type n) noexcept
11503
0
    {
11504
0
        auto result = *this;
11505
0
        result += n;
11506
0
        return result;
11507
0
    }
11508
11509
    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11510
0
    {
11511
0
        return lhs.m_it - rhs.m_it;
11512
0
    }
11513
11514
    primitive_iterator_t& operator++() noexcept
11515
0
    {
11516
0
        ++m_it;
11517
0
        return *this;
11518
0
    }
11519
11520
    primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11521
0
    {
11522
0
        auto result = *this;
11523
0
        ++m_it;
11524
0
        return result;
11525
0
    }
11526
11527
    primitive_iterator_t& operator--() noexcept
11528
0
    {
11529
0
        --m_it;
11530
0
        return *this;
11531
0
    }
11532
11533
    primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11534
0
    {
11535
0
        auto result = *this;
11536
0
        --m_it;
11537
0
        return result;
11538
0
    }
11539
11540
    primitive_iterator_t& operator+=(difference_type n) noexcept
11541
0
    {
11542
0
        m_it += n;
11543
0
        return *this;
11544
0
    }
11545
11546
    primitive_iterator_t& operator-=(difference_type n) noexcept
11547
0
    {
11548
0
        m_it -= n;
11549
0
        return *this;
11550
0
    }
11551
};
11552
}  // namespace detail
11553
}  // namespace nlohmann
11554
11555
11556
namespace nlohmann
11557
{
11558
namespace detail
11559
{
11560
/*!
11561
@brief an iterator value
11562
11563
@note This structure could easily be a union, but MSVC currently does not allow
11564
unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
11565
*/
11566
template<typename BasicJsonType> struct internal_iterator
11567
{
11568
    /// iterator for JSON objects
11569
    typename BasicJsonType::object_t::iterator object_iterator {};
11570
    /// iterator for JSON arrays
11571
    typename BasicJsonType::array_t::iterator array_iterator {};
11572
    /// generic iterator for all other types
11573
    primitive_iterator_t primitive_iterator {};
11574
};
11575
}  // namespace detail
11576
}  // namespace nlohmann
11577
11578
// #include <nlohmann/detail/iterators/iter_impl.hpp>
11579
11580
11581
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11582
#include <type_traits> // conditional, is_const, remove_const
11583
11584
// #include <nlohmann/detail/exceptions.hpp>
11585
11586
// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11587
11588
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11589
11590
// #include <nlohmann/detail/macro_scope.hpp>
11591
11592
// #include <nlohmann/detail/meta/cpp_future.hpp>
11593
11594
// #include <nlohmann/detail/meta/type_traits.hpp>
11595
11596
// #include <nlohmann/detail/value_t.hpp>
11597
11598
11599
namespace nlohmann
11600
{
11601
namespace detail
11602
{
11603
// forward declare, to be able to friend it later on
11604
template<typename IteratorType> class iteration_proxy;
11605
template<typename IteratorType> class iteration_proxy_value;
11606
11607
/*!
11608
@brief a template for a bidirectional iterator for the @ref basic_json class
11609
This class implements a both iterators (iterator and const_iterator) for the
11610
@ref basic_json class.
11611
@note An iterator is called *initialized* when a pointer to a JSON value has
11612
      been set (e.g., by a constructor or a copy assignment). If the iterator is
11613
      default-constructed, it is *uninitialized* and most methods are undefined.
11614
      **The library uses assertions to detect calls on uninitialized iterators.**
11615
@requirement The class satisfies the following concept requirements:
11616
-
11617
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
11618
  The iterator that can be moved can be moved in both directions (i.e.
11619
  incremented and decremented).
11620
@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
11621
       iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
11622
*/
11623
template<typename BasicJsonType>
11624
class iter_impl
11625
{
11626
    /// the iterator with BasicJsonType of different const-ness
11627
    using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11628
    /// allow basic_json to access private members
11629
    friend other_iter_impl;
11630
    friend BasicJsonType;
11631
    friend iteration_proxy<iter_impl>;
11632
    friend iteration_proxy_value<iter_impl>;
11633
11634
    using object_t = typename BasicJsonType::object_t;
11635
    using array_t = typename BasicJsonType::array_t;
11636
    // make sure BasicJsonType is basic_json or const basic_json
11637
    static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11638
                  "iter_impl only accepts (const) basic_json");
11639
11640
  public:
11641
11642
    /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
11643
    /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
11644
    /// A user-defined iterator should provide publicly accessible typedefs named
11645
    /// iterator_category, value_type, difference_type, pointer, and reference.
11646
    /// Note that value_type is required to be non-const, even for constant iterators.
11647
    using iterator_category = std::bidirectional_iterator_tag;
11648
11649
    /// the type of the values when the iterator is dereferenced
11650
    using value_type = typename BasicJsonType::value_type;
11651
    /// a type to represent differences between iterators
11652
    using difference_type = typename BasicJsonType::difference_type;
11653
    /// defines a pointer to the type iterated over (value_type)
11654
    using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11655
          typename BasicJsonType::const_pointer,
11656
          typename BasicJsonType::pointer>::type;
11657
    /// defines a reference to the type iterated over (value_type)
11658
    using reference =
11659
        typename std::conditional<std::is_const<BasicJsonType>::value,
11660
        typename BasicJsonType::const_reference,
11661
        typename BasicJsonType::reference>::type;
11662
11663
14.1M
    iter_impl() = default;
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::iter_impl()
Line
Count
Source
11663
14.1M
    iter_impl() = default;
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::iter_impl()
11664
    ~iter_impl() = default;
11665
    iter_impl(iter_impl&&) noexcept = default;
11666
    iter_impl& operator=(iter_impl&&) noexcept = default;
11667
11668
    /*!
11669
    @brief constructor for a given JSON instance
11670
    @param[in] object  pointer to a JSON object for this iterator
11671
    @pre object != nullptr
11672
    @post The iterator is initialized; i.e. `m_object != nullptr`.
11673
    */
11674
    explicit iter_impl(pointer object) noexcept : m_object(object)
11675
30.0M
    {
11676
30.0M
        JSON_ASSERT(m_object != nullptr);
11677
11678
0
        switch (m_object->m_type)
11679
30.0M
        {
11680
19.9M
            case value_t::object:
11681
19.9M
            {
11682
19.9M
                m_it.object_iterator = typename object_t::iterator();
11683
19.9M
                break;
11684
0
            }
11685
11686
916k
            case value_t::array:
11687
916k
            {
11688
916k
                m_it.array_iterator = typename array_t::iterator();
11689
916k
                break;
11690
0
            }
11691
11692
0
            case value_t::null:
11693
76
            case value_t::string:
11694
1.63k
            case value_t::boolean:
11695
21.4k
            case value_t::number_integer:
11696
9.17M
            case value_t::number_unsigned:
11697
9.21M
            case value_t::number_float:
11698
9.21M
            case value_t::binary:
11699
9.21M
            case value_t::discarded:
11700
9.21M
            default:
11701
9.21M
            {
11702
9.21M
                m_it.primitive_iterator = primitive_iterator_t();
11703
9.21M
                break;
11704
9.21M
            }
11705
30.0M
        }
11706
30.0M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*)
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const*)
Line
Count
Source
11675
30.0M
    {
11676
30.0M
        JSON_ASSERT(m_object != nullptr);
11677
11678
0
        switch (m_object->m_type)
11679
30.0M
        {
11680
19.9M
            case value_t::object:
11681
19.9M
            {
11682
19.9M
                m_it.object_iterator = typename object_t::iterator();
11683
19.9M
                break;
11684
0
            }
11685
11686
916k
            case value_t::array:
11687
916k
            {
11688
916k
                m_it.array_iterator = typename array_t::iterator();
11689
916k
                break;
11690
0
            }
11691
11692
0
            case value_t::null:
11693
76
            case value_t::string:
11694
1.63k
            case value_t::boolean:
11695
21.4k
            case value_t::number_integer:
11696
9.17M
            case value_t::number_unsigned:
11697
9.21M
            case value_t::number_float:
11698
9.21M
            case value_t::binary:
11699
9.21M
            case value_t::discarded:
11700
9.21M
            default:
11701
9.21M
            {
11702
9.21M
                m_it.primitive_iterator = primitive_iterator_t();
11703
9.21M
                break;
11704
9.21M
            }
11705
30.0M
        }
11706
30.0M
    }
11707
11708
    /*!
11709
    @note The conventional copy constructor and copy assignment are implicitly
11710
          defined. Combined with the following converting constructor and
11711
          assignment, they support: (1) copy from iterator to iterator, (2)
11712
          copy from const iterator to const iterator, and (3) conversion from
11713
          iterator to const iterator. However conversion from const iterator
11714
          to iterator is not defined.
11715
    */
11716
11717
    /*!
11718
    @brief const copy constructor
11719
    @param[in] other const iterator to copy from
11720
    @note This copy constructor had to be defined explicitly to circumvent a bug
11721
          occurring on msvc v19.0 compiler (VS 2015) debug build. For more
11722
          information refer to: https://github.com/nlohmann/json/issues/1608
11723
    */
11724
    iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11725
        : m_object(other.m_object), m_it(other.m_it)
11726
827k
    {}
11727
11728
    /*!
11729
    @brief converting assignment
11730
    @param[in] other const iterator to copy from
11731
    @return const/non-const iterator
11732
    @note It is not checked whether @a other is initialized.
11733
    */
11734
    iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11735
    {
11736
        if (&other != this)
11737
        {
11738
            m_object = other.m_object;
11739
            m_it = other.m_it;
11740
        }
11741
        return *this;
11742
    }
11743
11744
    /*!
11745
    @brief converting constructor
11746
    @param[in] other  non-const iterator to copy from
11747
    @note It is not checked whether @a other is initialized.
11748
    */
11749
    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11750
        : m_object(other.m_object), m_it(other.m_it)
11751
0
    {}
11752
11753
    /*!
11754
    @brief converting assignment
11755
    @param[in] other  non-const iterator to copy from
11756
    @return const/non-const iterator
11757
    @note It is not checked whether @a other is initialized.
11758
    */
11759
    iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11760
    {
11761
        m_object = other.m_object;
11762
        m_it = other.m_it;
11763
        return *this;
11764
    }
11765
11766
  JSON_PRIVATE_UNLESS_TESTED:
11767
    /*!
11768
    @brief set the iterator to the first value
11769
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11770
    */
11771
    void set_begin() noexcept
11772
438k
    {
11773
438k
        JSON_ASSERT(m_object != nullptr);
11774
11775
0
        switch (m_object->m_type)
11776
438k
        {
11777
386k
            case value_t::object:
11778
386k
            {
11779
386k
                m_it.object_iterator = m_object->m_value.object->begin();
11780
386k
                break;
11781
0
            }
11782
11783
51.7k
            case value_t::array:
11784
51.7k
            {
11785
51.7k
                m_it.array_iterator = m_object->m_value.array->begin();
11786
51.7k
                break;
11787
0
            }
11788
11789
0
            case value_t::null:
11790
0
            {
11791
                // set to end so begin()==end() is true: null is empty
11792
0
                m_it.primitive_iterator.set_end();
11793
0
                break;
11794
0
            }
11795
11796
0
            case value_t::string:
11797
0
            case value_t::boolean:
11798
0
            case value_t::number_integer:
11799
0
            case value_t::number_unsigned:
11800
0
            case value_t::number_float:
11801
0
            case value_t::binary:
11802
0
            case value_t::discarded:
11803
0
            default:
11804
0
            {
11805
0
                m_it.primitive_iterator.set_begin();
11806
0
                break;
11807
0
            }
11808
438k
        }
11809
438k
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::set_begin()
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::set_begin()
Line
Count
Source
11772
438k
    {
11773
438k
        JSON_ASSERT(m_object != nullptr);
11774
11775
0
        switch (m_object->m_type)
11776
438k
        {
11777
386k
            case value_t::object:
11778
386k
            {
11779
386k
                m_it.object_iterator = m_object->m_value.object->begin();
11780
386k
                break;
11781
0
            }
11782
11783
51.7k
            case value_t::array:
11784
51.7k
            {
11785
51.7k
                m_it.array_iterator = m_object->m_value.array->begin();
11786
51.7k
                break;
11787
0
            }
11788
11789
0
            case value_t::null:
11790
0
            {
11791
                // set to end so begin()==end() is true: null is empty
11792
0
                m_it.primitive_iterator.set_end();
11793
0
                break;
11794
0
            }
11795
11796
0
            case value_t::string:
11797
0
            case value_t::boolean:
11798
0
            case value_t::number_integer:
11799
0
            case value_t::number_unsigned:
11800
0
            case value_t::number_float:
11801
0
            case value_t::binary:
11802
0
            case value_t::discarded:
11803
0
            default:
11804
0
            {
11805
0
                m_it.primitive_iterator.set_begin();
11806
0
                break;
11807
0
            }
11808
438k
        }
11809
438k
    }
11810
11811
    /*!
11812
    @brief set the iterator past the last value
11813
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11814
    */
11815
    void set_end() noexcept
11816
29.6M
    {
11817
29.6M
        JSON_ASSERT(m_object != nullptr);
11818
11819
0
        switch (m_object->m_type)
11820
29.6M
        {
11821
19.5M
            case value_t::object:
11822
19.5M
            {
11823
19.5M
                m_it.object_iterator = m_object->m_value.object->end();
11824
19.5M
                break;
11825
0
            }
11826
11827
864k
            case value_t::array:
11828
864k
            {
11829
864k
                m_it.array_iterator = m_object->m_value.array->end();
11830
864k
                break;
11831
0
            }
11832
11833
0
            case value_t::null:
11834
76
            case value_t::string:
11835
1.63k
            case value_t::boolean:
11836
21.4k
            case value_t::number_integer:
11837
9.17M
            case value_t::number_unsigned:
11838
9.21M
            case value_t::number_float:
11839
9.21M
            case value_t::binary:
11840
9.21M
            case value_t::discarded:
11841
9.21M
            default:
11842
9.21M
            {
11843
9.21M
                m_it.primitive_iterator.set_end();
11844
9.21M
                break;
11845
9.21M
            }
11846
29.6M
        }
11847
29.6M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::set_end()
Line
Count
Source
11816
29.6M
    {
11817
29.6M
        JSON_ASSERT(m_object != nullptr);
11818
11819
0
        switch (m_object->m_type)
11820
29.6M
        {
11821
19.5M
            case value_t::object:
11822
19.5M
            {
11823
19.5M
                m_it.object_iterator = m_object->m_value.object->end();
11824
19.5M
                break;
11825
0
            }
11826
11827
864k
            case value_t::array:
11828
864k
            {
11829
864k
                m_it.array_iterator = m_object->m_value.array->end();
11830
864k
                break;
11831
0
            }
11832
11833
0
            case value_t::null:
11834
76
            case value_t::string:
11835
1.63k
            case value_t::boolean:
11836
21.4k
            case value_t::number_integer:
11837
9.17M
            case value_t::number_unsigned:
11838
9.21M
            case value_t::number_float:
11839
9.21M
            case value_t::binary:
11840
9.21M
            case value_t::discarded:
11841
9.21M
            default:
11842
9.21M
            {
11843
9.21M
                m_it.primitive_iterator.set_end();
11844
9.21M
                break;
11845
9.21M
            }
11846
29.6M
        }
11847
29.6M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::set_end()
11848
11849
  public:
11850
    /*!
11851
    @brief return a reference to the value pointed to by the iterator
11852
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11853
    */
11854
    reference operator*() const
11855
4.67M
    {
11856
4.67M
        JSON_ASSERT(m_object != nullptr);
11857
11858
0
        switch (m_object->m_type)
11859
4.67M
        {
11860
273k
            case value_t::object:
11861
273k
            {
11862
273k
                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11863
0
                return m_it.object_iterator->second;
11864
0
            }
11865
11866
4.40M
            case value_t::array:
11867
4.40M
            {
11868
4.40M
                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11869
0
                return *m_it.array_iterator;
11870
0
            }
11871
11872
0
            case value_t::null:
11873
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11874
11875
0
            case value_t::string:
11876
0
            case value_t::boolean:
11877
0
            case value_t::number_integer:
11878
0
            case value_t::number_unsigned:
11879
0
            case value_t::number_float:
11880
0
            case value_t::binary:
11881
0
            case value_t::discarded:
11882
0
            default:
11883
0
            {
11884
0
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11885
0
                {
11886
0
                    return *m_object;
11887
0
                }
11888
11889
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11890
0
            }
11891
4.67M
        }
11892
4.67M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::operator*() const
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::operator*() const
Line
Count
Source
11855
4.67M
    {
11856
4.67M
        JSON_ASSERT(m_object != nullptr);
11857
11858
0
        switch (m_object->m_type)
11859
4.67M
        {
11860
273k
            case value_t::object:
11861
273k
            {
11862
273k
                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11863
0
                return m_it.object_iterator->second;
11864
0
            }
11865
11866
4.40M
            case value_t::array:
11867
4.40M
            {
11868
4.40M
                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11869
0
                return *m_it.array_iterator;
11870
0
            }
11871
11872
0
            case value_t::null:
11873
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11874
11875
0
            case value_t::string:
11876
0
            case value_t::boolean:
11877
0
            case value_t::number_integer:
11878
0
            case value_t::number_unsigned:
11879
0
            case value_t::number_float:
11880
0
            case value_t::binary:
11881
0
            case value_t::discarded:
11882
0
            default:
11883
0
            {
11884
0
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11885
0
                {
11886
0
                    return *m_object;
11887
0
                }
11888
11889
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11890
0
            }
11891
4.67M
        }
11892
4.67M
    }
11893
11894
    /*!
11895
    @brief dereference the iterator
11896
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11897
    */
11898
    pointer operator->() const
11899
0
    {
11900
0
        JSON_ASSERT(m_object != nullptr);
11901
11902
0
        switch (m_object->m_type)
11903
0
        {
11904
0
            case value_t::object:
11905
0
            {
11906
0
                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11907
0
                return &(m_it.object_iterator->second);
11908
0
            }
11909
11910
0
            case value_t::array:
11911
0
            {
11912
0
                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11913
0
                return &*m_it.array_iterator;
11914
0
            }
11915
11916
0
            case value_t::null:
11917
0
            case value_t::string:
11918
0
            case value_t::boolean:
11919
0
            case value_t::number_integer:
11920
0
            case value_t::number_unsigned:
11921
0
            case value_t::number_float:
11922
0
            case value_t::binary:
11923
0
            case value_t::discarded:
11924
0
            default:
11925
0
            {
11926
0
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11927
0
                {
11928
0
                    return m_object;
11929
0
                }
11930
11931
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11932
0
            }
11933
0
        }
11934
0
    }
11935
11936
    /*!
11937
    @brief post-increment (it++)
11938
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11939
    */
11940
    iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11941
827k
    {
11942
827k
        auto result = *this;
11943
827k
        ++(*this);
11944
827k
        return result;
11945
827k
    }
11946
11947
    /*!
11948
    @brief pre-increment (++it)
11949
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11950
    */
11951
    iter_impl& operator++()
11952
4.50M
    {
11953
4.50M
        JSON_ASSERT(m_object != nullptr);
11954
11955
0
        switch (m_object->m_type)
11956
4.50M
        {
11957
104k
            case value_t::object:
11958
104k
            {
11959
104k
                std::advance(m_it.object_iterator, 1);
11960
104k
                break;
11961
0
            }
11962
11963
4.40M
            case value_t::array:
11964
4.40M
            {
11965
4.40M
                std::advance(m_it.array_iterator, 1);
11966
4.40M
                break;
11967
0
            }
11968
11969
0
            case value_t::null:
11970
0
            case value_t::string:
11971
0
            case value_t::boolean:
11972
0
            case value_t::number_integer:
11973
0
            case value_t::number_unsigned:
11974
0
            case value_t::number_float:
11975
0
            case value_t::binary:
11976
0
            case value_t::discarded:
11977
0
            default:
11978
0
            {
11979
0
                ++m_it.primitive_iterator;
11980
0
                break;
11981
0
            }
11982
4.50M
        }
11983
11984
4.50M
        return *this;
11985
4.50M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::operator++()
Line
Count
Source
11952
4.50M
    {
11953
4.50M
        JSON_ASSERT(m_object != nullptr);
11954
11955
0
        switch (m_object->m_type)
11956
4.50M
        {
11957
104k
            case value_t::object:
11958
104k
            {
11959
104k
                std::advance(m_it.object_iterator, 1);
11960
104k
                break;
11961
0
            }
11962
11963
4.40M
            case value_t::array:
11964
4.40M
            {
11965
4.40M
                std::advance(m_it.array_iterator, 1);
11966
4.40M
                break;
11967
0
            }
11968
11969
0
            case value_t::null:
11970
0
            case value_t::string:
11971
0
            case value_t::boolean:
11972
0
            case value_t::number_integer:
11973
0
            case value_t::number_unsigned:
11974
0
            case value_t::number_float:
11975
0
            case value_t::binary:
11976
0
            case value_t::discarded:
11977
0
            default:
11978
0
            {
11979
0
                ++m_it.primitive_iterator;
11980
0
                break;
11981
0
            }
11982
4.50M
        }
11983
11984
4.50M
        return *this;
11985
4.50M
    }
11986
11987
    /*!
11988
    @brief post-decrement (it--)
11989
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11990
    */
11991
    iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11992
    {
11993
        auto result = *this;
11994
        --(*this);
11995
        return result;
11996
    }
11997
11998
    /*!
11999
    @brief pre-decrement (--it)
12000
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12001
    */
12002
    iter_impl& operator--()
12003
    {
12004
        JSON_ASSERT(m_object != nullptr);
12005
12006
        switch (m_object->m_type)
12007
        {
12008
            case value_t::object:
12009
            {
12010
                std::advance(m_it.object_iterator, -1);
12011
                break;
12012
            }
12013
12014
            case value_t::array:
12015
            {
12016
                std::advance(m_it.array_iterator, -1);
12017
                break;
12018
            }
12019
12020
            case value_t::null:
12021
            case value_t::string:
12022
            case value_t::boolean:
12023
            case value_t::number_integer:
12024
            case value_t::number_unsigned:
12025
            case value_t::number_float:
12026
            case value_t::binary:
12027
            case value_t::discarded:
12028
            default:
12029
            {
12030
                --m_it.primitive_iterator;
12031
                break;
12032
            }
12033
        }
12034
12035
        return *this;
12036
    }
12037
12038
    /*!
12039
    @brief comparison: equal
12040
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12041
    */
12042
    template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12043
    bool operator==(const IterImpl& other) const
12044
19.1M
    {
12045
        // if objects are not the same, the comparison is undefined
12046
19.1M
        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12047
0
        {
12048
0
            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12049
0
        }
12050
12051
19.1M
        JSON_ASSERT(m_object != nullptr);
12052
12053
0
        switch (m_object->m_type)
12054
19.1M
        {
12055
10.0M
            case value_t::object:
12056
10.0M
                return (m_it.object_iterator == other.m_it.object_iterator);
12057
12058
4.45M
            case value_t::array:
12059
4.45M
                return (m_it.array_iterator == other.m_it.array_iterator);
12060
12061
0
            case value_t::null:
12062
38
            case value_t::string:
12063
818
            case value_t::boolean:
12064
10.7k
            case value_t::number_integer:
12065
4.58M
            case value_t::number_unsigned:
12066
4.60M
            case value_t::number_float:
12067
4.60M
            case value_t::binary:
12068
4.60M
            case value_t::discarded:
12069
4.60M
            default:
12070
4.60M
                return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12071
19.1M
        }
12072
19.1M
    }
bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>, (decltype(nullptr))0>(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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const> const&) const
Line
Count
Source
12044
19.1M
    {
12045
        // if objects are not the same, the comparison is undefined
12046
19.1M
        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12047
0
        {
12048
0
            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12049
0
        }
12050
12051
19.1M
        JSON_ASSERT(m_object != nullptr);
12052
12053
0
        switch (m_object->m_type)
12054
19.1M
        {
12055
10.0M
            case value_t::object:
12056
10.0M
                return (m_it.object_iterator == other.m_it.object_iterator);
12057
12058
4.45M
            case value_t::array:
12059
4.45M
                return (m_it.array_iterator == other.m_it.array_iterator);
12060
12061
0
            case value_t::null:
12062
38
            case value_t::string:
12063
818
            case value_t::boolean:
12064
10.7k
            case value_t::number_integer:
12065
4.58M
            case value_t::number_unsigned:
12066
4.60M
            case value_t::number_float:
12067
4.60M
            case value_t::binary:
12068
4.60M
            case value_t::discarded:
12069
4.60M
            default:
12070
4.60M
                return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12071
19.1M
        }
12072
19.1M
    }
Unexecuted instantiation: bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >, (decltype(nullptr))0>(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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > const&) const
12073
12074
    /*!
12075
    @brief comparison: not equal
12076
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12077
    */
12078
    template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12079
    bool operator!=(const IterImpl& other) const
12080
19.1M
    {
12081
19.1M
        return !operator==(other);
12082
19.1M
    }
bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>, (decltype(nullptr))0>(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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const> const&) const
Line
Count
Source
12080
19.1M
    {
12081
19.1M
        return !operator==(other);
12082
19.1M
    }
Unexecuted instantiation: bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >, (decltype(nullptr))0>(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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > const&) const
12083
12084
    /*!
12085
    @brief comparison: smaller
12086
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12087
    */
12088
    bool operator<(const iter_impl& other) const
12089
    {
12090
        // if objects are not the same, the comparison is undefined
12091
        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12092
        {
12093
            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12094
        }
12095
12096
        JSON_ASSERT(m_object != nullptr);
12097
12098
        switch (m_object->m_type)
12099
        {
12100
            case value_t::object:
12101
                JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12102
12103
            case value_t::array:
12104
                return (m_it.array_iterator < other.m_it.array_iterator);
12105
12106
            case value_t::null:
12107
            case value_t::string:
12108
            case value_t::boolean:
12109
            case value_t::number_integer:
12110
            case value_t::number_unsigned:
12111
            case value_t::number_float:
12112
            case value_t::binary:
12113
            case value_t::discarded:
12114
            default:
12115
                return (m_it.primitive_iterator < other.m_it.primitive_iterator);
12116
        }
12117
    }
12118
12119
    /*!
12120
    @brief comparison: less than or equal
12121
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12122
    */
12123
    bool operator<=(const iter_impl& other) const
12124
    {
12125
        return !other.operator < (*this);
12126
    }
12127
12128
    /*!
12129
    @brief comparison: greater than
12130
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12131
    */
12132
    bool operator>(const iter_impl& other) const
12133
    {
12134
        return !operator<=(other);
12135
    }
12136
12137
    /*!
12138
    @brief comparison: greater than or equal
12139
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12140
    */
12141
    bool operator>=(const iter_impl& other) const
12142
    {
12143
        return !operator<(other);
12144
    }
12145
12146
    /*!
12147
    @brief add to iterator
12148
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12149
    */
12150
    iter_impl& operator+=(difference_type i)
12151
    {
12152
        JSON_ASSERT(m_object != nullptr);
12153
12154
        switch (m_object->m_type)
12155
        {
12156
            case value_t::object:
12157
                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12158
12159
            case value_t::array:
12160
            {
12161
                std::advance(m_it.array_iterator, i);
12162
                break;
12163
            }
12164
12165
            case value_t::null:
12166
            case value_t::string:
12167
            case value_t::boolean:
12168
            case value_t::number_integer:
12169
            case value_t::number_unsigned:
12170
            case value_t::number_float:
12171
            case value_t::binary:
12172
            case value_t::discarded:
12173
            default:
12174
            {
12175
                m_it.primitive_iterator += i;
12176
                break;
12177
            }
12178
        }
12179
12180
        return *this;
12181
    }
12182
12183
    /*!
12184
    @brief subtract from iterator
12185
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12186
    */
12187
    iter_impl& operator-=(difference_type i)
12188
    {
12189
        return operator+=(-i);
12190
    }
12191
12192
    /*!
12193
    @brief add to iterator
12194
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12195
    */
12196
    iter_impl operator+(difference_type i) const
12197
    {
12198
        auto result = *this;
12199
        result += i;
12200
        return result;
12201
    }
12202
12203
    /*!
12204
    @brief addition of distance and iterator
12205
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12206
    */
12207
    friend iter_impl operator+(difference_type i, const iter_impl& it)
12208
    {
12209
        auto result = it;
12210
        result += i;
12211
        return result;
12212
    }
12213
12214
    /*!
12215
    @brief subtract from iterator
12216
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12217
    */
12218
    iter_impl operator-(difference_type i) const
12219
    {
12220
        auto result = *this;
12221
        result -= i;
12222
        return result;
12223
    }
12224
12225
    /*!
12226
    @brief return difference
12227
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12228
    */
12229
    difference_type operator-(const iter_impl& other) const
12230
    {
12231
        JSON_ASSERT(m_object != nullptr);
12232
12233
        switch (m_object->m_type)
12234
        {
12235
            case value_t::object:
12236
                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12237
12238
            case value_t::array:
12239
                return m_it.array_iterator - other.m_it.array_iterator;
12240
12241
            case value_t::null:
12242
            case value_t::string:
12243
            case value_t::boolean:
12244
            case value_t::number_integer:
12245
            case value_t::number_unsigned:
12246
            case value_t::number_float:
12247
            case value_t::binary:
12248
            case value_t::discarded:
12249
            default:
12250
                return m_it.primitive_iterator - other.m_it.primitive_iterator;
12251
        }
12252
    }
12253
12254
    /*!
12255
    @brief access to successor
12256
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12257
    */
12258
    reference operator[](difference_type n) const
12259
    {
12260
        JSON_ASSERT(m_object != nullptr);
12261
12262
        switch (m_object->m_type)
12263
        {
12264
            case value_t::object:
12265
                JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12266
12267
            case value_t::array:
12268
                return *std::next(m_it.array_iterator, n);
12269
12270
            case value_t::null:
12271
                JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12272
12273
            case value_t::string:
12274
            case value_t::boolean:
12275
            case value_t::number_integer:
12276
            case value_t::number_unsigned:
12277
            case value_t::number_float:
12278
            case value_t::binary:
12279
            case value_t::discarded:
12280
            default:
12281
            {
12282
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12283
                {
12284
                    return *m_object;
12285
                }
12286
12287
                JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12288
            }
12289
        }
12290
    }
12291
12292
    /*!
12293
    @brief return the key of an object iterator
12294
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12295
    */
12296
    const typename object_t::key_type& key() const
12297
103k
    {
12298
103k
        JSON_ASSERT(m_object != nullptr);
12299
12300
103k
        if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12301
103k
        {
12302
103k
            return m_it.object_iterator->first;
12303
103k
        }
12304
12305
103k
        JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12306
103k
    }
12307
12308
    /*!
12309
    @brief return the value of an iterator
12310
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
12311
    */
12312
    reference value() const
12313
1.08M
    {
12314
1.08M
        return operator*();
12315
1.08M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::value() const
Line
Count
Source
12313
1.08M
    {
12314
1.08M
        return operator*();
12315
1.08M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::value() const
12316
12317
  JSON_PRIVATE_UNLESS_TESTED:
12318
    /// associated JSON instance
12319
    pointer m_object = nullptr;
12320
    /// the actual iterator of the associated instance
12321
    internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
12322
};
12323
} // namespace detail
12324
} // namespace nlohmann
12325
12326
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12327
12328
// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12329
12330
12331
#include <cstddef> // ptrdiff_t
12332
#include <iterator> // reverse_iterator
12333
#include <utility> // declval
12334
12335
namespace nlohmann
12336
{
12337
namespace detail
12338
{
12339
//////////////////////
12340
// reverse_iterator //
12341
//////////////////////
12342
12343
/*!
12344
@brief a template for a reverse iterator class
12345
12346
@tparam Base the base iterator type to reverse. Valid types are @ref
12347
iterator (to create @ref reverse_iterator) and @ref const_iterator (to
12348
create @ref const_reverse_iterator).
12349
12350
@requirement The class satisfies the following concept requirements:
12351
-
12352
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
12353
  The iterator that can be moved can be moved in both directions (i.e.
12354
  incremented and decremented).
12355
- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
12356
  It is possible to write to the pointed-to element (only if @a Base is
12357
  @ref iterator).
12358
12359
@since version 1.0.0
12360
*/
12361
template<typename Base>
12362
class json_reverse_iterator : public std::reverse_iterator<Base>
12363
{
12364
  public:
12365
    using difference_type = std::ptrdiff_t;
12366
    /// shortcut to the reverse iterator adapter
12367
    using base_iterator = std::reverse_iterator<Base>;
12368
    /// the reference type for the pointed-to element
12369
    using reference = typename Base::reference;
12370
12371
    /// create reverse iterator from iterator
12372
    explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12373
        : base_iterator(it) {}
12374
12375
    /// create reverse iterator from base class
12376
    explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12377
12378
    /// post-increment (it++)
12379
    json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12380
    {
12381
        return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12382
    }
12383
12384
    /// pre-increment (++it)
12385
    json_reverse_iterator& operator++()
12386
    {
12387
        return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12388
    }
12389
12390
    /// post-decrement (it--)
12391
    json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12392
    {
12393
        return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12394
    }
12395
12396
    /// pre-decrement (--it)
12397
    json_reverse_iterator& operator--()
12398
    {
12399
        return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12400
    }
12401
12402
    /// add to iterator
12403
    json_reverse_iterator& operator+=(difference_type i)
12404
    {
12405
        return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12406
    }
12407
12408
    /// add to iterator
12409
    json_reverse_iterator operator+(difference_type i) const
12410
    {
12411
        return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12412
    }
12413
12414
    /// subtract from iterator
12415
    json_reverse_iterator operator-(difference_type i) const
12416
    {
12417
        return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12418
    }
12419
12420
    /// return difference
12421
    difference_type operator-(const json_reverse_iterator& other) const
12422
    {
12423
        return base_iterator(*this) - base_iterator(other);
12424
    }
12425
12426
    /// access to successor
12427
    reference operator[](difference_type n) const
12428
    {
12429
        return *(this->operator+(n));
12430
    }
12431
12432
    /// return the key of an object iterator
12433
    auto key() const -> decltype(std::declval<Base>().key())
12434
    {
12435
        auto it = --this->base();
12436
        return it.key();
12437
    }
12438
12439
    /// return the value of an iterator
12440
    reference value() const
12441
    {
12442
        auto it = --this->base();
12443
        return it.operator * ();
12444
    }
12445
};
12446
}  // namespace detail
12447
}  // namespace nlohmann
12448
12449
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12450
12451
// #include <nlohmann/detail/json_pointer.hpp>
12452
12453
12454
#include <algorithm> // all_of
12455
#include <cctype> // isdigit
12456
#include <limits> // max
12457
#include <numeric> // accumulate
12458
#include <string> // string
12459
#include <utility> // move
12460
#include <vector> // vector
12461
12462
// #include <nlohmann/detail/exceptions.hpp>
12463
12464
// #include <nlohmann/detail/macro_scope.hpp>
12465
12466
// #include <nlohmann/detail/string_escape.hpp>
12467
12468
// #include <nlohmann/detail/value_t.hpp>
12469
12470
12471
namespace nlohmann
12472
{
12473
template<typename BasicJsonType>
12474
class json_pointer
12475
{
12476
    // allow basic_json to access private members
12477
    NLOHMANN_BASIC_JSON_TPL_DECLARATION
12478
    friend class basic_json;
12479
12480
  public:
12481
    /*!
12482
    @brief create JSON pointer
12483
12484
    Create a JSON pointer according to the syntax described in
12485
    [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
12486
12487
    @param[in] s  string representing the JSON pointer; if omitted, the empty
12488
                  string is assumed which references the whole JSON value
12489
12490
    @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
12491
                           not begin with a slash (`/`); see example below
12492
12493
    @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
12494
    not followed by `0` (representing `~`) or `1` (representing `/`); see
12495
    example below
12496
12497
    @liveexample{The example shows the construction several valid JSON pointers
12498
    as well as the exceptional behavior.,json_pointer}
12499
12500
    @since version 2.0.0
12501
    */
12502
    explicit json_pointer(const std::string& s = "")
12503
        : reference_tokens(split(s))
12504
    {}
12505
12506
    /*!
12507
    @brief return a string representation of the JSON pointer
12508
12509
    @invariant For each JSON pointer `ptr`, it holds:
12510
    @code {.cpp}
12511
    ptr == json_pointer(ptr.to_string());
12512
    @endcode
12513
12514
    @return a string representation of the JSON pointer
12515
12516
    @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
12517
12518
    @since version 2.0.0
12519
    */
12520
    std::string to_string() const
12521
    {
12522
        return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12523
                               std::string{},
12524
                               [](const std::string & a, const std::string & b)
12525
        {
12526
            return a + "/" + detail::escape(b);
12527
        });
12528
    }
12529
12530
    /// @copydoc to_string()
12531
    operator std::string() const
12532
    {
12533
        return to_string();
12534
    }
12535
12536
    /*!
12537
    @brief append another JSON pointer at the end of this JSON pointer
12538
12539
    @param[in] ptr  JSON pointer to append
12540
    @return JSON pointer with @a ptr appended
12541
12542
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12543
12544
    @complexity Linear in the length of @a ptr.
12545
12546
    @sa see @ref operator/=(std::string) to append a reference token
12547
    @sa see @ref operator/=(std::size_t) to append an array index
12548
    @sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
12549
12550
    @since version 3.6.0
12551
    */
12552
    json_pointer& operator/=(const json_pointer& ptr)
12553
    {
12554
        reference_tokens.insert(reference_tokens.end(),
12555
                                ptr.reference_tokens.begin(),
12556
                                ptr.reference_tokens.end());
12557
        return *this;
12558
    }
12559
12560
    /*!
12561
    @brief append an unescaped reference token at the end of this JSON pointer
12562
12563
    @param[in] token  reference token to append
12564
    @return JSON pointer with @a token appended without escaping @a token
12565
12566
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12567
12568
    @complexity Amortized constant.
12569
12570
    @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12571
    @sa see @ref operator/=(std::size_t) to append an array index
12572
    @sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator
12573
12574
    @since version 3.6.0
12575
    */
12576
    json_pointer& operator/=(std::string token)
12577
    {
12578
        push_back(std::move(token));
12579
        return *this;
12580
    }
12581
12582
    /*!
12583
    @brief append an array index at the end of this JSON pointer
12584
12585
    @param[in] array_idx  array index to append
12586
    @return JSON pointer with @a array_idx appended
12587
12588
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12589
12590
    @complexity Amortized constant.
12591
12592
    @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12593
    @sa see @ref operator/=(std::string) to append a reference token
12594
    @sa see @ref operator/(const json_pointer&, std::string) for a binary operator
12595
12596
    @since version 3.6.0
12597
    */
12598
    json_pointer& operator/=(std::size_t array_idx)
12599
    {
12600
        return *this /= std::to_string(array_idx);
12601
    }
12602
12603
    /*!
12604
    @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
12605
12606
    @param[in] lhs  JSON pointer
12607
    @param[in] rhs  JSON pointer
12608
    @return a new JSON pointer with @a rhs appended to @a lhs
12609
12610
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12611
12612
    @complexity Linear in the length of @a lhs and @a rhs.
12613
12614
    @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12615
12616
    @since version 3.6.0
12617
    */
12618
    friend json_pointer operator/(const json_pointer& lhs,
12619
                                  const json_pointer& rhs)
12620
    {
12621
        return json_pointer(lhs) /= rhs;
12622
    }
12623
12624
    /*!
12625
    @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
12626
12627
    @param[in] ptr  JSON pointer
12628
    @param[in] token  reference token
12629
    @return a new JSON pointer with unescaped @a token appended to @a ptr
12630
12631
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12632
12633
    @complexity Linear in the length of @a ptr.
12634
12635
    @sa see @ref operator/=(std::string) to append a reference token
12636
12637
    @since version 3.6.0
12638
    */
12639
    friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12640
    {
12641
        return json_pointer(ptr) /= std::move(token);
12642
    }
12643
12644
    /*!
12645
    @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
12646
12647
    @param[in] ptr  JSON pointer
12648
    @param[in] array_idx  array index
12649
    @return a new JSON pointer with @a array_idx appended to @a ptr
12650
12651
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12652
12653
    @complexity Linear in the length of @a ptr.
12654
12655
    @sa see @ref operator/=(std::size_t) to append an array index
12656
12657
    @since version 3.6.0
12658
    */
12659
    friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12660
    {
12661
        return json_pointer(ptr) /= array_idx;
12662
    }
12663
12664
    /*!
12665
    @brief returns the parent of this JSON pointer
12666
12667
    @return parent of this JSON pointer; in case this JSON pointer is the root,
12668
            the root itself is returned
12669
12670
    @complexity Linear in the length of the JSON pointer.
12671
12672
    @liveexample{The example shows the result of `parent_pointer` for different
12673
    JSON Pointers.,json_pointer__parent_pointer}
12674
12675
    @since version 3.6.0
12676
    */
12677
    json_pointer parent_pointer() const
12678
    {
12679
        if (empty())
12680
        {
12681
            return *this;
12682
        }
12683
12684
        json_pointer res = *this;
12685
        res.pop_back();
12686
        return res;
12687
    }
12688
12689
    /*!
12690
    @brief remove last reference token
12691
12692
    @pre not `empty()`
12693
12694
    @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
12695
12696
    @complexity Constant.
12697
12698
    @throw out_of_range.405 if JSON pointer has no parent
12699
12700
    @since version 3.6.0
12701
    */
12702
    void pop_back()
12703
    {
12704
        if (JSON_HEDLEY_UNLIKELY(empty()))
12705
        {
12706
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12707
        }
12708
12709
        reference_tokens.pop_back();
12710
    }
12711
12712
    /*!
12713
    @brief return last reference token
12714
12715
    @pre not `empty()`
12716
    @return last reference token
12717
12718
    @liveexample{The example shows the usage of `back`.,json_pointer__back}
12719
12720
    @complexity Constant.
12721
12722
    @throw out_of_range.405 if JSON pointer has no parent
12723
12724
    @since version 3.6.0
12725
    */
12726
    const std::string& back() const
12727
    {
12728
        if (JSON_HEDLEY_UNLIKELY(empty()))
12729
        {
12730
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12731
        }
12732
12733
        return reference_tokens.back();
12734
    }
12735
12736
    /*!
12737
    @brief append an unescaped token at the end of the reference pointer
12738
12739
    @param[in] token  token to add
12740
12741
    @complexity Amortized constant.
12742
12743
    @liveexample{The example shows the result of `push_back` for different
12744
    JSON Pointers.,json_pointer__push_back}
12745
12746
    @since version 3.6.0
12747
    */
12748
    void push_back(const std::string& token)
12749
    {
12750
        reference_tokens.push_back(token);
12751
    }
12752
12753
    /// @copydoc push_back(const std::string&)
12754
    void push_back(std::string&& token)
12755
    {
12756
        reference_tokens.push_back(std::move(token));
12757
    }
12758
12759
    /*!
12760
    @brief return whether pointer points to the root document
12761
12762
    @return true iff the JSON pointer points to the root document
12763
12764
    @complexity Constant.
12765
12766
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
12767
12768
    @liveexample{The example shows the result of `empty` for different JSON
12769
    Pointers.,json_pointer__empty}
12770
12771
    @since version 3.6.0
12772
    */
12773
    bool empty() const noexcept
12774
    {
12775
        return reference_tokens.empty();
12776
    }
12777
12778
  private:
12779
    /*!
12780
    @param[in] s  reference token to be converted into an array index
12781
12782
    @return integer representation of @a s
12783
12784
    @throw parse_error.106  if an array index begins with '0'
12785
    @throw parse_error.109  if an array index begins not with a digit
12786
    @throw out_of_range.404 if string @a s could not be converted to an integer
12787
    @throw out_of_range.410 if an array index exceeds size_type
12788
    */
12789
    static typename BasicJsonType::size_type array_index(const std::string& s)
12790
    {
12791
        using size_type = typename BasicJsonType::size_type;
12792
12793
        // error condition (cf. RFC 6901, Sect. 4)
12794
        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12795
        {
12796
            JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12797
        }
12798
12799
        // error condition (cf. RFC 6901, Sect. 4)
12800
        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12801
        {
12802
            JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12803
        }
12804
12805
        std::size_t processed_chars = 0;
12806
        unsigned long long res = 0;  // NOLINT(runtime/int)
12807
        JSON_TRY
12808
        {
12809
            res = std::stoull(s, &processed_chars);
12810
        }
12811
        JSON_CATCH(std::out_of_range&)
12812
        {
12813
            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12814
        }
12815
12816
        // check if the string was completely read
12817
        if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12818
        {
12819
            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12820
        }
12821
12822
        // only triggered on special platforms (like 32bit), see also
12823
        // https://github.com/nlohmann/json/pull/2203
12824
        if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))  // NOLINT(runtime/int)
12825
        {
12826
            JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12827
        }
12828
12829
        return static_cast<size_type>(res);
12830
    }
12831
12832
  JSON_PRIVATE_UNLESS_TESTED:
12833
    json_pointer top() const
12834
    {
12835
        if (JSON_HEDLEY_UNLIKELY(empty()))
12836
        {
12837
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12838
        }
12839
12840
        json_pointer result = *this;
12841
        result.reference_tokens = {reference_tokens[0]};
12842
        return result;
12843
    }
12844
12845
  private:
12846
    /*!
12847
    @brief create and return a reference to the pointed to value
12848
12849
    @complexity Linear in the number of reference tokens.
12850
12851
    @throw parse_error.109 if array index is not a number
12852
    @throw type_error.313 if value cannot be unflattened
12853
    */
12854
    BasicJsonType& get_and_create(BasicJsonType& j) const
12855
    {
12856
        auto* result = &j;
12857
12858
        // in case no reference tokens exist, return a reference to the JSON value
12859
        // j which will be overwritten by a primitive value
12860
        for (const auto& reference_token : reference_tokens)
12861
        {
12862
            switch (result->type())
12863
            {
12864
                case detail::value_t::null:
12865
                {
12866
                    if (reference_token == "0")
12867
                    {
12868
                        // start a new array if reference token is 0
12869
                        result = &result->operator[](0);
12870
                    }
12871
                    else
12872
                    {
12873
                        // start a new object otherwise
12874
                        result = &result->operator[](reference_token);
12875
                    }
12876
                    break;
12877
                }
12878
12879
                case detail::value_t::object:
12880
                {
12881
                    // create an entry in the object
12882
                    result = &result->operator[](reference_token);
12883
                    break;
12884
                }
12885
12886
                case detail::value_t::array:
12887
                {
12888
                    // create an entry in the array
12889
                    result = &result->operator[](array_index(reference_token));
12890
                    break;
12891
                }
12892
12893
                /*
12894
                The following code is only reached if there exists a reference
12895
                token _and_ the current value is primitive. In this case, we have
12896
                an error situation, because primitive values may only occur as
12897
                single value; that is, with an empty list of reference tokens.
12898
                */
12899
                case detail::value_t::string:
12900
                case detail::value_t::boolean:
12901
                case detail::value_t::number_integer:
12902
                case detail::value_t::number_unsigned:
12903
                case detail::value_t::number_float:
12904
                case detail::value_t::binary:
12905
                case detail::value_t::discarded:
12906
                default:
12907
                    JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12908
            }
12909
        }
12910
12911
        return *result;
12912
    }
12913
12914
    /*!
12915
    @brief return a reference to the pointed to value
12916
12917
    @note This version does not throw if a value is not present, but tries to
12918
          create nested values instead. For instance, calling this function
12919
          with pointer `"/this/that"` on a null value is equivalent to calling
12920
          `operator[]("this").operator[]("that")` on that value, effectively
12921
          changing the null value to an object.
12922
12923
    @param[in] ptr  a JSON value
12924
12925
    @return reference to the JSON value pointed to by the JSON pointer
12926
12927
    @complexity Linear in the length of the JSON pointer.
12928
12929
    @throw parse_error.106   if an array index begins with '0'
12930
    @throw parse_error.109   if an array index was not a number
12931
    @throw out_of_range.404  if the JSON pointer can not be resolved
12932
    */
12933
    BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12934
    {
12935
        for (const auto& reference_token : reference_tokens)
12936
        {
12937
            // convert null values to arrays or objects before continuing
12938
            if (ptr->is_null())
12939
            {
12940
                // check if reference token is a number
12941
                const bool nums =
12942
                    std::all_of(reference_token.begin(), reference_token.end(),
12943
                                [](const unsigned char x)
12944
                {
12945
                    return std::isdigit(x);
12946
                });
12947
12948
                // change value to array for numbers or "-" or to object otherwise
12949
                *ptr = (nums || reference_token == "-")
12950
                       ? detail::value_t::array
12951
                       : detail::value_t::object;
12952
            }
12953
12954
            switch (ptr->type())
12955
            {
12956
                case detail::value_t::object:
12957
                {
12958
                    // use unchecked object access
12959
                    ptr = &ptr->operator[](reference_token);
12960
                    break;
12961
                }
12962
12963
                case detail::value_t::array:
12964
                {
12965
                    if (reference_token == "-")
12966
                    {
12967
                        // explicitly treat "-" as index beyond the end
12968
                        ptr = &ptr->operator[](ptr->m_value.array->size());
12969
                    }
12970
                    else
12971
                    {
12972
                        // convert array index to number; unchecked access
12973
                        ptr = &ptr->operator[](array_index(reference_token));
12974
                    }
12975
                    break;
12976
                }
12977
12978
                case detail::value_t::null:
12979
                case detail::value_t::string:
12980
                case detail::value_t::boolean:
12981
                case detail::value_t::number_integer:
12982
                case detail::value_t::number_unsigned:
12983
                case detail::value_t::number_float:
12984
                case detail::value_t::binary:
12985
                case detail::value_t::discarded:
12986
                default:
12987
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12988
            }
12989
        }
12990
12991
        return *ptr;
12992
    }
12993
12994
    /*!
12995
    @throw parse_error.106   if an array index begins with '0'
12996
    @throw parse_error.109   if an array index was not a number
12997
    @throw out_of_range.402  if the array index '-' is used
12998
    @throw out_of_range.404  if the JSON pointer can not be resolved
12999
    */
13000
    BasicJsonType& get_checked(BasicJsonType* ptr) const
13001
    {
13002
        for (const auto& reference_token : reference_tokens)
13003
        {
13004
            switch (ptr->type())
13005
            {
13006
                case detail::value_t::object:
13007
                {
13008
                    // note: at performs range check
13009
                    ptr = &ptr->at(reference_token);
13010
                    break;
13011
                }
13012
13013
                case detail::value_t::array:
13014
                {
13015
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13016
                    {
13017
                        // "-" always fails the range check
13018
                        JSON_THROW(detail::out_of_range::create(402,
13019
                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13020
                                                                ") is out of range", *ptr));
13021
                    }
13022
13023
                    // note: at performs range check
13024
                    ptr = &ptr->at(array_index(reference_token));
13025
                    break;
13026
                }
13027
13028
                case detail::value_t::null:
13029
                case detail::value_t::string:
13030
                case detail::value_t::boolean:
13031
                case detail::value_t::number_integer:
13032
                case detail::value_t::number_unsigned:
13033
                case detail::value_t::number_float:
13034
                case detail::value_t::binary:
13035
                case detail::value_t::discarded:
13036
                default:
13037
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13038
            }
13039
        }
13040
13041
        return *ptr;
13042
    }
13043
13044
    /*!
13045
    @brief return a const reference to the pointed to value
13046
13047
    @param[in] ptr  a JSON value
13048
13049
    @return const reference to the JSON value pointed to by the JSON
13050
    pointer
13051
13052
    @throw parse_error.106   if an array index begins with '0'
13053
    @throw parse_error.109   if an array index was not a number
13054
    @throw out_of_range.402  if the array index '-' is used
13055
    @throw out_of_range.404  if the JSON pointer can not be resolved
13056
    */
13057
    const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
13058
    {
13059
        for (const auto& reference_token : reference_tokens)
13060
        {
13061
            switch (ptr->type())
13062
            {
13063
                case detail::value_t::object:
13064
                {
13065
                    // use unchecked object access
13066
                    ptr = &ptr->operator[](reference_token);
13067
                    break;
13068
                }
13069
13070
                case detail::value_t::array:
13071
                {
13072
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13073
                    {
13074
                        // "-" cannot be used for const access
13075
                        JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
13076
                    }
13077
13078
                    // use unchecked array access
13079
                    ptr = &ptr->operator[](array_index(reference_token));
13080
                    break;
13081
                }
13082
13083
                case detail::value_t::null:
13084
                case detail::value_t::string:
13085
                case detail::value_t::boolean:
13086
                case detail::value_t::number_integer:
13087
                case detail::value_t::number_unsigned:
13088
                case detail::value_t::number_float:
13089
                case detail::value_t::binary:
13090
                case detail::value_t::discarded:
13091
                default:
13092
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13093
            }
13094
        }
13095
13096
        return *ptr;
13097
    }
13098
13099
    /*!
13100
    @throw parse_error.106   if an array index begins with '0'
13101
    @throw parse_error.109   if an array index was not a number
13102
    @throw out_of_range.402  if the array index '-' is used
13103
    @throw out_of_range.404  if the JSON pointer can not be resolved
13104
    */
13105
    const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13106
    {
13107
        for (const auto& reference_token : reference_tokens)
13108
        {
13109
            switch (ptr->type())
13110
            {
13111
                case detail::value_t::object:
13112
                {
13113
                    // note: at performs range check
13114
                    ptr = &ptr->at(reference_token);
13115
                    break;
13116
                }
13117
13118
                case detail::value_t::array:
13119
                {
13120
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13121
                    {
13122
                        // "-" always fails the range check
13123
                        JSON_THROW(detail::out_of_range::create(402,
13124
                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13125
                                                                ") is out of range", *ptr));
13126
                    }
13127
13128
                    // note: at performs range check
13129
                    ptr = &ptr->at(array_index(reference_token));
13130
                    break;
13131
                }
13132
13133
                case detail::value_t::null:
13134
                case detail::value_t::string:
13135
                case detail::value_t::boolean:
13136
                case detail::value_t::number_integer:
13137
                case detail::value_t::number_unsigned:
13138
                case detail::value_t::number_float:
13139
                case detail::value_t::binary:
13140
                case detail::value_t::discarded:
13141
                default:
13142
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13143
            }
13144
        }
13145
13146
        return *ptr;
13147
    }
13148
13149
    /*!
13150
    @throw parse_error.106   if an array index begins with '0'
13151
    @throw parse_error.109   if an array index was not a number
13152
    */
13153
    bool contains(const BasicJsonType* ptr) const
13154
    {
13155
        for (const auto& reference_token : reference_tokens)
13156
        {
13157
            switch (ptr->type())
13158
            {
13159
                case detail::value_t::object:
13160
                {
13161
                    if (!ptr->contains(reference_token))
13162
                    {
13163
                        // we did not find the key in the object
13164
                        return false;
13165
                    }
13166
13167
                    ptr = &ptr->operator[](reference_token);
13168
                    break;
13169
                }
13170
13171
                case detail::value_t::array:
13172
                {
13173
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13174
                    {
13175
                        // "-" always fails the range check
13176
                        return false;
13177
                    }
13178
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13179
                    {
13180
                        // invalid char
13181
                        return false;
13182
                    }
13183
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13184
                    {
13185
                        if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13186
                        {
13187
                            // first char should be between '1' and '9'
13188
                            return false;
13189
                        }
13190
                        for (std::size_t i = 1; i < reference_token.size(); i++)
13191
                        {
13192
                            if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13193
                            {
13194
                                // other char should be between '0' and '9'
13195
                                return false;
13196
                            }
13197
                        }
13198
                    }
13199
13200
                    const auto idx = array_index(reference_token);
13201
                    if (idx >= ptr->size())
13202
                    {
13203
                        // index out of range
13204
                        return false;
13205
                    }
13206
13207
                    ptr = &ptr->operator[](idx);
13208
                    break;
13209
                }
13210
13211
                case detail::value_t::null:
13212
                case detail::value_t::string:
13213
                case detail::value_t::boolean:
13214
                case detail::value_t::number_integer:
13215
                case detail::value_t::number_unsigned:
13216
                case detail::value_t::number_float:
13217
                case detail::value_t::binary:
13218
                case detail::value_t::discarded:
13219
                default:
13220
                {
13221
                    // we do not expect primitive values if there is still a
13222
                    // reference token to process
13223
                    return false;
13224
                }
13225
            }
13226
        }
13227
13228
        // no reference token left means we found a primitive value
13229
        return true;
13230
    }
13231
13232
    /*!
13233
    @brief split the string input to reference tokens
13234
13235
    @note This function is only called by the json_pointer constructor.
13236
          All exceptions below are documented there.
13237
13238
    @throw parse_error.107  if the pointer is not empty or begins with '/'
13239
    @throw parse_error.108  if character '~' is not followed by '0' or '1'
13240
    */
13241
    static std::vector<std::string> split(const std::string& reference_string)
13242
0
    {
13243
0
        std::vector<std::string> result;
13244
0
13245
0
        // special case: empty reference string -> no reference tokens
13246
0
        if (reference_string.empty())
13247
0
        {
13248
0
            return result;
13249
0
        }
13250
0
13251
0
        // check if nonempty reference string begins with slash
13252
0
        if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13253
0
        {
13254
0
            JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13255
0
        }
13256
0
13257
0
        // extract the reference tokens:
13258
0
        // - slash: position of the last read slash (or end of string)
13259
0
        // - start: position after the previous slash
13260
0
        for (
13261
0
            // search for the first slash after the first character
13262
0
            std::size_t slash = reference_string.find_first_of('/', 1),
13263
0
            // set the beginning of the first reference token
13264
0
            start = 1;
13265
0
            // we can stop if start == 0 (if slash == std::string::npos)
13266
0
            start != 0;
13267
0
            // set the beginning of the next reference token
13268
0
            // (will eventually be 0 if slash == std::string::npos)
13269
0
            start = (slash == std::string::npos) ? 0 : slash + 1,
13270
0
            // find next slash
13271
0
            slash = reference_string.find_first_of('/', start))
13272
0
        {
13273
0
            // use the text between the beginning of the reference token
13274
0
            // (start) and the last slash (slash).
13275
0
            auto reference_token = reference_string.substr(start, slash - start);
13276
0
13277
0
            // check reference tokens are properly escaped
13278
0
            for (std::size_t pos = reference_token.find_first_of('~');
13279
0
                    pos != std::string::npos;
13280
0
                    pos = reference_token.find_first_of('~', pos + 1))
13281
0
            {
13282
0
                JSON_ASSERT(reference_token[pos] == '~');
13283
0
13284
0
                // ~ must be followed by 0 or 1
13285
0
                if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13286
0
                                         (reference_token[pos + 1] != '0' &&
13287
0
                                          reference_token[pos + 1] != '1')))
13288
0
                {
13289
0
                    JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13290
0
                }
13291
0
            }
13292
0
13293
0
            // finally, store the reference token
13294
0
            detail::unescape(reference_token);
13295
0
            result.push_back(reference_token);
13296
0
        }
13297
0
13298
0
        return result;
13299
0
    }
13300
13301
  private:
13302
    /*!
13303
    @param[in] reference_string  the reference string to the current value
13304
    @param[in] value             the value to consider
13305
    @param[in,out] result        the result object to insert values to
13306
13307
    @note Empty objects or arrays are flattened to `null`.
13308
    */
13309
    static void flatten(const std::string& reference_string,
13310
                        const BasicJsonType& value,
13311
                        BasicJsonType& result)
13312
    {
13313
        switch (value.type())
13314
        {
13315
            case detail::value_t::array:
13316
            {
13317
                if (value.m_value.array->empty())
13318
                {
13319
                    // flatten empty array as null
13320
                    result[reference_string] = nullptr;
13321
                }
13322
                else
13323
                {
13324
                    // iterate array and use index as reference string
13325
                    for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13326
                    {
13327
                        flatten(reference_string + "/" + std::to_string(i),
13328
                                value.m_value.array->operator[](i), result);
13329
                    }
13330
                }
13331
                break;
13332
            }
13333
13334
            case detail::value_t::object:
13335
            {
13336
                if (value.m_value.object->empty())
13337
                {
13338
                    // flatten empty object as null
13339
                    result[reference_string] = nullptr;
13340
                }
13341
                else
13342
                {
13343
                    // iterate object and use keys as reference string
13344
                    for (const auto& element : *value.m_value.object)
13345
                    {
13346
                        flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13347
                    }
13348
                }
13349
                break;
13350
            }
13351
13352
            case detail::value_t::null:
13353
            case detail::value_t::string:
13354
            case detail::value_t::boolean:
13355
            case detail::value_t::number_integer:
13356
            case detail::value_t::number_unsigned:
13357
            case detail::value_t::number_float:
13358
            case detail::value_t::binary:
13359
            case detail::value_t::discarded:
13360
            default:
13361
            {
13362
                // add primitive value with its reference string
13363
                result[reference_string] = value;
13364
                break;
13365
            }
13366
        }
13367
    }
13368
13369
    /*!
13370
    @param[in] value  flattened JSON
13371
13372
    @return unflattened JSON
13373
13374
    @throw parse_error.109 if array index is not a number
13375
    @throw type_error.314  if value is not an object
13376
    @throw type_error.315  if object values are not primitive
13377
    @throw type_error.313  if value cannot be unflattened
13378
    */
13379
    static BasicJsonType
13380
    unflatten(const BasicJsonType& value)
13381
    {
13382
        if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13383
        {
13384
            JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13385
        }
13386
13387
        BasicJsonType result;
13388
13389
        // iterate the JSON object values
13390
        for (const auto& element : *value.m_value.object)
13391
        {
13392
            if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13393
            {
13394
                JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13395
            }
13396
13397
            // assign value to reference pointed to by JSON pointer; Note that if
13398
            // the JSON pointer is "" (i.e., points to the whole value), function
13399
            // get_and_create returns a reference to result itself. An assignment
13400
            // will then create a primitive value.
13401
            json_pointer(element.first).get_and_create(result) = element.second;
13402
        }
13403
13404
        return result;
13405
    }
13406
13407
    /*!
13408
    @brief compares two JSON pointers for equality
13409
13410
    @param[in] lhs  JSON pointer to compare
13411
    @param[in] rhs  JSON pointer to compare
13412
    @return whether @a lhs is equal to @a rhs
13413
13414
    @complexity Linear in the length of the JSON pointer
13415
13416
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
13417
    */
13418
    friend bool operator==(json_pointer const& lhs,
13419
                           json_pointer const& rhs) noexcept
13420
    {
13421
        return lhs.reference_tokens == rhs.reference_tokens;
13422
    }
13423
13424
    /*!
13425
    @brief compares two JSON pointers for inequality
13426
13427
    @param[in] lhs  JSON pointer to compare
13428
    @param[in] rhs  JSON pointer to compare
13429
    @return whether @a lhs is not equal @a rhs
13430
13431
    @complexity Linear in the length of the JSON pointer
13432
13433
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
13434
    */
13435
    friend bool operator!=(json_pointer const& lhs,
13436
                           json_pointer const& rhs) noexcept
13437
    {
13438
        return !(lhs == rhs);
13439
    }
13440
13441
    /// the reference tokens
13442
    std::vector<std::string> reference_tokens;
13443
};
13444
}  // namespace nlohmann
13445
13446
// #include <nlohmann/detail/json_ref.hpp>
13447
13448
13449
#include <initializer_list>
13450
#include <utility>
13451
13452
// #include <nlohmann/detail/meta/type_traits.hpp>
13453
13454
13455
namespace nlohmann
13456
{
13457
namespace detail
13458
{
13459
template<typename BasicJsonType>
13460
class json_ref
13461
{
13462
  public:
13463
    using value_type = BasicJsonType;
13464
13465
    json_ref(value_type&& value)
13466
        : owned_value(std::move(value))
13467
    {}
13468
13469
    json_ref(const value_type& value)
13470
        : value_ref(&value)
13471
    {}
13472
13473
    json_ref(std::initializer_list<json_ref> init)
13474
        : owned_value(init)
13475
    {}
13476
13477
    template <
13478
        class... Args,
13479
        enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13480
    json_ref(Args && ... args)
13481
        : owned_value(std::forward<Args>(args)...)
13482
    {}
13483
13484
    // class should be movable only
13485
    json_ref(json_ref&&) noexcept = default;
13486
    json_ref(const json_ref&) = delete;
13487
    json_ref& operator=(const json_ref&) = delete;
13488
    json_ref& operator=(json_ref&&) = delete;
13489
    ~json_ref() = default;
13490
13491
    value_type moved_or_copied() const
13492
0
    {
13493
0
        if (value_ref == nullptr)
13494
0
        {
13495
0
            return std::move(owned_value);
13496
0
        }
13497
0
        return *value_ref;
13498
0
    }
13499
13500
    value_type const& operator*() const
13501
0
    {
13502
0
        return value_ref ? *value_ref : owned_value;
13503
0
    }
13504
13505
    value_type const* operator->() const
13506
0
    {
13507
0
        return &** this;
13508
0
    }
13509
13510
  private:
13511
    mutable value_type owned_value = nullptr;
13512
    value_type const* value_ref = nullptr;
13513
};
13514
}  // namespace detail
13515
}  // namespace nlohmann
13516
13517
// #include <nlohmann/detail/macro_scope.hpp>
13518
13519
// #include <nlohmann/detail/string_escape.hpp>
13520
13521
// #include <nlohmann/detail/meta/cpp_future.hpp>
13522
13523
// #include <nlohmann/detail/meta/type_traits.hpp>
13524
13525
// #include <nlohmann/detail/output/binary_writer.hpp>
13526
13527
13528
#include <algorithm> // reverse
13529
#include <array> // array
13530
#include <cmath> // isnan, isinf
13531
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13532
#include <cstring> // memcpy
13533
#include <limits> // numeric_limits
13534
#include <string> // string
13535
#include <utility> // move
13536
13537
// #include <nlohmann/detail/input/binary_reader.hpp>
13538
13539
// #include <nlohmann/detail/macro_scope.hpp>
13540
13541
// #include <nlohmann/detail/output/output_adapters.hpp>
13542
13543
13544
#include <algorithm> // copy
13545
#include <cstddef> // size_t
13546
#include <iterator> // back_inserter
13547
#include <memory> // shared_ptr, make_shared
13548
#include <string> // basic_string
13549
#include <vector> // vector
13550
13551
#ifndef JSON_NO_IO
13552
    #include <ios>      // streamsize
13553
    #include <ostream>  // basic_ostream
13554
#endif  // JSON_NO_IO
13555
13556
// #include <nlohmann/detail/macro_scope.hpp>
13557
13558
13559
namespace nlohmann
13560
{
13561
namespace detail
13562
{
13563
/// abstract output adapter interface
13564
template<typename CharType> struct output_adapter_protocol
13565
{
13566
    virtual void write_character(CharType c) = 0;
13567
    virtual void write_characters(const CharType* s, std::size_t length) = 0;
13568
0
    virtual ~output_adapter_protocol() = default;
13569
13570
0
    output_adapter_protocol() = default;
13571
    output_adapter_protocol(const output_adapter_protocol&) = default;
13572
    output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13573
    output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13574
    output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13575
};
13576
13577
/// a type to simplify interfaces
13578
template<typename CharType>
13579
using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13580
13581
/// output adapter for byte vectors
13582
template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13583
class output_vector_adapter : public output_adapter_protocol<CharType>
13584
{
13585
  public:
13586
    explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
13587
        : v(vec)
13588
    {}
13589
13590
    void write_character(CharType c) override
13591
    {
13592
        v.push_back(c);
13593
    }
13594
13595
    JSON_HEDLEY_NON_NULL(2)
13596
    void write_characters(const CharType* s, std::size_t length) override
13597
    {
13598
        std::copy(s, s + length, std::back_inserter(v));
13599
    }
13600
13601
  private:
13602
    std::vector<CharType, AllocatorType>& v;
13603
};
13604
13605
#ifndef JSON_NO_IO
13606
/// output adapter for output streams
13607
template<typename CharType>
13608
class output_stream_adapter : public output_adapter_protocol<CharType>
13609
{
13610
  public:
13611
    explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13612
        : stream(s)
13613
    {}
13614
13615
    void write_character(CharType c) override
13616
    {
13617
        stream.put(c);
13618
    }
13619
13620
    JSON_HEDLEY_NON_NULL(2)
13621
    void write_characters(const CharType* s, std::size_t length) override
13622
    {
13623
        stream.write(s, static_cast<std::streamsize>(length));
13624
    }
13625
13626
  private:
13627
    std::basic_ostream<CharType>& stream;
13628
};
13629
#endif  // JSON_NO_IO
13630
13631
/// output adapter for basic_string
13632
template<typename CharType, typename StringType = std::basic_string<CharType>>
13633
class output_string_adapter : public output_adapter_protocol<CharType>
13634
{
13635
  public:
13636
    explicit output_string_adapter(StringType& s) noexcept
13637
        : str(s)
13638
0
    {}
13639
13640
    void write_character(CharType c) override
13641
0
    {
13642
0
        str.push_back(c);
13643
0
    }
13644
13645
    JSON_HEDLEY_NON_NULL(2)
13646
    void write_characters(const CharType* s, std::size_t length) override
13647
0
    {
13648
0
        str.append(s, length);
13649
0
    }
13650
13651
  private:
13652
    StringType& str;
13653
};
13654
13655
template<typename CharType, typename StringType = std::basic_string<CharType>>
13656
class output_adapter
13657
{
13658
  public:
13659
    template<typename AllocatorType = std::allocator<CharType>>
13660
    output_adapter(std::vector<CharType, AllocatorType>& vec)
13661
        : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
13662
13663
#ifndef JSON_NO_IO
13664
    output_adapter(std::basic_ostream<CharType>& s)
13665
        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13666
#endif  // JSON_NO_IO
13667
13668
    output_adapter(StringType& s)
13669
0
        : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13670
13671
    operator output_adapter_t<CharType>()
13672
0
    {
13673
0
        return oa;
13674
0
    }
13675
13676
  private:
13677
    output_adapter_t<CharType> oa = nullptr;
13678
};
13679
}  // namespace detail
13680
}  // namespace nlohmann
13681
13682
13683
namespace nlohmann
13684
{
13685
namespace detail
13686
{
13687
///////////////////
13688
// binary writer //
13689
///////////////////
13690
13691
/*!
13692
@brief serialization to CBOR and MessagePack values
13693
*/
13694
template<typename BasicJsonType, typename CharType>
13695
class binary_writer
13696
{
13697
    using string_t = typename BasicJsonType::string_t;
13698
    using binary_t = typename BasicJsonType::binary_t;
13699
    using number_float_t = typename BasicJsonType::number_float_t;
13700
13701
  public:
13702
    /*!
13703
    @brief create a binary writer
13704
13705
    @param[in] adapter  output adapter to write to
13706
    */
13707
    explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13708
    {
13709
        JSON_ASSERT(oa);
13710
    }
13711
13712
    /*!
13713
    @param[in] j  JSON value to serialize
13714
    @pre       j.type() == value_t::object
13715
    */
13716
    void write_bson(const BasicJsonType& j)
13717
    {
13718
        switch (j.type())
13719
        {
13720
            case value_t::object:
13721
            {
13722
                write_bson_object(*j.m_value.object);
13723
                break;
13724
            }
13725
13726
            case value_t::null:
13727
            case value_t::array:
13728
            case value_t::string:
13729
            case value_t::boolean:
13730
            case value_t::number_integer:
13731
            case value_t::number_unsigned:
13732
            case value_t::number_float:
13733
            case value_t::binary:
13734
            case value_t::discarded:
13735
            default:
13736
            {
13737
                JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13738
            }
13739
        }
13740
    }
13741
13742
    /*!
13743
    @param[in] j  JSON value to serialize
13744
    */
13745
    void write_cbor(const BasicJsonType& j)
13746
    {
13747
        switch (j.type())
13748
        {
13749
            case value_t::null:
13750
            {
13751
                oa->write_character(to_char_type(0xF6));
13752
                break;
13753
            }
13754
13755
            case value_t::boolean:
13756
            {
13757
                oa->write_character(j.m_value.boolean
13758
                                    ? to_char_type(0xF5)
13759
                                    : to_char_type(0xF4));
13760
                break;
13761
            }
13762
13763
            case value_t::number_integer:
13764
            {
13765
                if (j.m_value.number_integer >= 0)
13766
                {
13767
                    // CBOR does not differentiate between positive signed
13768
                    // integers and unsigned integers. Therefore, we used the
13769
                    // code from the value_t::number_unsigned case here.
13770
                    if (j.m_value.number_integer <= 0x17)
13771
                    {
13772
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13773
                    }
13774
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13775
                    {
13776
                        oa->write_character(to_char_type(0x18));
13777
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13778
                    }
13779
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13780
                    {
13781
                        oa->write_character(to_char_type(0x19));
13782
                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13783
                    }
13784
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13785
                    {
13786
                        oa->write_character(to_char_type(0x1A));
13787
                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13788
                    }
13789
                    else
13790
                    {
13791
                        oa->write_character(to_char_type(0x1B));
13792
                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13793
                    }
13794
                }
13795
                else
13796
                {
13797
                    // The conversions below encode the sign in the first
13798
                    // byte, and the value is converted to a positive number.
13799
                    const auto positive_number = -1 - j.m_value.number_integer;
13800
                    if (j.m_value.number_integer >= -24)
13801
                    {
13802
                        write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13803
                    }
13804
                    else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13805
                    {
13806
                        oa->write_character(to_char_type(0x38));
13807
                        write_number(static_cast<std::uint8_t>(positive_number));
13808
                    }
13809
                    else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13810
                    {
13811
                        oa->write_character(to_char_type(0x39));
13812
                        write_number(static_cast<std::uint16_t>(positive_number));
13813
                    }
13814
                    else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13815
                    {
13816
                        oa->write_character(to_char_type(0x3A));
13817
                        write_number(static_cast<std::uint32_t>(positive_number));
13818
                    }
13819
                    else
13820
                    {
13821
                        oa->write_character(to_char_type(0x3B));
13822
                        write_number(static_cast<std::uint64_t>(positive_number));
13823
                    }
13824
                }
13825
                break;
13826
            }
13827
13828
            case value_t::number_unsigned:
13829
            {
13830
                if (j.m_value.number_unsigned <= 0x17)
13831
                {
13832
                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13833
                }
13834
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13835
                {
13836
                    oa->write_character(to_char_type(0x18));
13837
                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13838
                }
13839
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13840
                {
13841
                    oa->write_character(to_char_type(0x19));
13842
                    write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13843
                }
13844
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13845
                {
13846
                    oa->write_character(to_char_type(0x1A));
13847
                    write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13848
                }
13849
                else
13850
                {
13851
                    oa->write_character(to_char_type(0x1B));
13852
                    write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13853
                }
13854
                break;
13855
            }
13856
13857
            case value_t::number_float:
13858
            {
13859
                if (std::isnan(j.m_value.number_float))
13860
                {
13861
                    // NaN is 0xf97e00 in CBOR
13862
                    oa->write_character(to_char_type(0xF9));
13863
                    oa->write_character(to_char_type(0x7E));
13864
                    oa->write_character(to_char_type(0x00));
13865
                }
13866
                else if (std::isinf(j.m_value.number_float))
13867
                {
13868
                    // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13869
                    oa->write_character(to_char_type(0xf9));
13870
                    oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13871
                    oa->write_character(to_char_type(0x00));
13872
                }
13873
                else
13874
                {
13875
                    write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13876
                }
13877
                break;
13878
            }
13879
13880
            case value_t::string:
13881
            {
13882
                // step 1: write control byte and the string length
13883
                const auto N = j.m_value.string->size();
13884
                if (N <= 0x17)
13885
                {
13886
                    write_number(static_cast<std::uint8_t>(0x60 + N));
13887
                }
13888
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13889
                {
13890
                    oa->write_character(to_char_type(0x78));
13891
                    write_number(static_cast<std::uint8_t>(N));
13892
                }
13893
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13894
                {
13895
                    oa->write_character(to_char_type(0x79));
13896
                    write_number(static_cast<std::uint16_t>(N));
13897
                }
13898
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13899
                {
13900
                    oa->write_character(to_char_type(0x7A));
13901
                    write_number(static_cast<std::uint32_t>(N));
13902
                }
13903
                // LCOV_EXCL_START
13904
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13905
                {
13906
                    oa->write_character(to_char_type(0x7B));
13907
                    write_number(static_cast<std::uint64_t>(N));
13908
                }
13909
                // LCOV_EXCL_STOP
13910
13911
                // step 2: write the string
13912
                oa->write_characters(
13913
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13914
                    j.m_value.string->size());
13915
                break;
13916
            }
13917
13918
            case value_t::array:
13919
            {
13920
                // step 1: write control byte and the array size
13921
                const auto N = j.m_value.array->size();
13922
                if (N <= 0x17)
13923
                {
13924
                    write_number(static_cast<std::uint8_t>(0x80 + N));
13925
                }
13926
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13927
                {
13928
                    oa->write_character(to_char_type(0x98));
13929
                    write_number(static_cast<std::uint8_t>(N));
13930
                }
13931
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13932
                {
13933
                    oa->write_character(to_char_type(0x99));
13934
                    write_number(static_cast<std::uint16_t>(N));
13935
                }
13936
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13937
                {
13938
                    oa->write_character(to_char_type(0x9A));
13939
                    write_number(static_cast<std::uint32_t>(N));
13940
                }
13941
                // LCOV_EXCL_START
13942
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13943
                {
13944
                    oa->write_character(to_char_type(0x9B));
13945
                    write_number(static_cast<std::uint64_t>(N));
13946
                }
13947
                // LCOV_EXCL_STOP
13948
13949
                // step 2: write each element
13950
                for (const auto& el : *j.m_value.array)
13951
                {
13952
                    write_cbor(el);
13953
                }
13954
                break;
13955
            }
13956
13957
            case value_t::binary:
13958
            {
13959
                if (j.m_value.binary->has_subtype())
13960
                {
13961
                    if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13962
                    {
13963
                        write_number(static_cast<std::uint8_t>(0xd8));
13964
                        write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13965
                    }
13966
                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13967
                    {
13968
                        write_number(static_cast<std::uint8_t>(0xd9));
13969
                        write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13970
                    }
13971
                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13972
                    {
13973
                        write_number(static_cast<std::uint8_t>(0xda));
13974
                        write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13975
                    }
13976
                    else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13977
                    {
13978
                        write_number(static_cast<std::uint8_t>(0xdb));
13979
                        write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13980
                    }
13981
                }
13982
13983
                // step 1: write control byte and the binary array size
13984
                const auto N = j.m_value.binary->size();
13985
                if (N <= 0x17)
13986
                {
13987
                    write_number(static_cast<std::uint8_t>(0x40 + N));
13988
                }
13989
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13990
                {
13991
                    oa->write_character(to_char_type(0x58));
13992
                    write_number(static_cast<std::uint8_t>(N));
13993
                }
13994
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13995
                {
13996
                    oa->write_character(to_char_type(0x59));
13997
                    write_number(static_cast<std::uint16_t>(N));
13998
                }
13999
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14000
                {
14001
                    oa->write_character(to_char_type(0x5A));
14002
                    write_number(static_cast<std::uint32_t>(N));
14003
                }
14004
                // LCOV_EXCL_START
14005
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14006
                {
14007
                    oa->write_character(to_char_type(0x5B));
14008
                    write_number(static_cast<std::uint64_t>(N));
14009
                }
14010
                // LCOV_EXCL_STOP
14011
14012
                // step 2: write each element
14013
                oa->write_characters(
14014
                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14015
                    N);
14016
14017
                break;
14018
            }
14019
14020
            case value_t::object:
14021
            {
14022
                // step 1: write control byte and the object size
14023
                const auto N = j.m_value.object->size();
14024
                if (N <= 0x17)
14025
                {
14026
                    write_number(static_cast<std::uint8_t>(0xA0 + N));
14027
                }
14028
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14029
                {
14030
                    oa->write_character(to_char_type(0xB8));
14031
                    write_number(static_cast<std::uint8_t>(N));
14032
                }
14033
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14034
                {
14035
                    oa->write_character(to_char_type(0xB9));
14036
                    write_number(static_cast<std::uint16_t>(N));
14037
                }
14038
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14039
                {
14040
                    oa->write_character(to_char_type(0xBA));
14041
                    write_number(static_cast<std::uint32_t>(N));
14042
                }
14043
                // LCOV_EXCL_START
14044
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14045
                {
14046
                    oa->write_character(to_char_type(0xBB));
14047
                    write_number(static_cast<std::uint64_t>(N));
14048
                }
14049
                // LCOV_EXCL_STOP
14050
14051
                // step 2: write each element
14052
                for (const auto& el : *j.m_value.object)
14053
                {
14054
                    write_cbor(el.first);
14055
                    write_cbor(el.second);
14056
                }
14057
                break;
14058
            }
14059
14060
            case value_t::discarded:
14061
            default:
14062
                break;
14063
        }
14064
    }
14065
14066
    /*!
14067
    @param[in] j  JSON value to serialize
14068
    */
14069
    void write_msgpack(const BasicJsonType& j)
14070
    {
14071
        switch (j.type())
14072
        {
14073
            case value_t::null: // nil
14074
            {
14075
                oa->write_character(to_char_type(0xC0));
14076
                break;
14077
            }
14078
14079
            case value_t::boolean: // true and false
14080
            {
14081
                oa->write_character(j.m_value.boolean
14082
                                    ? to_char_type(0xC3)
14083
                                    : to_char_type(0xC2));
14084
                break;
14085
            }
14086
14087
            case value_t::number_integer:
14088
            {
14089
                if (j.m_value.number_integer >= 0)
14090
                {
14091
                    // MessagePack does not differentiate between positive
14092
                    // signed integers and unsigned integers. Therefore, we used
14093
                    // the code from the value_t::number_unsigned case here.
14094
                    if (j.m_value.number_unsigned < 128)
14095
                    {
14096
                        // positive fixnum
14097
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14098
                    }
14099
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14100
                    {
14101
                        // uint 8
14102
                        oa->write_character(to_char_type(0xCC));
14103
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14104
                    }
14105
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14106
                    {
14107
                        // uint 16
14108
                        oa->write_character(to_char_type(0xCD));
14109
                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14110
                    }
14111
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14112
                    {
14113
                        // uint 32
14114
                        oa->write_character(to_char_type(0xCE));
14115
                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14116
                    }
14117
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14118
                    {
14119
                        // uint 64
14120
                        oa->write_character(to_char_type(0xCF));
14121
                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14122
                    }
14123
                }
14124
                else
14125
                {
14126
                    if (j.m_value.number_integer >= -32)
14127
                    {
14128
                        // negative fixnum
14129
                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14130
                    }
14131
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14132
                             j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14133
                    {
14134
                        // int 8
14135
                        oa->write_character(to_char_type(0xD0));
14136
                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14137
                    }
14138
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14139
                             j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14140
                    {
14141
                        // int 16
14142
                        oa->write_character(to_char_type(0xD1));
14143
                        write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14144
                    }
14145
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14146
                             j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14147
                    {
14148
                        // int 32
14149
                        oa->write_character(to_char_type(0xD2));
14150
                        write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14151
                    }
14152
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14153
                             j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14154
                    {
14155
                        // int 64
14156
                        oa->write_character(to_char_type(0xD3));
14157
                        write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14158
                    }
14159
                }
14160
                break;
14161
            }
14162
14163
            case value_t::number_unsigned:
14164
            {
14165
                if (j.m_value.number_unsigned < 128)
14166
                {
14167
                    // positive fixnum
14168
                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14169
                }
14170
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14171
                {
14172
                    // uint 8
14173
                    oa->write_character(to_char_type(0xCC));
14174
                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14175
                }
14176
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14177
                {
14178
                    // uint 16
14179
                    oa->write_character(to_char_type(0xCD));
14180
                    write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14181
                }
14182
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14183
                {
14184
                    // uint 32
14185
                    oa->write_character(to_char_type(0xCE));
14186
                    write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14187
                }
14188
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14189
                {
14190
                    // uint 64
14191
                    oa->write_character(to_char_type(0xCF));
14192
                    write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14193
                }
14194
                break;
14195
            }
14196
14197
            case value_t::number_float:
14198
            {
14199
                write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14200
                break;
14201
            }
14202
14203
            case value_t::string:
14204
            {
14205
                // step 1: write control byte and the string length
14206
                const auto N = j.m_value.string->size();
14207
                if (N <= 31)
14208
                {
14209
                    // fixstr
14210
                    write_number(static_cast<std::uint8_t>(0xA0 | N));
14211
                }
14212
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14213
                {
14214
                    // str 8
14215
                    oa->write_character(to_char_type(0xD9));
14216
                    write_number(static_cast<std::uint8_t>(N));
14217
                }
14218
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14219
                {
14220
                    // str 16
14221
                    oa->write_character(to_char_type(0xDA));
14222
                    write_number(static_cast<std::uint16_t>(N));
14223
                }
14224
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14225
                {
14226
                    // str 32
14227
                    oa->write_character(to_char_type(0xDB));
14228
                    write_number(static_cast<std::uint32_t>(N));
14229
                }
14230
14231
                // step 2: write the string
14232
                oa->write_characters(
14233
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14234
                    j.m_value.string->size());
14235
                break;
14236
            }
14237
14238
            case value_t::array:
14239
            {
14240
                // step 1: write control byte and the array size
14241
                const auto N = j.m_value.array->size();
14242
                if (N <= 15)
14243
                {
14244
                    // fixarray
14245
                    write_number(static_cast<std::uint8_t>(0x90 | N));
14246
                }
14247
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14248
                {
14249
                    // array 16
14250
                    oa->write_character(to_char_type(0xDC));
14251
                    write_number(static_cast<std::uint16_t>(N));
14252
                }
14253
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14254
                {
14255
                    // array 32
14256
                    oa->write_character(to_char_type(0xDD));
14257
                    write_number(static_cast<std::uint32_t>(N));
14258
                }
14259
14260
                // step 2: write each element
14261
                for (const auto& el : *j.m_value.array)
14262
                {
14263
                    write_msgpack(el);
14264
                }
14265
                break;
14266
            }
14267
14268
            case value_t::binary:
14269
            {
14270
                // step 0: determine if the binary type has a set subtype to
14271
                // determine whether or not to use the ext or fixext types
14272
                const bool use_ext = j.m_value.binary->has_subtype();
14273
14274
                // step 1: write control byte and the byte string length
14275
                const auto N = j.m_value.binary->size();
14276
                if (N <= (std::numeric_limits<std::uint8_t>::max)())
14277
                {
14278
                    std::uint8_t output_type{};
14279
                    bool fixed = true;
14280
                    if (use_ext)
14281
                    {
14282
                        switch (N)
14283
                        {
14284
                            case 1:
14285
                                output_type = 0xD4; // fixext 1
14286
                                break;
14287
                            case 2:
14288
                                output_type = 0xD5; // fixext 2
14289
                                break;
14290
                            case 4:
14291
                                output_type = 0xD6; // fixext 4
14292
                                break;
14293
                            case 8:
14294
                                output_type = 0xD7; // fixext 8
14295
                                break;
14296
                            case 16:
14297
                                output_type = 0xD8; // fixext 16
14298
                                break;
14299
                            default:
14300
                                output_type = 0xC7; // ext 8
14301
                                fixed = false;
14302
                                break;
14303
                        }
14304
14305
                    }
14306
                    else
14307
                    {
14308
                        output_type = 0xC4; // bin 8
14309
                        fixed = false;
14310
                    }
14311
14312
                    oa->write_character(to_char_type(output_type));
14313
                    if (!fixed)
14314
                    {
14315
                        write_number(static_cast<std::uint8_t>(N));
14316
                    }
14317
                }
14318
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14319
                {
14320
                    std::uint8_t output_type = use_ext
14321
                                               ? 0xC8 // ext 16
14322
                                               : 0xC5; // bin 16
14323
14324
                    oa->write_character(to_char_type(output_type));
14325
                    write_number(static_cast<std::uint16_t>(N));
14326
                }
14327
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14328
                {
14329
                    std::uint8_t output_type = use_ext
14330
                                               ? 0xC9 // ext 32
14331
                                               : 0xC6; // bin 32
14332
14333
                    oa->write_character(to_char_type(output_type));
14334
                    write_number(static_cast<std::uint32_t>(N));
14335
                }
14336
14337
                // step 1.5: if this is an ext type, write the subtype
14338
                if (use_ext)
14339
                {
14340
                    write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14341
                }
14342
14343
                // step 2: write the byte string
14344
                oa->write_characters(
14345
                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14346
                    N);
14347
14348
                break;
14349
            }
14350
14351
            case value_t::object:
14352
            {
14353
                // step 1: write control byte and the object size
14354
                const auto N = j.m_value.object->size();
14355
                if (N <= 15)
14356
                {
14357
                    // fixmap
14358
                    write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14359
                }
14360
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14361
                {
14362
                    // map 16
14363
                    oa->write_character(to_char_type(0xDE));
14364
                    write_number(static_cast<std::uint16_t>(N));
14365
                }
14366
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14367
                {
14368
                    // map 32
14369
                    oa->write_character(to_char_type(0xDF));
14370
                    write_number(static_cast<std::uint32_t>(N));
14371
                }
14372
14373
                // step 2: write each element
14374
                for (const auto& el : *j.m_value.object)
14375
                {
14376
                    write_msgpack(el.first);
14377
                    write_msgpack(el.second);
14378
                }
14379
                break;
14380
            }
14381
14382
            case value_t::discarded:
14383
            default:
14384
                break;
14385
        }
14386
    }
14387
14388
    /*!
14389
    @param[in] j  JSON value to serialize
14390
    @param[in] use_count   whether to use '#' prefixes (optimized format)
14391
    @param[in] use_type    whether to use '$' prefixes (optimized format)
14392
    @param[in] add_prefix  whether prefixes need to be used for this value
14393
    */
14394
    void write_ubjson(const BasicJsonType& j, const bool use_count,
14395
                      const bool use_type, const bool add_prefix = true)
14396
    {
14397
        switch (j.type())
14398
        {
14399
            case value_t::null:
14400
            {
14401
                if (add_prefix)
14402
                {
14403
                    oa->write_character(to_char_type('Z'));
14404
                }
14405
                break;
14406
            }
14407
14408
            case value_t::boolean:
14409
            {
14410
                if (add_prefix)
14411
                {
14412
                    oa->write_character(j.m_value.boolean
14413
                                        ? to_char_type('T')
14414
                                        : to_char_type('F'));
14415
                }
14416
                break;
14417
            }
14418
14419
            case value_t::number_integer:
14420
            {
14421
                write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14422
                break;
14423
            }
14424
14425
            case value_t::number_unsigned:
14426
            {
14427
                write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14428
                break;
14429
            }
14430
14431
            case value_t::number_float:
14432
            {
14433
                write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14434
                break;
14435
            }
14436
14437
            case value_t::string:
14438
            {
14439
                if (add_prefix)
14440
                {
14441
                    oa->write_character(to_char_type('S'));
14442
                }
14443
                write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14444
                oa->write_characters(
14445
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14446
                    j.m_value.string->size());
14447
                break;
14448
            }
14449
14450
            case value_t::array:
14451
            {
14452
                if (add_prefix)
14453
                {
14454
                    oa->write_character(to_char_type('['));
14455
                }
14456
14457
                bool prefix_required = true;
14458
                if (use_type && !j.m_value.array->empty())
14459
                {
14460
                    JSON_ASSERT(use_count);
14461
                    const CharType first_prefix = ubjson_prefix(j.front());
14462
                    const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14463
                                                         [this, first_prefix](const BasicJsonType & v)
14464
                    {
14465
                        return ubjson_prefix(v) == first_prefix;
14466
                    });
14467
14468
                    if (same_prefix)
14469
                    {
14470
                        prefix_required = false;
14471
                        oa->write_character(to_char_type('$'));
14472
                        oa->write_character(first_prefix);
14473
                    }
14474
                }
14475
14476
                if (use_count)
14477
                {
14478
                    oa->write_character(to_char_type('#'));
14479
                    write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14480
                }
14481
14482
                for (const auto& el : *j.m_value.array)
14483
                {
14484
                    write_ubjson(el, use_count, use_type, prefix_required);
14485
                }
14486
14487
                if (!use_count)
14488
                {
14489
                    oa->write_character(to_char_type(']'));
14490
                }
14491
14492
                break;
14493
            }
14494
14495
            case value_t::binary:
14496
            {
14497
                if (add_prefix)
14498
                {
14499
                    oa->write_character(to_char_type('['));
14500
                }
14501
14502
                if (use_type && !j.m_value.binary->empty())
14503
                {
14504
                    JSON_ASSERT(use_count);
14505
                    oa->write_character(to_char_type('$'));
14506
                    oa->write_character('U');
14507
                }
14508
14509
                if (use_count)
14510
                {
14511
                    oa->write_character(to_char_type('#'));
14512
                    write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14513
                }
14514
14515
                if (use_type)
14516
                {
14517
                    oa->write_characters(
14518
                        reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14519
                        j.m_value.binary->size());
14520
                }
14521
                else
14522
                {
14523
                    for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14524
                    {
14525
                        oa->write_character(to_char_type('U'));
14526
                        oa->write_character(j.m_value.binary->data()[i]);
14527
                    }
14528
                }
14529
14530
                if (!use_count)
14531
                {
14532
                    oa->write_character(to_char_type(']'));
14533
                }
14534
14535
                break;
14536
            }
14537
14538
            case value_t::object:
14539
            {
14540
                if (add_prefix)
14541
                {
14542
                    oa->write_character(to_char_type('{'));
14543
                }
14544
14545
                bool prefix_required = true;
14546
                if (use_type && !j.m_value.object->empty())
14547
                {
14548
                    JSON_ASSERT(use_count);
14549
                    const CharType first_prefix = ubjson_prefix(j.front());
14550
                    const bool same_prefix = std::all_of(j.begin(), j.end(),
14551
                                                         [this, first_prefix](const BasicJsonType & v)
14552
                    {
14553
                        return ubjson_prefix(v) == first_prefix;
14554
                    });
14555
14556
                    if (same_prefix)
14557
                    {
14558
                        prefix_required = false;
14559
                        oa->write_character(to_char_type('$'));
14560
                        oa->write_character(first_prefix);
14561
                    }
14562
                }
14563
14564
                if (use_count)
14565
                {
14566
                    oa->write_character(to_char_type('#'));
14567
                    write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14568
                }
14569
14570
                for (const auto& el : *j.m_value.object)
14571
                {
14572
                    write_number_with_ubjson_prefix(el.first.size(), true);
14573
                    oa->write_characters(
14574
                        reinterpret_cast<const CharType*>(el.first.c_str()),
14575
                        el.first.size());
14576
                    write_ubjson(el.second, use_count, use_type, prefix_required);
14577
                }
14578
14579
                if (!use_count)
14580
                {
14581
                    oa->write_character(to_char_type('}'));
14582
                }
14583
14584
                break;
14585
            }
14586
14587
            case value_t::discarded:
14588
            default:
14589
                break;
14590
        }
14591
    }
14592
14593
  private:
14594
    //////////
14595
    // BSON //
14596
    //////////
14597
14598
    /*!
14599
    @return The size of a BSON document entry header, including the id marker
14600
            and the entry name size (and its null-terminator).
14601
    */
14602
    static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14603
    {
14604
        const auto it = name.find(static_cast<typename string_t::value_type>(0));
14605
        if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14606
        {
14607
            JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14608
            static_cast<void>(j);
14609
        }
14610
14611
        return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14612
    }
14613
14614
    /*!
14615
    @brief Writes the given @a element_type and @a name to the output adapter
14616
    */
14617
    void write_bson_entry_header(const string_t& name,
14618
                                 const std::uint8_t element_type)
14619
    {
14620
        oa->write_character(to_char_type(element_type)); // boolean
14621
        oa->write_characters(
14622
            reinterpret_cast<const CharType*>(name.c_str()),
14623
            name.size() + 1u);
14624
    }
14625
14626
    /*!
14627
    @brief Writes a BSON element with key @a name and boolean value @a value
14628
    */
14629
    void write_bson_boolean(const string_t& name,
14630
                            const bool value)
14631
    {
14632
        write_bson_entry_header(name, 0x08);
14633
        oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14634
    }
14635
14636
    /*!
14637
    @brief Writes a BSON element with key @a name and double value @a value
14638
    */
14639
    void write_bson_double(const string_t& name,
14640
                           const double value)
14641
    {
14642
        write_bson_entry_header(name, 0x01);
14643
        write_number<double, true>(value);
14644
    }
14645
14646
    /*!
14647
    @return The size of the BSON-encoded string in @a value
14648
    */
14649
    static std::size_t calc_bson_string_size(const string_t& value)
14650
    {
14651
        return sizeof(std::int32_t) + value.size() + 1ul;
14652
    }
14653
14654
    /*!
14655
    @brief Writes a BSON element with key @a name and string value @a value
14656
    */
14657
    void write_bson_string(const string_t& name,
14658
                           const string_t& value)
14659
    {
14660
        write_bson_entry_header(name, 0x02);
14661
14662
        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14663
        oa->write_characters(
14664
            reinterpret_cast<const CharType*>(value.c_str()),
14665
            value.size() + 1);
14666
    }
14667
14668
    /*!
14669
    @brief Writes a BSON element with key @a name and null value
14670
    */
14671
    void write_bson_null(const string_t& name)
14672
    {
14673
        write_bson_entry_header(name, 0x0A);
14674
    }
14675
14676
    /*!
14677
    @return The size of the BSON-encoded integer @a value
14678
    */
14679
    static std::size_t calc_bson_integer_size(const std::int64_t value)
14680
    {
14681
        return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14682
               ? sizeof(std::int32_t)
14683
               : sizeof(std::int64_t);
14684
    }
14685
14686
    /*!
14687
    @brief Writes a BSON element with key @a name and integer @a value
14688
    */
14689
    void write_bson_integer(const string_t& name,
14690
                            const std::int64_t value)
14691
    {
14692
        if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14693
        {
14694
            write_bson_entry_header(name, 0x10); // int32
14695
            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14696
        }
14697
        else
14698
        {
14699
            write_bson_entry_header(name, 0x12); // int64
14700
            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14701
        }
14702
    }
14703
14704
    /*!
14705
    @return The size of the BSON-encoded unsigned integer in @a j
14706
    */
14707
    static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14708
    {
14709
        return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14710
               ? sizeof(std::int32_t)
14711
               : sizeof(std::int64_t);
14712
    }
14713
14714
    /*!
14715
    @brief Writes a BSON element with key @a name and unsigned @a value
14716
    */
14717
    void write_bson_unsigned(const string_t& name,
14718
                             const BasicJsonType& j)
14719
    {
14720
        if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14721
        {
14722
            write_bson_entry_header(name, 0x10 /* int32 */);
14723
            write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14724
        }
14725
        else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14726
        {
14727
            write_bson_entry_header(name, 0x12 /* int64 */);
14728
            write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14729
        }
14730
        else
14731
        {
14732
            JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
14733
        }
14734
    }
14735
14736
    /*!
14737
    @brief Writes a BSON element with key @a name and object @a value
14738
    */
14739
    void write_bson_object_entry(const string_t& name,
14740
                                 const typename BasicJsonType::object_t& value)
14741
    {
14742
        write_bson_entry_header(name, 0x03); // object
14743
        write_bson_object(value);
14744
    }
14745
14746
    /*!
14747
    @return The size of the BSON-encoded array @a value
14748
    */
14749
    static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14750
    {
14751
        std::size_t array_index = 0ul;
14752
14753
        const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14754
        {
14755
            return result + calc_bson_element_size(std::to_string(array_index++), el);
14756
        });
14757
14758
        return sizeof(std::int32_t) + embedded_document_size + 1ul;
14759
    }
14760
14761
    /*!
14762
    @return The size of the BSON-encoded binary array @a value
14763
    */
14764
    static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14765
    {
14766
        return sizeof(std::int32_t) + value.size() + 1ul;
14767
    }
14768
14769
    /*!
14770
    @brief Writes a BSON element with key @a name and array @a value
14771
    */
14772
    void write_bson_array(const string_t& name,
14773
                          const typename BasicJsonType::array_t& value)
14774
    {
14775
        write_bson_entry_header(name, 0x04); // array
14776
        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14777
14778
        std::size_t array_index = 0ul;
14779
14780
        for (const auto& el : value)
14781
        {
14782
            write_bson_element(std::to_string(array_index++), el);
14783
        }
14784
14785
        oa->write_character(to_char_type(0x00));
14786
    }
14787
14788
    /*!
14789
    @brief Writes a BSON element with key @a name and binary value @a value
14790
    */
14791
    void write_bson_binary(const string_t& name,
14792
                           const binary_t& value)
14793
    {
14794
        write_bson_entry_header(name, 0x05);
14795
14796
        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14797
        write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14798
14799
        oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14800
    }
14801
14802
    /*!
14803
    @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
14804
    @return The calculated size for the BSON document entry for @a j with the given @a name.
14805
    */
14806
    static std::size_t calc_bson_element_size(const string_t& name,
14807
            const BasicJsonType& j)
14808
    {
14809
        const auto header_size = calc_bson_entry_header_size(name, j);
14810
        switch (j.type())
14811
        {
14812
            case value_t::object:
14813
                return header_size + calc_bson_object_size(*j.m_value.object);
14814
14815
            case value_t::array:
14816
                return header_size + calc_bson_array_size(*j.m_value.array);
14817
14818
            case value_t::binary:
14819
                return header_size + calc_bson_binary_size(*j.m_value.binary);
14820
14821
            case value_t::boolean:
14822
                return header_size + 1ul;
14823
14824
            case value_t::number_float:
14825
                return header_size + 8ul;
14826
14827
            case value_t::number_integer:
14828
                return header_size + calc_bson_integer_size(j.m_value.number_integer);
14829
14830
            case value_t::number_unsigned:
14831
                return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14832
14833
            case value_t::string:
14834
                return header_size + calc_bson_string_size(*j.m_value.string);
14835
14836
            case value_t::null:
14837
                return header_size + 0ul;
14838
14839
            // LCOV_EXCL_START
14840
            case value_t::discarded:
14841
            default:
14842
                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14843
                return 0ul;
14844
                // LCOV_EXCL_STOP
14845
        }
14846
    }
14847
14848
    /*!
14849
    @brief Serializes the JSON value @a j to BSON and associates it with the
14850
           key @a name.
14851
    @param name The name to associate with the JSON entity @a j within the
14852
                current BSON document
14853
    */
14854
    void write_bson_element(const string_t& name,
14855
                            const BasicJsonType& j)
14856
    {
14857
        switch (j.type())
14858
        {
14859
            case value_t::object:
14860
                return write_bson_object_entry(name, *j.m_value.object);
14861
14862
            case value_t::array:
14863
                return write_bson_array(name, *j.m_value.array);
14864
14865
            case value_t::binary:
14866
                return write_bson_binary(name, *j.m_value.binary);
14867
14868
            case value_t::boolean:
14869
                return write_bson_boolean(name, j.m_value.boolean);
14870
14871
            case value_t::number_float:
14872
                return write_bson_double(name, j.m_value.number_float);
14873
14874
            case value_t::number_integer:
14875
                return write_bson_integer(name, j.m_value.number_integer);
14876
14877
            case value_t::number_unsigned:
14878
                return write_bson_unsigned(name, j);
14879
14880
            case value_t::string:
14881
                return write_bson_string(name, *j.m_value.string);
14882
14883
            case value_t::null:
14884
                return write_bson_null(name);
14885
14886
            // LCOV_EXCL_START
14887
            case value_t::discarded:
14888
            default:
14889
                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14890
                return;
14891
                // LCOV_EXCL_STOP
14892
        }
14893
    }
14894
14895
    /*!
14896
    @brief Calculates the size of the BSON serialization of the given
14897
           JSON-object @a j.
14898
    @param[in] value  JSON value to serialize
14899
    @pre       value.type() == value_t::object
14900
    */
14901
    static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14902
    {
14903
        std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14904
                                    [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14905
        {
14906
            return result += calc_bson_element_size(el.first, el.second);
14907
        });
14908
14909
        return sizeof(std::int32_t) + document_size + 1ul;
14910
    }
14911
14912
    /*!
14913
    @param[in] value  JSON value to serialize
14914
    @pre       value.type() == value_t::object
14915
    */
14916
    void write_bson_object(const typename BasicJsonType::object_t& value)
14917
    {
14918
        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14919
14920
        for (const auto& el : value)
14921
        {
14922
            write_bson_element(el.first, el.second);
14923
        }
14924
14925
        oa->write_character(to_char_type(0x00));
14926
    }
14927
14928
    //////////
14929
    // CBOR //
14930
    //////////
14931
14932
    static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14933
    {
14934
        return to_char_type(0xFA);  // Single-Precision Float
14935
    }
14936
14937
    static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14938
    {
14939
        return to_char_type(0xFB);  // Double-Precision Float
14940
    }
14941
14942
    /////////////
14943
    // MsgPack //
14944
    /////////////
14945
14946
    static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14947
    {
14948
        return to_char_type(0xCA);  // float 32
14949
    }
14950
14951
    static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14952
    {
14953
        return to_char_type(0xCB);  // float 64
14954
    }
14955
14956
    ////////////
14957
    // UBJSON //
14958
    ////////////
14959
14960
    // UBJSON: write number (floating point)
14961
    template<typename NumberType, typename std::enable_if<
14962
                 std::is_floating_point<NumberType>::value, int>::type = 0>
14963
    void write_number_with_ubjson_prefix(const NumberType n,
14964
                                         const bool add_prefix)
14965
    {
14966
        if (add_prefix)
14967
        {
14968
            oa->write_character(get_ubjson_float_prefix(n));
14969
        }
14970
        write_number(n);
14971
    }
14972
14973
    // UBJSON: write number (unsigned integer)
14974
    template<typename NumberType, typename std::enable_if<
14975
                 std::is_unsigned<NumberType>::value, int>::type = 0>
14976
    void write_number_with_ubjson_prefix(const NumberType n,
14977
                                         const bool add_prefix)
14978
    {
14979
        if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14980
        {
14981
            if (add_prefix)
14982
            {
14983
                oa->write_character(to_char_type('i'));  // int8
14984
            }
14985
            write_number(static_cast<std::uint8_t>(n));
14986
        }
14987
        else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14988
        {
14989
            if (add_prefix)
14990
            {
14991
                oa->write_character(to_char_type('U'));  // uint8
14992
            }
14993
            write_number(static_cast<std::uint8_t>(n));
14994
        }
14995
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14996
        {
14997
            if (add_prefix)
14998
            {
14999
                oa->write_character(to_char_type('I'));  // int16
15000
            }
15001
            write_number(static_cast<std::int16_t>(n));
15002
        }
15003
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15004
        {
15005
            if (add_prefix)
15006
            {
15007
                oa->write_character(to_char_type('l'));  // int32
15008
            }
15009
            write_number(static_cast<std::int32_t>(n));
15010
        }
15011
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15012
        {
15013
            if (add_prefix)
15014
            {
15015
                oa->write_character(to_char_type('L'));  // int64
15016
            }
15017
            write_number(static_cast<std::int64_t>(n));
15018
        }
15019
        else
15020
        {
15021
            if (add_prefix)
15022
            {
15023
                oa->write_character(to_char_type('H'));  // high-precision number
15024
            }
15025
15026
            const auto number = BasicJsonType(n).dump();
15027
            write_number_with_ubjson_prefix(number.size(), true);
15028
            for (std::size_t i = 0; i < number.size(); ++i)
15029
            {
15030
                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15031
            }
15032
        }
15033
    }
15034
15035
    // UBJSON: write number (signed integer)
15036
    template < typename NumberType, typename std::enable_if <
15037
                   std::is_signed<NumberType>::value&&
15038
                   !std::is_floating_point<NumberType>::value, int >::type = 0 >
15039
    void write_number_with_ubjson_prefix(const NumberType n,
15040
                                         const bool add_prefix)
15041
    {
15042
        if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15043
        {
15044
            if (add_prefix)
15045
            {
15046
                oa->write_character(to_char_type('i'));  // int8
15047
            }
15048
            write_number(static_cast<std::int8_t>(n));
15049
        }
15050
        else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
15051
        {
15052
            if (add_prefix)
15053
            {
15054
                oa->write_character(to_char_type('U'));  // uint8
15055
            }
15056
            write_number(static_cast<std::uint8_t>(n));
15057
        }
15058
        else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15059
        {
15060
            if (add_prefix)
15061
            {
15062
                oa->write_character(to_char_type('I'));  // int16
15063
            }
15064
            write_number(static_cast<std::int16_t>(n));
15065
        }
15066
        else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15067
        {
15068
            if (add_prefix)
15069
            {
15070
                oa->write_character(to_char_type('l'));  // int32
15071
            }
15072
            write_number(static_cast<std::int32_t>(n));
15073
        }
15074
        else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15075
        {
15076
            if (add_prefix)
15077
            {
15078
                oa->write_character(to_char_type('L'));  // int64
15079
            }
15080
            write_number(static_cast<std::int64_t>(n));
15081
        }
15082
        // LCOV_EXCL_START
15083
        else
15084
        {
15085
            if (add_prefix)
15086
            {
15087
                oa->write_character(to_char_type('H'));  // high-precision number
15088
            }
15089
15090
            const auto number = BasicJsonType(n).dump();
15091
            write_number_with_ubjson_prefix(number.size(), true);
15092
            for (std::size_t i = 0; i < number.size(); ++i)
15093
            {
15094
                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15095
            }
15096
        }
15097
        // LCOV_EXCL_STOP
15098
    }
15099
15100
    /*!
15101
    @brief determine the type prefix of container values
15102
    */
15103
    CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15104
    {
15105
        switch (j.type())
15106
        {
15107
            case value_t::null:
15108
                return 'Z';
15109
15110
            case value_t::boolean:
15111
                return j.m_value.boolean ? 'T' : 'F';
15112
15113
            case value_t::number_integer:
15114
            {
15115
                if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15116
                {
15117
                    return 'i';
15118
                }
15119
                if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15120
                {
15121
                    return 'U';
15122
                }
15123
                if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15124
                {
15125
                    return 'I';
15126
                }
15127
                if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15128
                {
15129
                    return 'l';
15130
                }
15131
                if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15132
                {
15133
                    return 'L';
15134
                }
15135
                // anything else is treated as high-precision number
15136
                return 'H'; // LCOV_EXCL_LINE
15137
            }
15138
15139
            case value_t::number_unsigned:
15140
            {
15141
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15142
                {
15143
                    return 'i';
15144
                }
15145
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15146
                {
15147
                    return 'U';
15148
                }
15149
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15150
                {
15151
                    return 'I';
15152
                }
15153
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15154
                {
15155
                    return 'l';
15156
                }
15157
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15158
                {
15159
                    return 'L';
15160
                }
15161
                // anything else is treated as high-precision number
15162
                return 'H'; // LCOV_EXCL_LINE
15163
            }
15164
15165
            case value_t::number_float:
15166
                return get_ubjson_float_prefix(j.m_value.number_float);
15167
15168
            case value_t::string:
15169
                return 'S';
15170
15171
            case value_t::array: // fallthrough
15172
            case value_t::binary:
15173
                return '[';
15174
15175
            case value_t::object:
15176
                return '{';
15177
15178
            case value_t::discarded:
15179
            default:  // discarded values
15180
                return 'N';
15181
        }
15182
    }
15183
15184
    static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15185
    {
15186
        return 'd';  // float 32
15187
    }
15188
15189
    static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15190
    {
15191
        return 'D';  // float 64
15192
    }
15193
15194
    ///////////////////////
15195
    // Utility functions //
15196
    ///////////////////////
15197
15198
    /*
15199
    @brief write a number to output input
15200
    @param[in] n number of type @a NumberType
15201
    @tparam NumberType the type of the number
15202
    @tparam OutputIsLittleEndian Set to true if output data is
15203
                                 required to be little endian
15204
15205
    @note This function needs to respect the system's endianess, because bytes
15206
          in CBOR, MessagePack, and UBJSON are stored in network order (big
15207
          endian) and therefore need reordering on little endian systems.
15208
    */
15209
    template<typename NumberType, bool OutputIsLittleEndian = false>
15210
    void write_number(const NumberType n)
15211
    {
15212
        // step 1: write number to array of length NumberType
15213
        std::array<CharType, sizeof(NumberType)> vec{};
15214
        std::memcpy(vec.data(), &n, sizeof(NumberType));
15215
15216
        // step 2: write array to output (with possible reordering)
15217
        if (is_little_endian != OutputIsLittleEndian)
15218
        {
15219
            // reverse byte order prior to conversion if necessary
15220
            std::reverse(vec.begin(), vec.end());
15221
        }
15222
15223
        oa->write_characters(vec.data(), sizeof(NumberType));
15224
    }
15225
15226
    void write_compact_float(const number_float_t n, detail::input_format_t format)
15227
    {
15228
#ifdef __GNUC__
15229
#pragma GCC diagnostic push
15230
#pragma GCC diagnostic ignored "-Wfloat-equal"
15231
#endif
15232
        if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15233
                static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15234
                static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15235
        {
15236
            oa->write_character(format == detail::input_format_t::cbor
15237
                                ? get_cbor_float_prefix(static_cast<float>(n))
15238
                                : get_msgpack_float_prefix(static_cast<float>(n)));
15239
            write_number(static_cast<float>(n));
15240
        }
15241
        else
15242
        {
15243
            oa->write_character(format == detail::input_format_t::cbor
15244
                                ? get_cbor_float_prefix(n)
15245
                                : get_msgpack_float_prefix(n));
15246
            write_number(n);
15247
        }
15248
#ifdef __GNUC__
15249
#pragma GCC diagnostic pop
15250
#endif
15251
    }
15252
15253
  public:
15254
    // The following to_char_type functions are implement the conversion
15255
    // between uint8_t and CharType. In case CharType is not unsigned,
15256
    // such a conversion is required to allow values greater than 128.
15257
    // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15258
    template < typename C = CharType,
15259
               enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15260
    static constexpr CharType to_char_type(std::uint8_t x) noexcept
15261
    {
15262
        return *reinterpret_cast<char*>(&x);
15263
    }
15264
15265
    template < typename C = CharType,
15266
               enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15267
    static CharType to_char_type(std::uint8_t x) noexcept
15268
    {
15269
        static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15270
        static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15271
        CharType result;
15272
        std::memcpy(&result, &x, sizeof(x));
15273
        return result;
15274
    }
15275
15276
    template<typename C = CharType,
15277
             enable_if_t<std::is_unsigned<C>::value>* = nullptr>
15278
    static constexpr CharType to_char_type(std::uint8_t x) noexcept
15279
    {
15280
        return x;
15281
    }
15282
15283
    template < typename InputCharType, typename C = CharType,
15284
               enable_if_t <
15285
                   std::is_signed<C>::value &&
15286
                   std::is_signed<char>::value &&
15287
                   std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15288
                   > * = nullptr >
15289
    static constexpr CharType to_char_type(InputCharType x) noexcept
15290
0
    {
15291
0
        return x;
15292
0
    }
15293
15294
  private:
15295
    /// whether we can assume little endianess
15296
    const bool is_little_endian = little_endianess();
15297
15298
    /// the output
15299
    output_adapter_t<CharType> oa = nullptr;
15300
};
15301
}  // namespace detail
15302
}  // namespace nlohmann
15303
15304
// #include <nlohmann/detail/output/output_adapters.hpp>
15305
15306
// #include <nlohmann/detail/output/serializer.hpp>
15307
15308
15309
#include <algorithm> // reverse, remove, fill, find, none_of
15310
#include <array> // array
15311
#include <clocale> // localeconv, lconv
15312
#include <cmath> // labs, isfinite, isnan, signbit
15313
#include <cstddef> // size_t, ptrdiff_t
15314
#include <cstdint> // uint8_t
15315
#include <cstdio> // snprintf
15316
#include <limits> // numeric_limits
15317
#include <string> // string, char_traits
15318
#include <type_traits> // is_same
15319
#include <utility> // move
15320
15321
// #include <nlohmann/detail/conversions/to_chars.hpp>
15322
15323
15324
#include <array> // array
15325
#include <cmath>   // signbit, isfinite
15326
#include <cstdint> // intN_t, uintN_t
15327
#include <cstring> // memcpy, memmove
15328
#include <limits> // numeric_limits
15329
#include <type_traits> // conditional
15330
15331
// #include <nlohmann/detail/macro_scope.hpp>
15332
15333
15334
namespace nlohmann
15335
{
15336
namespace detail
15337
{
15338
15339
/*!
15340
@brief implements the Grisu2 algorithm for binary to decimal floating-point
15341
conversion.
15342
15343
This implementation is a slightly modified version of the reference
15344
implementation which may be obtained from
15345
http://florian.loitsch.com/publications (bench.tar.gz).
15346
15347
The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
15348
15349
For a detailed description of the algorithm see:
15350
15351
[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
15352
    Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
15353
    Language Design and Implementation, PLDI 2010
15354
[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
15355
    Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
15356
    Design and Implementation, PLDI 1996
15357
*/
15358
namespace dtoa_impl
15359
{
15360
15361
template<typename Target, typename Source>
15362
Target reinterpret_bits(const Source source)
15363
0
{
15364
0
    static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15365
15366
0
    Target target;
15367
0
    std::memcpy(&target, &source, sizeof(Source));
15368
0
    return target;
15369
0
}
15370
15371
struct diyfp // f * 2^e
15372
{
15373
    static constexpr int kPrecision = 64; // = q
15374
15375
    std::uint64_t f = 0;
15376
    int e = 0;
15377
15378
0
    constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15379
15380
    /*!
15381
    @brief returns x - y
15382
    @pre x.e == y.e and x.f >= y.f
15383
    */
15384
    static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15385
0
    {
15386
0
        JSON_ASSERT(x.e == y.e);
15387
0
        JSON_ASSERT(x.f >= y.f);
15388
15389
0
        return {x.f - y.f, x.e};
15390
0
    }
15391
15392
    /*!
15393
    @brief returns x * y
15394
    @note The result is rounded. (Only the upper q bits are returned.)
15395
    */
15396
    static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15397
0
    {
15398
0
        static_assert(kPrecision == 64, "internal error");
15399
15400
        // Computes:
15401
        //  f = round((x.f * y.f) / 2^q)
15402
        //  e = x.e + y.e + q
15403
15404
        // Emulate the 64-bit * 64-bit multiplication:
15405
        //
15406
        // p = u * v
15407
        //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15408
        //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
15409
        //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
15410
        //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
15411
        //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
15412
        //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
15413
        //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
15414
        //
15415
        // (Since Q might be larger than 2^32 - 1)
15416
        //
15417
        //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15418
        //
15419
        // (Q_hi + H does not overflow a 64-bit int)
15420
        //
15421
        //   = p_lo + 2^64 p_hi
15422
15423
0
        const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15424
0
        const std::uint64_t u_hi = x.f >> 32u;
15425
0
        const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15426
0
        const std::uint64_t v_hi = y.f >> 32u;
15427
15428
0
        const std::uint64_t p0 = u_lo * v_lo;
15429
0
        const std::uint64_t p1 = u_lo * v_hi;
15430
0
        const std::uint64_t p2 = u_hi * v_lo;
15431
0
        const std::uint64_t p3 = u_hi * v_hi;
15432
15433
0
        const std::uint64_t p0_hi = p0 >> 32u;
15434
0
        const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15435
0
        const std::uint64_t p1_hi = p1 >> 32u;
15436
0
        const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15437
0
        const std::uint64_t p2_hi = p2 >> 32u;
15438
15439
0
        std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15440
15441
        // The full product might now be computed as
15442
        //
15443
        // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15444
        // p_lo = p0_lo + (Q << 32)
15445
        //
15446
        // But in this particular case here, the full p_lo is not required.
15447
        // Effectively we only need to add the highest bit in p_lo to p_hi (and
15448
        // Q_hi + 1 does not overflow).
15449
15450
0
        Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15451
15452
0
        const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15453
15454
0
        return {h, x.e + y.e + 64};
15455
0
    }
15456
15457
    /*!
15458
    @brief normalize x such that the significand is >= 2^(q-1)
15459
    @pre x.f != 0
15460
    */
15461
    static diyfp normalize(diyfp x) noexcept
15462
0
    {
15463
0
        JSON_ASSERT(x.f != 0);
15464
15465
0
        while ((x.f >> 63u) == 0)
15466
0
        {
15467
0
            x.f <<= 1u;
15468
0
            x.e--;
15469
0
        }
15470
15471
0
        return x;
15472
0
    }
15473
15474
    /*!
15475
    @brief normalize x such that the result has the exponent E
15476
    @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
15477
    */
15478
    static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15479
0
    {
15480
0
        const int delta = x.e - target_exponent;
15481
15482
0
        JSON_ASSERT(delta >= 0);
15483
0
        JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15484
15485
0
        return {x.f << delta, target_exponent};
15486
0
    }
15487
};
15488
15489
struct boundaries
15490
{
15491
    diyfp w;
15492
    diyfp minus;
15493
    diyfp plus;
15494
};
15495
15496
/*!
15497
Compute the (normalized) diyfp representing the input number 'value' and its
15498
boundaries.
15499
15500
@pre value must be finite and positive
15501
*/
15502
template<typename FloatType>
15503
boundaries compute_boundaries(FloatType value)
15504
0
{
15505
0
    JSON_ASSERT(std::isfinite(value));
15506
0
    JSON_ASSERT(value > 0);
15507
15508
    // Convert the IEEE representation into a diyfp.
15509
    //
15510
    // If v is denormal:
15511
    //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
15512
    // If v is normalized:
15513
    //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15514
15515
0
    static_assert(std::numeric_limits<FloatType>::is_iec559,
15516
0
                  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15517
15518
0
    constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15519
0
    constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15520
0
    constexpr int      kMinExp    = 1 - kBias;
15521
0
    constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15522
15523
0
    using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15524
15525
0
    const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15526
0
    const std::uint64_t E = bits >> (kPrecision - 1);
15527
0
    const std::uint64_t F = bits & (kHiddenBit - 1);
15528
15529
0
    const bool is_denormal = E == 0;
15530
0
    const diyfp v = is_denormal
15531
0
                    ? diyfp(F, kMinExp)
15532
0
                    : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15533
15534
    // Compute the boundaries m- and m+ of the floating-point value
15535
    // v = f * 2^e.
15536
    //
15537
    // Determine v- and v+, the floating-point predecessor and successor if v,
15538
    // respectively.
15539
    //
15540
    //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
15541
    //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
15542
    //
15543
    //      v+ = v + 2^e
15544
    //
15545
    // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15546
    // between m- and m+ round to v, regardless of how the input rounding
15547
    // algorithm breaks ties.
15548
    //
15549
    //      ---+-------------+-------------+-------------+-------------+---  (A)
15550
    //         v-            m-            v             m+            v+
15551
    //
15552
    //      -----------------+------+------+-------------+-------------+---  (B)
15553
    //                       v-     m-     v             m+            v+
15554
15555
0
    const bool lower_boundary_is_closer = F == 0 && E > 1;
15556
0
    const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15557
0
    const diyfp m_minus = lower_boundary_is_closer
15558
0
                          ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
15559
0
                          : diyfp(2 * v.f - 1, v.e - 1); // (A)
15560
15561
    // Determine the normalized w+ = m+.
15562
0
    const diyfp w_plus = diyfp::normalize(m_plus);
15563
15564
    // Determine w- = m- such that e_(w-) = e_(w+).
15565
0
    const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15566
15567
0
    return {diyfp::normalize(v), w_minus, w_plus};
15568
0
}
15569
15570
// Given normalized diyfp w, Grisu needs to find a (normalized) cached
15571
// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15572
// within a certain range [alpha, gamma] (Definition 3.2 from [1])
15573
//
15574
//      alpha <= e = e_c + e_w + q <= gamma
15575
//
15576
// or
15577
//
15578
//      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15579
//                          <= f_c * f_w * 2^gamma
15580
//
15581
// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15582
//
15583
//      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15584
//
15585
// or
15586
//
15587
//      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15588
//
15589
// The choice of (alpha,gamma) determines the size of the table and the form of
15590
// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15591
// in practice:
15592
//
15593
// The idea is to cut the number c * w = f * 2^e into two parts, which can be
15594
// processed independently: An integral part p1, and a fractional part p2:
15595
//
15596
//      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15597
//              = (f div 2^-e) + (f mod 2^-e) * 2^e
15598
//              = p1 + p2 * 2^e
15599
//
15600
// The conversion of p1 into decimal form requires a series of divisions and
15601
// modulos by (a power of) 10. These operations are faster for 32-bit than for
15602
// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15603
// achieved by choosing
15604
//
15605
//      -e >= 32   or   e <= -32 := gamma
15606
//
15607
// In order to convert the fractional part
15608
//
15609
//      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15610
//
15611
// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15612
// d[-i] are extracted in order:
15613
//
15614
//      (10 * p2) div 2^-e = d[-1]
15615
//      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15616
//
15617
// The multiplication by 10 must not overflow. It is sufficient to choose
15618
//
15619
//      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15620
//
15621
// Since p2 = f mod 2^-e < 2^-e,
15622
//
15623
//      -e <= 60   or   e >= -60 := alpha
15624
15625
constexpr int kAlpha = -60;
15626
constexpr int kGamma = -32;
15627
15628
struct cached_power // c = f * 2^e ~= 10^k
15629
{
15630
    std::uint64_t f;
15631
    int e;
15632
    int k;
15633
};
15634
15635
/*!
15636
For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
15637
power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
15638
satisfies (Definition 3.2 from [1])
15639
15640
     alpha <= e_c + e + q <= gamma.
15641
*/
15642
inline cached_power get_cached_power_for_binary_exponent(int e)
15643
0
{
15644
    // Now
15645
    //
15646
    //      alpha <= e_c + e + q <= gamma                                    (1)
15647
    //      ==> f_c * 2^alpha <= c * 2^e * 2^q
15648
    //
15649
    // and since the c's are normalized, 2^(q-1) <= f_c,
15650
    //
15651
    //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15652
    //      ==> 2^(alpha - e - 1) <= c
15653
    //
15654
    // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15655
    //
15656
    //      k = ceil( log_10( 2^(alpha - e - 1) ) )
15657
    //        = ceil( (alpha - e - 1) * log_10(2) )
15658
    //
15659
    // From the paper:
15660
    // "In theory the result of the procedure could be wrong since c is rounded,
15661
    //  and the computation itself is approximated [...]. In practice, however,
15662
    //  this simple function is sufficient."
15663
    //
15664
    // For IEEE double precision floating-point numbers converted into
15665
    // normalized diyfp's w = f * 2^e, with q = 64,
15666
    //
15667
    //      e >= -1022      (min IEEE exponent)
15668
    //           -52        (p - 1)
15669
    //           -52        (p - 1, possibly normalize denormal IEEE numbers)
15670
    //           -11        (normalize the diyfp)
15671
    //         = -1137
15672
    //
15673
    // and
15674
    //
15675
    //      e <= +1023      (max IEEE exponent)
15676
    //           -52        (p - 1)
15677
    //           -11        (normalize the diyfp)
15678
    //         = 960
15679
    //
15680
    // This binary exponent range [-1137,960] results in a decimal exponent
15681
    // range [-307,324]. One does not need to store a cached power for each
15682
    // k in this range. For each such k it suffices to find a cached power
15683
    // such that the exponent of the product lies in [alpha,gamma].
15684
    // This implies that the difference of the decimal exponents of adjacent
15685
    // table entries must be less than or equal to
15686
    //
15687
    //      floor( (gamma - alpha) * log_10(2) ) = 8.
15688
    //
15689
    // (A smaller distance gamma-alpha would require a larger table.)
15690
15691
    // NB:
15692
    // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15693
15694
0
    constexpr int kCachedPowersMinDecExp = -300;
15695
0
    constexpr int kCachedPowersDecStep = 8;
15696
15697
0
    static constexpr std::array<cached_power, 79> kCachedPowers =
15698
0
    {
15699
0
        {
15700
0
            { 0xAB70FE17C79AC6CA, -1060, -300 },
15701
0
            { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15702
0
            { 0xBE5691EF416BD60C, -1007, -284 },
15703
0
            { 0x8DD01FAD907FFC3C,  -980, -276 },
15704
0
            { 0xD3515C2831559A83,  -954, -268 },
15705
0
            { 0x9D71AC8FADA6C9B5,  -927, -260 },
15706
0
            { 0xEA9C227723EE8BCB,  -901, -252 },
15707
0
            { 0xAECC49914078536D,  -874, -244 },
15708
0
            { 0x823C12795DB6CE57,  -847, -236 },
15709
0
            { 0xC21094364DFB5637,  -821, -228 },
15710
0
            { 0x9096EA6F3848984F,  -794, -220 },
15711
0
            { 0xD77485CB25823AC7,  -768, -212 },
15712
0
            { 0xA086CFCD97BF97F4,  -741, -204 },
15713
0
            { 0xEF340A98172AACE5,  -715, -196 },
15714
0
            { 0xB23867FB2A35B28E,  -688, -188 },
15715
0
            { 0x84C8D4DFD2C63F3B,  -661, -180 },
15716
0
            { 0xC5DD44271AD3CDBA,  -635, -172 },
15717
0
            { 0x936B9FCEBB25C996,  -608, -164 },
15718
0
            { 0xDBAC6C247D62A584,  -582, -156 },
15719
0
            { 0xA3AB66580D5FDAF6,  -555, -148 },
15720
0
            { 0xF3E2F893DEC3F126,  -529, -140 },
15721
0
            { 0xB5B5ADA8AAFF80B8,  -502, -132 },
15722
0
            { 0x87625F056C7C4A8B,  -475, -124 },
15723
0
            { 0xC9BCFF6034C13053,  -449, -116 },
15724
0
            { 0x964E858C91BA2655,  -422, -108 },
15725
0
            { 0xDFF9772470297EBD,  -396, -100 },
15726
0
            { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
15727
0
            { 0xF8A95FCF88747D94,  -343,  -84 },
15728
0
            { 0xB94470938FA89BCF,  -316,  -76 },
15729
0
            { 0x8A08F0F8BF0F156B,  -289,  -68 },
15730
0
            { 0xCDB02555653131B6,  -263,  -60 },
15731
0
            { 0x993FE2C6D07B7FAC,  -236,  -52 },
15732
0
            { 0xE45C10C42A2B3B06,  -210,  -44 },
15733
0
            { 0xAA242499697392D3,  -183,  -36 },
15734
0
            { 0xFD87B5F28300CA0E,  -157,  -28 },
15735
0
            { 0xBCE5086492111AEB,  -130,  -20 },
15736
0
            { 0x8CBCCC096F5088CC,  -103,  -12 },
15737
0
            { 0xD1B71758E219652C,   -77,   -4 },
15738
0
            { 0x9C40000000000000,   -50,    4 },
15739
0
            { 0xE8D4A51000000000,   -24,   12 },
15740
0
            { 0xAD78EBC5AC620000,     3,   20 },
15741
0
            { 0x813F3978F8940984,    30,   28 },
15742
0
            { 0xC097CE7BC90715B3,    56,   36 },
15743
0
            { 0x8F7E32CE7BEA5C70,    83,   44 },
15744
0
            { 0xD5D238A4ABE98068,   109,   52 },
15745
0
            { 0x9F4F2726179A2245,   136,   60 },
15746
0
            { 0xED63A231D4C4FB27,   162,   68 },
15747
0
            { 0xB0DE65388CC8ADA8,   189,   76 },
15748
0
            { 0x83C7088E1AAB65DB,   216,   84 },
15749
0
            { 0xC45D1DF942711D9A,   242,   92 },
15750
0
            { 0x924D692CA61BE758,   269,  100 },
15751
0
            { 0xDA01EE641A708DEA,   295,  108 },
15752
0
            { 0xA26DA3999AEF774A,   322,  116 },
15753
0
            { 0xF209787BB47D6B85,   348,  124 },
15754
0
            { 0xB454E4A179DD1877,   375,  132 },
15755
0
            { 0x865B86925B9BC5C2,   402,  140 },
15756
0
            { 0xC83553C5C8965D3D,   428,  148 },
15757
0
            { 0x952AB45CFA97A0B3,   455,  156 },
15758
0
            { 0xDE469FBD99A05FE3,   481,  164 },
15759
0
            { 0xA59BC234DB398C25,   508,  172 },
15760
0
            { 0xF6C69A72A3989F5C,   534,  180 },
15761
0
            { 0xB7DCBF5354E9BECE,   561,  188 },
15762
0
            { 0x88FCF317F22241E2,   588,  196 },
15763
0
            { 0xCC20CE9BD35C78A5,   614,  204 },
15764
0
            { 0x98165AF37B2153DF,   641,  212 },
15765
0
            { 0xE2A0B5DC971F303A,   667,  220 },
15766
0
            { 0xA8D9D1535CE3B396,   694,  228 },
15767
0
            { 0xFB9B7CD9A4A7443C,   720,  236 },
15768
0
            { 0xBB764C4CA7A44410,   747,  244 },
15769
0
            { 0x8BAB8EEFB6409C1A,   774,  252 },
15770
0
            { 0xD01FEF10A657842C,   800,  260 },
15771
0
            { 0x9B10A4E5E9913129,   827,  268 },
15772
0
            { 0xE7109BFBA19C0C9D,   853,  276 },
15773
0
            { 0xAC2820D9623BF429,   880,  284 },
15774
0
            { 0x80444B5E7AA7CF85,   907,  292 },
15775
0
            { 0xBF21E44003ACDD2D,   933,  300 },
15776
0
            { 0x8E679C2F5E44FF8F,   960,  308 },
15777
0
            { 0xD433179D9C8CB841,   986,  316 },
15778
0
            { 0x9E19DB92B4E31BA9,  1013,  324 },
15779
0
        }
15780
0
    };
15781
15782
    // This computation gives exactly the same results for k as
15783
    //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15784
    // for |e| <= 1500, but doesn't require floating-point operations.
15785
    // NB: log_10(2) ~= 78913 / 2^18
15786
0
    JSON_ASSERT(e >= -1500);
15787
0
    JSON_ASSERT(e <=  1500);
15788
0
    const int f = kAlpha - e - 1;
15789
0
    const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15790
15791
0
    const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15792
0
    JSON_ASSERT(index >= 0);
15793
0
    JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15794
15795
0
    const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15796
0
    JSON_ASSERT(kAlpha <= cached.e + e + 64);
15797
0
    JSON_ASSERT(kGamma >= cached.e + e + 64);
15798
15799
0
    return cached;
15800
0
}
15801
15802
/*!
15803
For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
15804
For n == 0, returns 1 and sets pow10 := 1.
15805
*/
15806
inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15807
0
{
15808
    // LCOV_EXCL_START
15809
0
    if (n >= 1000000000)
15810
0
    {
15811
0
        pow10 = 1000000000;
15812
0
        return 10;
15813
0
    }
15814
    // LCOV_EXCL_STOP
15815
0
    if (n >= 100000000)
15816
0
    {
15817
0
        pow10 = 100000000;
15818
0
        return  9;
15819
0
    }
15820
0
    if (n >= 10000000)
15821
0
    {
15822
0
        pow10 = 10000000;
15823
0
        return  8;
15824
0
    }
15825
0
    if (n >= 1000000)
15826
0
    {
15827
0
        pow10 = 1000000;
15828
0
        return  7;
15829
0
    }
15830
0
    if (n >= 100000)
15831
0
    {
15832
0
        pow10 = 100000;
15833
0
        return  6;
15834
0
    }
15835
0
    if (n >= 10000)
15836
0
    {
15837
0
        pow10 = 10000;
15838
0
        return  5;
15839
0
    }
15840
0
    if (n >= 1000)
15841
0
    {
15842
0
        pow10 = 1000;
15843
0
        return  4;
15844
0
    }
15845
0
    if (n >= 100)
15846
0
    {
15847
0
        pow10 = 100;
15848
0
        return  3;
15849
0
    }
15850
0
    if (n >= 10)
15851
0
    {
15852
0
        pow10 = 10;
15853
0
        return  2;
15854
0
    }
15855
15856
0
    pow10 = 1;
15857
0
    return 1;
15858
0
}
15859
15860
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15861
                         std::uint64_t rest, std::uint64_t ten_k)
15862
0
{
15863
0
    JSON_ASSERT(len >= 1);
15864
0
    JSON_ASSERT(dist <= delta);
15865
0
    JSON_ASSERT(rest <= delta);
15866
0
    JSON_ASSERT(ten_k > 0);
15867
15868
    //               <--------------------------- delta ---->
15869
    //                                  <---- dist --------->
15870
    // --------------[------------------+-------------------]--------------
15871
    //               M-                 w                   M+
15872
    //
15873
    //                                  ten_k
15874
    //                                <------>
15875
    //                                       <---- rest ---->
15876
    // --------------[------------------+----+--------------]--------------
15877
    //                                  w    V
15878
    //                                       = buf * 10^k
15879
    //
15880
    // ten_k represents a unit-in-the-last-place in the decimal representation
15881
    // stored in buf.
15882
    // Decrement buf by ten_k while this takes buf closer to w.
15883
15884
    // The tests are written in this order to avoid overflow in unsigned
15885
    // integer arithmetic.
15886
15887
0
    while (rest < dist
15888
0
            && delta - rest >= ten_k
15889
0
            && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15890
0
    {
15891
0
        JSON_ASSERT(buf[len - 1] != '0');
15892
0
        buf[len - 1]--;
15893
0
        rest += ten_k;
15894
0
    }
15895
0
}
15896
15897
/*!
15898
Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
15899
M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
15900
*/
15901
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15902
                             diyfp M_minus, diyfp w, diyfp M_plus)
15903
0
{
15904
0
    static_assert(kAlpha >= -60, "internal error");
15905
0
    static_assert(kGamma <= -32, "internal error");
15906
15907
    // Generates the digits (and the exponent) of a decimal floating-point
15908
    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15909
    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15910
    //
15911
    //               <--------------------------- delta ---->
15912
    //                                  <---- dist --------->
15913
    // --------------[------------------+-------------------]--------------
15914
    //               M-                 w                   M+
15915
    //
15916
    // Grisu2 generates the digits of M+ from left to right and stops as soon as
15917
    // V is in [M-,M+].
15918
15919
0
    JSON_ASSERT(M_plus.e >= kAlpha);
15920
0
    JSON_ASSERT(M_plus.e <= kGamma);
15921
15922
0
    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15923
0
    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
15924
15925
    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15926
    //
15927
    //      M+ = f * 2^e
15928
    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15929
    //         = ((p1        ) * 2^-e + (p2        )) * 2^e
15930
    //         = p1 + p2 * 2^e
15931
15932
0
    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15933
15934
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.)
15935
0
    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
15936
15937
    // 1)
15938
    //
15939
    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15940
15941
0
    JSON_ASSERT(p1 > 0);
15942
15943
0
    std::uint32_t pow10{};
15944
0
    const int k = find_largest_pow10(p1, pow10);
15945
15946
    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15947
    //
15948
    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15949
    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
15950
    //
15951
    //      M+ = p1                                             + p2 * 2^e
15952
    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
15953
    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15954
    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
15955
    //
15956
    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15957
    //
15958
    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15959
    //
15960
    // but stop as soon as
15961
    //
15962
    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15963
15964
0
    int n = k;
15965
0
    while (n > 0)
15966
0
    {
15967
        // Invariants:
15968
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
15969
        //      pow10 = 10^(n-1) <= p1 < 10^n
15970
        //
15971
0
        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
15972
0
        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
15973
        //
15974
        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15975
        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15976
        //
15977
0
        JSON_ASSERT(d <= 9);
15978
0
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15979
        //
15980
        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15981
        //
15982
0
        p1 = r;
15983
0
        n--;
15984
        //
15985
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
15986
        //      pow10 = 10^n
15987
        //
15988
15989
        // Now check if enough digits have been generated.
15990
        // Compute
15991
        //
15992
        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15993
        //
15994
        // Note:
15995
        // Since rest and delta share the same exponent e, it suffices to
15996
        // compare the significands.
15997
0
        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15998
0
        if (rest <= delta)
15999
0
        {
16000
            // V = buffer * 10^n, with M- <= V <= M+.
16001
16002
0
            decimal_exponent += n;
16003
16004
            // We may now just stop. But instead look if the buffer could be
16005
            // decremented to bring V closer to w.
16006
            //
16007
            // pow10 = 10^n is now 1 ulp in the decimal representation V.
16008
            // The rounding procedure works with diyfp's with an implicit
16009
            // exponent of e.
16010
            //
16011
            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16012
            //
16013
0
            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16014
0
            grisu2_round(buffer, length, dist, delta, rest, ten_n);
16015
16016
0
            return;
16017
0
        }
16018
16019
0
        pow10 /= 10;
16020
        //
16021
        //      pow10 = 10^(n-1) <= p1 < 10^n
16022
        // Invariants restored.
16023
0
    }
16024
16025
    // 2)
16026
    //
16027
    // The digits of the integral part have been generated:
16028
    //
16029
    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16030
    //         = buffer            + p2 * 2^e
16031
    //
16032
    // Now generate the digits of the fractional part p2 * 2^e.
16033
    //
16034
    // Note:
16035
    // No decimal point is generated: the exponent is adjusted instead.
16036
    //
16037
    // p2 actually represents the fraction
16038
    //
16039
    //      p2 * 2^e
16040
    //          = p2 / 2^-e
16041
    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
16042
    //
16043
    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16044
    //
16045
    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16046
    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16047
    //
16048
    // using
16049
    //
16050
    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16051
    //                = (                   d) * 2^-e + (                   r)
16052
    //
16053
    // or
16054
    //      10^m * p2 * 2^e = d + r * 2^e
16055
    //
16056
    // i.e.
16057
    //
16058
    //      M+ = buffer + p2 * 2^e
16059
    //         = buffer + 10^-m * (d + r * 2^e)
16060
    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16061
    //
16062
    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16063
16064
0
    JSON_ASSERT(p2 > delta);
16065
16066
0
    int m = 0;
16067
0
    for (;;)
16068
0
    {
16069
        // Invariant:
16070
        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16071
        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
16072
        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
16073
        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16074
        //
16075
0
        JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16076
0
        p2 *= 10;
16077
0
        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
16078
0
        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16079
        //
16080
        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16081
        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16082
        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16083
        //
16084
0
        JSON_ASSERT(d <= 9);
16085
0
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16086
        //
16087
        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16088
        //
16089
0
        p2 = r;
16090
0
        m++;
16091
        //
16092
        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16093
        // Invariant restored.
16094
16095
        // Check if enough digits have been generated.
16096
        //
16097
        //      10^-m * p2 * 2^e <= delta * 2^e
16098
        //              p2 * 2^e <= 10^m * delta * 2^e
16099
        //                    p2 <= 10^m * delta
16100
0
        delta *= 10;
16101
0
        dist  *= 10;
16102
0
        if (p2 <= delta)
16103
0
        {
16104
0
            break;
16105
0
        }
16106
0
    }
16107
16108
    // V = buffer * 10^-m, with M- <= V <= M+.
16109
16110
0
    decimal_exponent -= m;
16111
16112
    // 1 ulp in the decimal representation is now 10^-m.
16113
    // Since delta and dist are now scaled by 10^m, we need to do the
16114
    // same with ulp in order to keep the units in sync.
16115
    //
16116
    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16117
    //
16118
0
    const std::uint64_t ten_m = one.f;
16119
0
    grisu2_round(buffer, length, dist, delta, p2, ten_m);
16120
16121
    // By construction this algorithm generates the shortest possible decimal
16122
    // number (Loitsch, Theorem 6.2) which rounds back to w.
16123
    // For an input number of precision p, at least
16124
    //
16125
    //      N = 1 + ceil(p * log_10(2))
16126
    //
16127
    // decimal digits are sufficient to identify all binary floating-point
16128
    // numbers (Matula, "In-and-Out conversions").
16129
    // This implies that the algorithm does not produce more than N decimal
16130
    // digits.
16131
    //
16132
    //      N = 17 for p = 53 (IEEE double precision)
16133
    //      N = 9  for p = 24 (IEEE single precision)
16134
0
}
16135
16136
/*!
16137
v = buf * 10^decimal_exponent
16138
len is the length of the buffer (number of decimal digits)
16139
The buffer must be large enough, i.e. >= max_digits10.
16140
*/
16141
JSON_HEDLEY_NON_NULL(1)
16142
inline void grisu2(char* buf, int& len, int& decimal_exponent,
16143
                   diyfp m_minus, diyfp v, diyfp m_plus)
16144
0
{
16145
0
    JSON_ASSERT(m_plus.e == m_minus.e);
16146
0
    JSON_ASSERT(m_plus.e == v.e);
16147
16148
    //  --------(-----------------------+-----------------------)--------    (A)
16149
    //          m-                      v                       m+
16150
    //
16151
    //  --------------------(-----------+-----------------------)--------    (B)
16152
    //                      m-          v                       m+
16153
    //
16154
    // First scale v (and m- and m+) such that the exponent is in the range
16155
    // [alpha, gamma].
16156
16157
0
    const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16158
16159
0
    const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16160
16161
    // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16162
0
    const diyfp w       = diyfp::mul(v,       c_minus_k);
16163
0
    const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16164
0
    const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
16165
16166
    //  ----(---+---)---------------(---+---)---------------(---+---)----
16167
    //          w-                      w                       w+
16168
    //          = c*m-                  = c*v                   = c*m+
16169
    //
16170
    // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16171
    // w+ are now off by a small amount.
16172
    // In fact:
16173
    //
16174
    //      w - v * 10^k < 1 ulp
16175
    //
16176
    // To account for this inaccuracy, add resp. subtract 1 ulp.
16177
    //
16178
    //  --------+---[---------------(---+---)---------------]---+--------
16179
    //          w-  M-                  w                   M+  w+
16180
    //
16181
    // Now any number in [M-, M+] (bounds included) will round to w when input,
16182
    // regardless of how the input rounding algorithm breaks ties.
16183
    //
16184
    // And digit_gen generates the shortest possible such number in [M-, M+].
16185
    // Note that this does not mean that Grisu2 always generates the shortest
16186
    // possible number in the interval (m-, m+).
16187
0
    const diyfp M_minus(w_minus.f + 1, w_minus.e);
16188
0
    const diyfp M_plus (w_plus.f  - 1, w_plus.e );
16189
16190
0
    decimal_exponent = -cached.k; // = -(-k) = k
16191
16192
0
    grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16193
0
}
16194
16195
/*!
16196
v = buf * 10^decimal_exponent
16197
len is the length of the buffer (number of decimal digits)
16198
The buffer must be large enough, i.e. >= max_digits10.
16199
*/
16200
template<typename FloatType>
16201
JSON_HEDLEY_NON_NULL(1)
16202
void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16203
0
{
16204
0
    static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16205
0
                  "internal error: not enough precision");
16206
16207
0
    JSON_ASSERT(std::isfinite(value));
16208
0
    JSON_ASSERT(value > 0);
16209
16210
    // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16211
    // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16212
    // decimal representations are not exactly "short".
16213
    //
16214
    // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16215
    // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16216
    // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16217
    // does.
16218
    // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16219
    // representation using the corresponding std::from_chars function recovers value exactly". That
16220
    // indicates that single precision floating-point numbers should be recovered using
16221
    // 'std::strtof'.
16222
    //
16223
    // NB: If the neighbors are computed for single-precision numbers, there is a single float
16224
    //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16225
    //     value is off by 1 ulp.
16226
#if 0
16227
    const boundaries w = compute_boundaries(static_cast<double>(value));
16228
#else
16229
0
    const boundaries w = compute_boundaries(value);
16230
0
#endif
16231
16232
0
    grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16233
0
}
16234
16235
/*!
16236
@brief appends a decimal representation of e to buf
16237
@return a pointer to the element following the exponent.
16238
@pre -1000 < e < 1000
16239
*/
16240
JSON_HEDLEY_NON_NULL(1)
16241
JSON_HEDLEY_RETURNS_NON_NULL
16242
inline char* append_exponent(char* buf, int e)
16243
0
{
16244
0
    JSON_ASSERT(e > -1000);
16245
0
    JSON_ASSERT(e <  1000);
16246
16247
0
    if (e < 0)
16248
0
    {
16249
0
        e = -e;
16250
0
        *buf++ = '-';
16251
0
    }
16252
0
    else
16253
0
    {
16254
0
        *buf++ = '+';
16255
0
    }
16256
16257
0
    auto k = static_cast<std::uint32_t>(e);
16258
0
    if (k < 10)
16259
0
    {
16260
        // Always print at least two digits in the exponent.
16261
        // This is for compatibility with printf("%g").
16262
0
        *buf++ = '0';
16263
0
        *buf++ = static_cast<char>('0' + k);
16264
0
    }
16265
0
    else if (k < 100)
16266
0
    {
16267
0
        *buf++ = static_cast<char>('0' + k / 10);
16268
0
        k %= 10;
16269
0
        *buf++ = static_cast<char>('0' + k);
16270
0
    }
16271
0
    else
16272
0
    {
16273
0
        *buf++ = static_cast<char>('0' + k / 100);
16274
0
        k %= 100;
16275
0
        *buf++ = static_cast<char>('0' + k / 10);
16276
0
        k %= 10;
16277
0
        *buf++ = static_cast<char>('0' + k);
16278
0
    }
16279
16280
0
    return buf;
16281
0
}
16282
16283
/*!
16284
@brief prettify v = buf * 10^decimal_exponent
16285
16286
If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
16287
notation. Otherwise it will be printed in exponential notation.
16288
16289
@pre min_exp < 0
16290
@pre max_exp > 0
16291
*/
16292
JSON_HEDLEY_NON_NULL(1)
16293
JSON_HEDLEY_RETURNS_NON_NULL
16294
inline char* format_buffer(char* buf, int len, int decimal_exponent,
16295
                           int min_exp, int max_exp)
16296
0
{
16297
0
    JSON_ASSERT(min_exp < 0);
16298
0
    JSON_ASSERT(max_exp > 0);
16299
16300
0
    const int k = len;
16301
0
    const int n = len + decimal_exponent;
16302
16303
    // v = buf * 10^(n-k)
16304
    // k is the length of the buffer (number of decimal digits)
16305
    // n is the position of the decimal point relative to the start of the buffer.
16306
16307
0
    if (k <= n && n <= max_exp)
16308
0
    {
16309
        // digits[000]
16310
        // len <= max_exp + 2
16311
16312
0
        std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16313
        // Make it look like a floating-point number (#362, #378)
16314
0
        buf[n + 0] = '.';
16315
0
        buf[n + 1] = '0';
16316
0
        return buf + (static_cast<size_t>(n) + 2);
16317
0
    }
16318
16319
0
    if (0 < n && n <= max_exp)
16320
0
    {
16321
        // dig.its
16322
        // len <= max_digits10 + 1
16323
16324
0
        JSON_ASSERT(k > n);
16325
16326
0
        std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16327
0
        buf[n] = '.';
16328
0
        return buf + (static_cast<size_t>(k) + 1U);
16329
0
    }
16330
16331
0
    if (min_exp < n && n <= 0)
16332
0
    {
16333
        // 0.[000]digits
16334
        // len <= 2 + (-min_exp - 1) + max_digits10
16335
16336
0
        std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16337
0
        buf[0] = '0';
16338
0
        buf[1] = '.';
16339
0
        std::memset(buf + 2, '0', static_cast<size_t>(-n));
16340
0
        return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16341
0
    }
16342
16343
0
    if (k == 1)
16344
0
    {
16345
        // dE+123
16346
        // len <= 1 + 5
16347
16348
0
        buf += 1;
16349
0
    }
16350
0
    else
16351
0
    {
16352
        // d.igitsE+123
16353
        // len <= max_digits10 + 1 + 5
16354
16355
0
        std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16356
0
        buf[1] = '.';
16357
0
        buf += 1 + static_cast<size_t>(k);
16358
0
    }
16359
16360
0
    *buf++ = 'e';
16361
0
    return append_exponent(buf, n - 1);
16362
0
}
16363
16364
} // namespace dtoa_impl
16365
16366
/*!
16367
@brief generates a decimal representation of the floating-point number value in [first, last).
16368
16369
The format of the resulting decimal representation is similar to printf's %g
16370
format. Returns an iterator pointing past-the-end of the decimal representation.
16371
16372
@note The input number must be finite, i.e. NaN's and Inf's are not supported.
16373
@note The buffer must be large enough.
16374
@note The result is NOT null-terminated.
16375
*/
16376
template<typename FloatType>
16377
JSON_HEDLEY_NON_NULL(1, 2)
16378
JSON_HEDLEY_RETURNS_NON_NULL
16379
char* to_chars(char* first, const char* last, FloatType value)
16380
0
{
16381
0
    static_cast<void>(last); // maybe unused - fix warning
16382
0
    JSON_ASSERT(std::isfinite(value));
16383
16384
    // Use signbit(value) instead of (value < 0) since signbit works for -0.
16385
0
    if (std::signbit(value))
16386
0
    {
16387
0
        value = -value;
16388
0
        *first++ = '-';
16389
0
    }
16390
16391
0
#ifdef __GNUC__
16392
0
#pragma GCC diagnostic push
16393
0
#pragma GCC diagnostic ignored "-Wfloat-equal"
16394
0
#endif
16395
0
    if (value == 0) // +-0
16396
0
    {
16397
0
        *first++ = '0';
16398
        // Make it look like a floating-point number (#362, #378)
16399
0
        *first++ = '.';
16400
0
        *first++ = '0';
16401
0
        return first;
16402
0
    }
16403
0
#ifdef __GNUC__
16404
0
#pragma GCC diagnostic pop
16405
0
#endif
16406
16407
0
    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16408
16409
    // Compute v = buffer * 10^decimal_exponent.
16410
    // The decimal digits are stored in the buffer, which needs to be interpreted
16411
    // as an unsigned decimal integer.
16412
    // len is the length of the buffer, i.e. the number of decimal digits.
16413
0
    int len = 0;
16414
0
    int decimal_exponent = 0;
16415
0
    dtoa_impl::grisu2(first, len, decimal_exponent, value);
16416
16417
0
    JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16418
16419
    // Format the buffer like printf("%.*g", prec, value)
16420
0
    constexpr int kMinExp = -4;
16421
    // Use digits10 here to increase compatibility with version 2.
16422
0
    constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16423
16424
0
    JSON_ASSERT(last - first >= kMaxExp + 2);
16425
0
    JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16426
0
    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16427
16428
0
    return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16429
0
}
16430
16431
} // namespace detail
16432
} // namespace nlohmann
16433
16434
// #include <nlohmann/detail/exceptions.hpp>
16435
16436
// #include <nlohmann/detail/macro_scope.hpp>
16437
16438
// #include <nlohmann/detail/meta/cpp_future.hpp>
16439
16440
// #include <nlohmann/detail/output/binary_writer.hpp>
16441
16442
// #include <nlohmann/detail/output/output_adapters.hpp>
16443
16444
// #include <nlohmann/detail/value_t.hpp>
16445
16446
16447
namespace nlohmann
16448
{
16449
namespace detail
16450
{
16451
///////////////////
16452
// serialization //
16453
///////////////////
16454
16455
/// how to treat decoding errors
16456
enum class error_handler_t
16457
{
16458
    strict,  ///< throw a type_error exception in case of invalid UTF-8
16459
    replace, ///< replace invalid UTF-8 sequences with U+FFFD
16460
    ignore   ///< ignore invalid UTF-8 sequences
16461
};
16462
16463
template<typename BasicJsonType>
16464
class serializer
16465
{
16466
    using string_t = typename BasicJsonType::string_t;
16467
    using number_float_t = typename BasicJsonType::number_float_t;
16468
    using number_integer_t = typename BasicJsonType::number_integer_t;
16469
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16470
    using binary_char_t = typename BasicJsonType::binary_t::value_type;
16471
    static constexpr std::uint8_t UTF8_ACCEPT = 0;
16472
    static constexpr std::uint8_t UTF8_REJECT = 1;
16473
16474
  public:
16475
    /*!
16476
    @param[in] s  output stream to serialize to
16477
    @param[in] ichar  indentation character to use
16478
    @param[in] error_handler_  how to react on decoding errors
16479
    */
16480
    serializer(output_adapter_t<char> s, const char ichar,
16481
               error_handler_t error_handler_ = error_handler_t::strict)
16482
        : o(std::move(s))
16483
        , loc(std::localeconv())
16484
        , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16485
        , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16486
        , indent_char(ichar)
16487
        , indent_string(512, indent_char)
16488
        , error_handler(error_handler_)
16489
0
    {}
16490
16491
    // delete because of pointer members
16492
    serializer(const serializer&) = delete;
16493
    serializer& operator=(const serializer&) = delete;
16494
    serializer(serializer&&) = delete;
16495
    serializer& operator=(serializer&&) = delete;
16496
0
    ~serializer() = default;
16497
16498
    /*!
16499
    @brief internal implementation of the serialization function
16500
16501
    This function is called by the public member function dump and organizes
16502
    the serialization internally. The indentation level is propagated as
16503
    additional parameter. In case of arrays and objects, the function is
16504
    called recursively.
16505
16506
    - strings and object keys are escaped using `escape_string()`
16507
    - integer numbers are converted implicitly via `operator<<`
16508
    - floating-point numbers are converted to a string using `"%g"` format
16509
    - binary values are serialized as objects containing the subtype and the
16510
      byte array
16511
16512
    @param[in] val               value to serialize
16513
    @param[in] pretty_print      whether the output shall be pretty-printed
16514
    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
16515
    in the output are escaped with `\uXXXX` sequences, and the result consists
16516
    of ASCII characters only.
16517
    @param[in] indent_step       the indent level
16518
    @param[in] current_indent    the current indent level (only used internally)
16519
    */
16520
    void dump(const BasicJsonType& val,
16521
              const bool pretty_print,
16522
              const bool ensure_ascii,
16523
              const unsigned int indent_step,
16524
              const unsigned int current_indent = 0)
16525
0
    {
16526
0
        switch (val.m_type)
16527
0
        {
16528
0
            case value_t::object:
16529
0
            {
16530
0
                if (val.m_value.object->empty())
16531
0
                {
16532
0
                    o->write_characters("{}", 2);
16533
0
                    return;
16534
0
                }
16535
16536
0
                if (pretty_print)
16537
0
                {
16538
0
                    o->write_characters("{\n", 2);
16539
16540
                    // variable to hold indentation for recursive calls
16541
0
                    const auto new_indent = current_indent + indent_step;
16542
0
                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16543
0
                    {
16544
0
                        indent_string.resize(indent_string.size() * 2, ' ');
16545
0
                    }
16546
16547
                    // first n-1 elements
16548
0
                    auto i = val.m_value.object->cbegin();
16549
0
                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16550
0
                    {
16551
0
                        o->write_characters(indent_string.c_str(), new_indent);
16552
0
                        o->write_character('\"');
16553
0
                        dump_escaped(i->first, ensure_ascii);
16554
0
                        o->write_characters("\": ", 3);
16555
0
                        dump(i->second, true, ensure_ascii, indent_step, new_indent);
16556
0
                        o->write_characters(",\n", 2);
16557
0
                    }
16558
16559
                    // last element
16560
0
                    JSON_ASSERT(i != val.m_value.object->cend());
16561
0
                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16562
0
                    o->write_characters(indent_string.c_str(), new_indent);
16563
0
                    o->write_character('\"');
16564
0
                    dump_escaped(i->first, ensure_ascii);
16565
0
                    o->write_characters("\": ", 3);
16566
0
                    dump(i->second, true, ensure_ascii, indent_step, new_indent);
16567
16568
0
                    o->write_character('\n');
16569
0
                    o->write_characters(indent_string.c_str(), current_indent);
16570
0
                    o->write_character('}');
16571
0
                }
16572
0
                else
16573
0
                {
16574
0
                    o->write_character('{');
16575
16576
                    // first n-1 elements
16577
0
                    auto i = val.m_value.object->cbegin();
16578
0
                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16579
0
                    {
16580
0
                        o->write_character('\"');
16581
0
                        dump_escaped(i->first, ensure_ascii);
16582
0
                        o->write_characters("\":", 2);
16583
0
                        dump(i->second, false, ensure_ascii, indent_step, current_indent);
16584
0
                        o->write_character(',');
16585
0
                    }
16586
16587
                    // last element
16588
0
                    JSON_ASSERT(i != val.m_value.object->cend());
16589
0
                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16590
0
                    o->write_character('\"');
16591
0
                    dump_escaped(i->first, ensure_ascii);
16592
0
                    o->write_characters("\":", 2);
16593
0
                    dump(i->second, false, ensure_ascii, indent_step, current_indent);
16594
16595
0
                    o->write_character('}');
16596
0
                }
16597
16598
0
                return;
16599
0
            }
16600
16601
0
            case value_t::array:
16602
0
            {
16603
0
                if (val.m_value.array->empty())
16604
0
                {
16605
0
                    o->write_characters("[]", 2);
16606
0
                    return;
16607
0
                }
16608
16609
0
                if (pretty_print)
16610
0
                {
16611
0
                    o->write_characters("[\n", 2);
16612
16613
                    // variable to hold indentation for recursive calls
16614
0
                    const auto new_indent = current_indent + indent_step;
16615
0
                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16616
0
                    {
16617
0
                        indent_string.resize(indent_string.size() * 2, ' ');
16618
0
                    }
16619
16620
                    // first n-1 elements
16621
0
                    for (auto i = val.m_value.array->cbegin();
16622
0
                            i != val.m_value.array->cend() - 1; ++i)
16623
0
                    {
16624
0
                        o->write_characters(indent_string.c_str(), new_indent);
16625
0
                        dump(*i, true, ensure_ascii, indent_step, new_indent);
16626
0
                        o->write_characters(",\n", 2);
16627
0
                    }
16628
16629
                    // last element
16630
0
                    JSON_ASSERT(!val.m_value.array->empty());
16631
0
                    o->write_characters(indent_string.c_str(), new_indent);
16632
0
                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16633
16634
0
                    o->write_character('\n');
16635
0
                    o->write_characters(indent_string.c_str(), current_indent);
16636
0
                    o->write_character(']');
16637
0
                }
16638
0
                else
16639
0
                {
16640
0
                    o->write_character('[');
16641
16642
                    // first n-1 elements
16643
0
                    for (auto i = val.m_value.array->cbegin();
16644
0
                            i != val.m_value.array->cend() - 1; ++i)
16645
0
                    {
16646
0
                        dump(*i, false, ensure_ascii, indent_step, current_indent);
16647
0
                        o->write_character(',');
16648
0
                    }
16649
16650
                    // last element
16651
0
                    JSON_ASSERT(!val.m_value.array->empty());
16652
0
                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16653
16654
0
                    o->write_character(']');
16655
0
                }
16656
16657
0
                return;
16658
0
            }
16659
16660
0
            case value_t::string:
16661
0
            {
16662
0
                o->write_character('\"');
16663
0
                dump_escaped(*val.m_value.string, ensure_ascii);
16664
0
                o->write_character('\"');
16665
0
                return;
16666
0
            }
16667
16668
0
            case value_t::binary:
16669
0
            {
16670
0
                if (pretty_print)
16671
0
                {
16672
0
                    o->write_characters("{\n", 2);
16673
16674
                    // variable to hold indentation for recursive calls
16675
0
                    const auto new_indent = current_indent + indent_step;
16676
0
                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16677
0
                    {
16678
0
                        indent_string.resize(indent_string.size() * 2, ' ');
16679
0
                    }
16680
16681
0
                    o->write_characters(indent_string.c_str(), new_indent);
16682
16683
0
                    o->write_characters("\"bytes\": [", 10);
16684
16685
0
                    if (!val.m_value.binary->empty())
16686
0
                    {
16687
0
                        for (auto i = val.m_value.binary->cbegin();
16688
0
                                i != val.m_value.binary->cend() - 1; ++i)
16689
0
                        {
16690
0
                            dump_integer(*i);
16691
0
                            o->write_characters(", ", 2);
16692
0
                        }
16693
0
                        dump_integer(val.m_value.binary->back());
16694
0
                    }
16695
16696
0
                    o->write_characters("],\n", 3);
16697
0
                    o->write_characters(indent_string.c_str(), new_indent);
16698
16699
0
                    o->write_characters("\"subtype\": ", 11);
16700
0
                    if (val.m_value.binary->has_subtype())
16701
0
                    {
16702
0
                        dump_integer(val.m_value.binary->subtype());
16703
0
                    }
16704
0
                    else
16705
0
                    {
16706
0
                        o->write_characters("null", 4);
16707
0
                    }
16708
0
                    o->write_character('\n');
16709
0
                    o->write_characters(indent_string.c_str(), current_indent);
16710
0
                    o->write_character('}');
16711
0
                }
16712
0
                else
16713
0
                {
16714
0
                    o->write_characters("{\"bytes\":[", 10);
16715
16716
0
                    if (!val.m_value.binary->empty())
16717
0
                    {
16718
0
                        for (auto i = val.m_value.binary->cbegin();
16719
0
                                i != val.m_value.binary->cend() - 1; ++i)
16720
0
                        {
16721
0
                            dump_integer(*i);
16722
0
                            o->write_character(',');
16723
0
                        }
16724
0
                        dump_integer(val.m_value.binary->back());
16725
0
                    }
16726
16727
0
                    o->write_characters("],\"subtype\":", 12);
16728
0
                    if (val.m_value.binary->has_subtype())
16729
0
                    {
16730
0
                        dump_integer(val.m_value.binary->subtype());
16731
0
                        o->write_character('}');
16732
0
                    }
16733
0
                    else
16734
0
                    {
16735
0
                        o->write_characters("null}", 5);
16736
0
                    }
16737
0
                }
16738
0
                return;
16739
0
            }
16740
16741
0
            case value_t::boolean:
16742
0
            {
16743
0
                if (val.m_value.boolean)
16744
0
                {
16745
0
                    o->write_characters("true", 4);
16746
0
                }
16747
0
                else
16748
0
                {
16749
0
                    o->write_characters("false", 5);
16750
0
                }
16751
0
                return;
16752
0
            }
16753
16754
0
            case value_t::number_integer:
16755
0
            {
16756
0
                dump_integer(val.m_value.number_integer);
16757
0
                return;
16758
0
            }
16759
16760
0
            case value_t::number_unsigned:
16761
0
            {
16762
0
                dump_integer(val.m_value.number_unsigned);
16763
0
                return;
16764
0
            }
16765
16766
0
            case value_t::number_float:
16767
0
            {
16768
0
                dump_float(val.m_value.number_float);
16769
0
                return;
16770
0
            }
16771
16772
0
            case value_t::discarded:
16773
0
            {
16774
0
                o->write_characters("<discarded>", 11);
16775
0
                return;
16776
0
            }
16777
16778
0
            case value_t::null:
16779
0
            {
16780
0
                o->write_characters("null", 4);
16781
0
                return;
16782
0
            }
16783
16784
0
            default:            // LCOV_EXCL_LINE
16785
0
                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16786
0
        }
16787
0
    }
16788
16789
  JSON_PRIVATE_UNLESS_TESTED:
16790
    /*!
16791
    @brief dump escaped string
16792
16793
    Escape a string by replacing certain special characters by a sequence of an
16794
    escape character (backslash) and another character and other control
16795
    characters by a sequence of "\u" followed by a four-digit hex
16796
    representation. The escaped string is written to output stream @a o.
16797
16798
    @param[in] s  the string to escape
16799
    @param[in] ensure_ascii  whether to escape non-ASCII characters with
16800
                             \uXXXX sequences
16801
16802
    @complexity Linear in the length of string @a s.
16803
    */
16804
    void dump_escaped(const string_t& s, const bool ensure_ascii)
16805
0
    {
16806
0
        std::uint32_t codepoint{};
16807
0
        std::uint8_t state = UTF8_ACCEPT;
16808
0
        std::size_t bytes = 0;  // number of bytes written to string_buffer
16809
16810
        // number of bytes written at the point of the last valid byte
16811
0
        std::size_t bytes_after_last_accept = 0;
16812
0
        std::size_t undumped_chars = 0;
16813
16814
0
        for (std::size_t i = 0; i < s.size(); ++i)
16815
0
        {
16816
0
            const auto byte = static_cast<std::uint8_t>(s[i]);
16817
16818
0
            switch (decode(state, codepoint, byte))
16819
0
            {
16820
0
                case UTF8_ACCEPT:  // decode found a new code point
16821
0
                {
16822
0
                    switch (codepoint)
16823
0
                    {
16824
0
                        case 0x08: // backspace
16825
0
                        {
16826
0
                            string_buffer[bytes++] = '\\';
16827
0
                            string_buffer[bytes++] = 'b';
16828
0
                            break;
16829
0
                        }
16830
16831
0
                        case 0x09: // horizontal tab
16832
0
                        {
16833
0
                            string_buffer[bytes++] = '\\';
16834
0
                            string_buffer[bytes++] = 't';
16835
0
                            break;
16836
0
                        }
16837
16838
0
                        case 0x0A: // newline
16839
0
                        {
16840
0
                            string_buffer[bytes++] = '\\';
16841
0
                            string_buffer[bytes++] = 'n';
16842
0
                            break;
16843
0
                        }
16844
16845
0
                        case 0x0C: // formfeed
16846
0
                        {
16847
0
                            string_buffer[bytes++] = '\\';
16848
0
                            string_buffer[bytes++] = 'f';
16849
0
                            break;
16850
0
                        }
16851
16852
0
                        case 0x0D: // carriage return
16853
0
                        {
16854
0
                            string_buffer[bytes++] = '\\';
16855
0
                            string_buffer[bytes++] = 'r';
16856
0
                            break;
16857
0
                        }
16858
16859
0
                        case 0x22: // quotation mark
16860
0
                        {
16861
0
                            string_buffer[bytes++] = '\\';
16862
0
                            string_buffer[bytes++] = '\"';
16863
0
                            break;
16864
0
                        }
16865
16866
0
                        case 0x5C: // reverse solidus
16867
0
                        {
16868
0
                            string_buffer[bytes++] = '\\';
16869
0
                            string_buffer[bytes++] = '\\';
16870
0
                            break;
16871
0
                        }
16872
16873
0
                        default:
16874
0
                        {
16875
                            // escape control characters (0x00..0x1F) or, if
16876
                            // ensure_ascii parameter is used, non-ASCII characters
16877
0
                            if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16878
0
                            {
16879
0
                                if (codepoint <= 0xFFFF)
16880
0
                                {
16881
                                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16882
0
                                    (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16883
0
                                                    static_cast<std::uint16_t>(codepoint));
16884
0
                                    bytes += 6;
16885
0
                                }
16886
0
                                else
16887
0
                                {
16888
                                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16889
0
                                    (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16890
0
                                                    static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16891
0
                                                    static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16892
0
                                    bytes += 12;
16893
0
                                }
16894
0
                            }
16895
0
                            else
16896
0
                            {
16897
                                // copy byte to buffer (all previous bytes
16898
                                // been copied have in default case above)
16899
0
                                string_buffer[bytes++] = s[i];
16900
0
                            }
16901
0
                            break;
16902
0
                        }
16903
0
                    }
16904
16905
                    // write buffer and reset index; there must be 13 bytes
16906
                    // left, as this is the maximal number of bytes to be
16907
                    // written ("\uxxxx\uxxxx\0") for one code point
16908
0
                    if (string_buffer.size() - bytes < 13)
16909
0
                    {
16910
0
                        o->write_characters(string_buffer.data(), bytes);
16911
0
                        bytes = 0;
16912
0
                    }
16913
16914
                    // remember the byte position of this accept
16915
0
                    bytes_after_last_accept = bytes;
16916
0
                    undumped_chars = 0;
16917
0
                    break;
16918
0
                }
16919
16920
0
                case UTF8_REJECT:  // decode found invalid UTF-8 byte
16921
0
                {
16922
0
                    switch (error_handler)
16923
0
                    {
16924
0
                        case error_handler_t::strict:
16925
0
                        {
16926
0
                            std::string sn(9, '\0');
16927
                            // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16928
0
                            (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16929
0
                            JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16930
0
                        }
16931
16932
0
                        case error_handler_t::ignore:
16933
0
                        case error_handler_t::replace:
16934
0
                        {
16935
                            // in case we saw this character the first time, we
16936
                            // would like to read it again, because the byte
16937
                            // may be OK for itself, but just not OK for the
16938
                            // previous sequence
16939
0
                            if (undumped_chars > 0)
16940
0
                            {
16941
0
                                --i;
16942
0
                            }
16943
16944
                            // reset length buffer to the last accepted index;
16945
                            // thus removing/ignoring the invalid characters
16946
0
                            bytes = bytes_after_last_accept;
16947
16948
0
                            if (error_handler == error_handler_t::replace)
16949
0
                            {
16950
                                // add a replacement character
16951
0
                                if (ensure_ascii)
16952
0
                                {
16953
0
                                    string_buffer[bytes++] = '\\';
16954
0
                                    string_buffer[bytes++] = 'u';
16955
0
                                    string_buffer[bytes++] = 'f';
16956
0
                                    string_buffer[bytes++] = 'f';
16957
0
                                    string_buffer[bytes++] = 'f';
16958
0
                                    string_buffer[bytes++] = 'd';
16959
0
                                }
16960
0
                                else
16961
0
                                {
16962
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16963
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16964
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16965
0
                                }
16966
16967
                                // write buffer and reset index; there must be 13 bytes
16968
                                // left, as this is the maximal number of bytes to be
16969
                                // written ("\uxxxx\uxxxx\0") for one code point
16970
0
                                if (string_buffer.size() - bytes < 13)
16971
0
                                {
16972
0
                                    o->write_characters(string_buffer.data(), bytes);
16973
0
                                    bytes = 0;
16974
0
                                }
16975
16976
0
                                bytes_after_last_accept = bytes;
16977
0
                            }
16978
16979
0
                            undumped_chars = 0;
16980
16981
                            // continue processing the string
16982
0
                            state = UTF8_ACCEPT;
16983
0
                            break;
16984
0
                        }
16985
16986
0
                        default:            // LCOV_EXCL_LINE
16987
0
                            JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16988
0
                    }
16989
0
                    break;
16990
0
                }
16991
16992
0
                default:  // decode found yet incomplete multi-byte code point
16993
0
                {
16994
0
                    if (!ensure_ascii)
16995
0
                    {
16996
                        // code point will not be escaped - copy byte to buffer
16997
0
                        string_buffer[bytes++] = s[i];
16998
0
                    }
16999
0
                    ++undumped_chars;
17000
0
                    break;
17001
0
                }
17002
0
            }
17003
0
        }
17004
17005
        // we finished processing the string
17006
0
        if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
17007
0
        {
17008
            // write buffer
17009
0
            if (bytes > 0)
17010
0
            {
17011
0
                o->write_characters(string_buffer.data(), bytes);
17012
0
            }
17013
0
        }
17014
0
        else
17015
0
        {
17016
            // we finish reading, but do not accept: string was incomplete
17017
0
            switch (error_handler)
17018
0
            {
17019
0
                case error_handler_t::strict:
17020
0
                {
17021
0
                    std::string sn(9, '\0');
17022
                    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17023
0
                    (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
17024
0
                    JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
17025
0
                }
17026
17027
0
                case error_handler_t::ignore:
17028
0
                {
17029
                    // write all accepted bytes
17030
0
                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
17031
0
                    break;
17032
0
                }
17033
17034
0
                case error_handler_t::replace:
17035
0
                {
17036
                    // write all accepted bytes
17037
0
                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
17038
                    // add a replacement character
17039
0
                    if (ensure_ascii)
17040
0
                    {
17041
0
                        o->write_characters("\\ufffd", 6);
17042
0
                    }
17043
0
                    else
17044
0
                    {
17045
0
                        o->write_characters("\xEF\xBF\xBD", 3);
17046
0
                    }
17047
0
                    break;
17048
0
                }
17049
17050
0
                default:            // LCOV_EXCL_LINE
17051
0
                    JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17052
0
            }
17053
0
        }
17054
0
    }
17055
17056
  private:
17057
    /*!
17058
    @brief count digits
17059
17060
    Count the number of decimal (base 10) digits for an input unsigned integer.
17061
17062
    @param[in] x  unsigned integer number to count its digits
17063
    @return    number of decimal digits
17064
    */
17065
    inline unsigned int count_digits(number_unsigned_t x) noexcept
17066
0
    {
17067
0
        unsigned int n_digits = 1;
17068
0
        for (;;)
17069
0
        {
17070
0
            if (x < 10)
17071
0
            {
17072
0
                return n_digits;
17073
0
            }
17074
0
            if (x < 100)
17075
0
            {
17076
0
                return n_digits + 1;
17077
0
            }
17078
0
            if (x < 1000)
17079
0
            {
17080
0
                return n_digits + 2;
17081
0
            }
17082
0
            if (x < 10000)
17083
0
            {
17084
0
                return n_digits + 3;
17085
0
            }
17086
0
            x = x / 10000u;
17087
0
            n_digits += 4;
17088
0
        }
17089
0
    }
17090
17091
    /*!
17092
    @brief dump an integer
17093
17094
    Dump a given integer to output stream @a o. Works internally with
17095
    @a number_buffer.
17096
17097
    @param[in] x  integer number (signed or unsigned) to dump
17098
    @tparam NumberType either @a number_integer_t or @a number_unsigned_t
17099
    */
17100
    template < typename NumberType, detail::enable_if_t <
17101
                   std::is_integral<NumberType>::value ||
17102
                   std::is_same<NumberType, number_unsigned_t>::value ||
17103
                   std::is_same<NumberType, number_integer_t>::value ||
17104
                   std::is_same<NumberType, binary_char_t>::value,
17105
                   int > = 0 >
17106
    void dump_integer(NumberType x)
17107
0
    {
17108
0
        static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17109
0
        {
17110
0
            {
17111
0
                {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17112
0
                {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17113
0
                {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17114
0
                {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17115
0
                {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17116
0
                {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17117
0
                {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17118
0
                {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17119
0
                {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17120
0
                {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17121
0
            }
17122
0
        };
17123
17124
        // special case for "0"
17125
0
        if (x == 0)
17126
0
        {
17127
0
            o->write_character('0');
17128
0
            return;
17129
0
        }
17130
17131
        // use a pointer to fill the buffer
17132
0
        auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17133
17134
0
        const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17135
0
        number_unsigned_t abs_value;
17136
17137
0
        unsigned int n_chars{};
17138
17139
0
        if (is_negative)
17140
0
        {
17141
0
            *buffer_ptr = '-';
17142
0
            abs_value = remove_sign(static_cast<number_integer_t>(x));
17143
17144
            // account one more byte for the minus sign
17145
0
            n_chars = 1 + count_digits(abs_value);
17146
0
        }
17147
0
        else
17148
0
        {
17149
0
            abs_value = static_cast<number_unsigned_t>(x);
17150
0
            n_chars = count_digits(abs_value);
17151
0
        }
17152
17153
        // spare 1 byte for '\0'
17154
0
        JSON_ASSERT(n_chars < number_buffer.size() - 1);
17155
17156
        // jump to the end to generate the string from backward
17157
        // so we later avoid reversing the result
17158
0
        buffer_ptr += n_chars;
17159
17160
        // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17161
        // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17162
0
        while (abs_value >= 100)
17163
0
        {
17164
0
            const auto digits_index = static_cast<unsigned>((abs_value % 100));
17165
0
            abs_value /= 100;
17166
0
            *(--buffer_ptr) = digits_to_99[digits_index][1];
17167
0
            *(--buffer_ptr) = digits_to_99[digits_index][0];
17168
0
        }
17169
17170
0
        if (abs_value >= 10)
17171
0
        {
17172
0
            const auto digits_index = static_cast<unsigned>(abs_value);
17173
0
            *(--buffer_ptr) = digits_to_99[digits_index][1];
17174
0
            *(--buffer_ptr) = digits_to_99[digits_index][0];
17175
0
        }
17176
0
        else
17177
0
        {
17178
0
            *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17179
0
        }
17180
17181
0
        o->write_characters(number_buffer.data(), n_chars);
17182
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::dump_integer<unsigned char, 0>(unsigned char)
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::dump_integer<unsigned long, 0>(unsigned 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::dump_integer<long, 0>(long)
17183
17184
    /*!
17185
    @brief dump a floating-point number
17186
17187
    Dump a given floating-point number to output stream @a o. Works internally
17188
    with @a number_buffer.
17189
17190
    @param[in] x  floating-point number to dump
17191
    */
17192
    void dump_float(number_float_t x)
17193
0
    {
17194
        // NaN / inf
17195
0
        if (!std::isfinite(x))
17196
0
        {
17197
0
            o->write_characters("null", 4);
17198
0
            return;
17199
0
        }
17200
17201
        // If number_float_t is an IEEE-754 single or double precision number,
17202
        // use the Grisu2 algorithm to produce short numbers which are
17203
        // guaranteed to round-trip, using strtof and strtod, resp.
17204
        //
17205
        // NB: The test below works if <long double> == <double>.
17206
0
        static constexpr bool is_ieee_single_or_double
17207
0
            = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17208
0
              (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17209
17210
0
        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17211
0
    }
17212
17213
    void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17214
0
    {
17215
0
        auto* begin = number_buffer.data();
17216
0
        auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17217
17218
0
        o->write_characters(begin, static_cast<size_t>(end - begin));
17219
0
    }
17220
17221
    void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17222
    {
17223
        // get number of digits for a float -> text -> float round-trip
17224
        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17225
17226
        // the actual conversion
17227
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17228
        std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17229
17230
        // negative value indicates an error
17231
        JSON_ASSERT(len > 0);
17232
        // check if buffer was large enough
17233
        JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17234
17235
        // erase thousands separator
17236
        if (thousands_sep != '\0')
17237
        {
17238
            // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
17239
            const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
17240
            std::fill(end, number_buffer.end(), '\0');
17241
            JSON_ASSERT((end - number_buffer.begin()) <= len);
17242
            len = (end - number_buffer.begin());
17243
        }
17244
17245
        // convert decimal point to '.'
17246
        if (decimal_point != '\0' && decimal_point != '.')
17247
        {
17248
            // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
17249
            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17250
            if (dec_pos != number_buffer.end())
17251
            {
17252
                *dec_pos = '.';
17253
            }
17254
        }
17255
17256
        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17257
17258
        // determine if need to append ".0"
17259
        const bool value_is_int_like =
17260
            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17261
                         [](char c)
17262
        {
17263
            return c == '.' || c == 'e';
17264
        });
17265
17266
        if (value_is_int_like)
17267
        {
17268
            o->write_characters(".0", 2);
17269
        }
17270
    }
17271
17272
    /*!
17273
    @brief check whether a string is UTF-8 encoded
17274
17275
    The function checks each byte of a string whether it is UTF-8 encoded. The
17276
    result of the check is stored in the @a state parameter. The function must
17277
    be called initially with state 0 (accept). State 1 means the string must
17278
    be rejected, because the current byte is not allowed. If the string is
17279
    completely processed, but the state is non-zero, the string ended
17280
    prematurely; that is, the last byte indicated more bytes should have
17281
    followed.
17282
17283
    @param[in,out] state  the state of the decoding
17284
    @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
17285
    @param[in] byte       next byte to decode
17286
    @return               new state
17287
17288
    @note The function has been edited: a std::array is used.
17289
17290
    @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
17291
    @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
17292
    */
17293
    static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17294
0
    {
17295
0
        static const std::array<std::uint8_t, 400> utf8d =
17296
0
        {
17297
0
            {
17298
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
17299
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
17300
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
17301
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
17302
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
17303
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
17304
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
17305
0
                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17306
0
                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17307
0
                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17308
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
17309
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
17310
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
17311
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
17312
0
            }
17313
0
        };
17314
17315
0
        JSON_ASSERT(byte < utf8d.size());
17316
0
        const std::uint8_t type = utf8d[byte];
17317
17318
0
        codep = (state != UTF8_ACCEPT)
17319
0
                ? (byte & 0x3fu) | (codep << 6u)
17320
0
                : (0xFFu >> type) & (byte);
17321
17322
0
        std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17323
0
        JSON_ASSERT(index < 400);
17324
0
        state = utf8d[index];
17325
0
        return state;
17326
0
    }
17327
17328
    /*
17329
     * Overload to make the compiler happy while it is instantiating
17330
     * dump_integer for number_unsigned_t.
17331
     * Must never be called.
17332
     */
17333
    number_unsigned_t remove_sign(number_unsigned_t x)
17334
    {
17335
        JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17336
        return x; // LCOV_EXCL_LINE
17337
    }
17338
17339
    /*
17340
     * Helper function for dump_integer
17341
     *
17342
     * This function takes a negative signed integer and returns its absolute
17343
     * value as unsigned integer. The plus/minus shuffling is necessary as we can
17344
     * not directly remove the sign of an arbitrary signed integer as the
17345
     * absolute values of INT_MIN and INT_MAX are usually not the same. See
17346
     * #1708 for details.
17347
     */
17348
    inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17349
0
    {
17350
0
        JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17351
0
        return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17352
0
    }
17353
17354
  private:
17355
    /// the output of the serializer
17356
    output_adapter_t<char> o = nullptr;
17357
17358
    /// a (hopefully) large enough character buffer
17359
    std::array<char, 64> number_buffer{{}};
17360
17361
    /// the locale
17362
    const std::lconv* loc = nullptr;
17363
    /// the locale's thousand separator character
17364
    const char thousands_sep = '\0';
17365
    /// the locale's decimal point character
17366
    const char decimal_point = '\0';
17367
17368
    /// string buffer
17369
    std::array<char, 512> string_buffer{{}};
17370
17371
    /// the indentation character
17372
    const char indent_char;
17373
    /// the indentation string
17374
    string_t indent_string;
17375
17376
    /// error_handler how to react on decoding errors
17377
    const error_handler_t error_handler;
17378
};
17379
}  // namespace detail
17380
}  // namespace nlohmann
17381
17382
// #include <nlohmann/detail/value_t.hpp>
17383
17384
// #include <nlohmann/json_fwd.hpp>
17385
17386
// #include <nlohmann/ordered_map.hpp>
17387
17388
17389
#include <functional> // less
17390
#include <initializer_list> // initializer_list
17391
#include <iterator> // input_iterator_tag, iterator_traits
17392
#include <memory> // allocator
17393
#include <stdexcept> // for out_of_range
17394
#include <type_traits> // enable_if, is_convertible
17395
#include <utility> // pair
17396
#include <vector> // vector
17397
17398
// #include <nlohmann/detail/macro_scope.hpp>
17399
17400
17401
namespace nlohmann
17402
{
17403
17404
/// ordered_map: a minimal map-like container that preserves insertion order
17405
/// for use within nlohmann::basic_json<ordered_map>
17406
template <class Key, class T, class IgnoredLess = std::less<Key>,
17407
          class Allocator = std::allocator<std::pair<const Key, T>>>
17408
                  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17409
{
17410
    using key_type = Key;
17411
    using mapped_type = T;
17412
    using Container = std::vector<std::pair<const Key, T>, Allocator>;
17413
    using typename Container::iterator;
17414
    using typename Container::const_iterator;
17415
    using typename Container::size_type;
17416
    using typename Container::value_type;
17417
17418
    // Explicit constructors instead of `using Container::Container`
17419
    // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17420
    ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17421
    template <class It>
17422
    ordered_map(It first, It last, const Allocator& alloc = Allocator())
17423
        : Container{first, last, alloc} {}
17424
    ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17425
        : Container{init, alloc} {}
17426
17427
    std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17428
    {
17429
        for (auto it = this->begin(); it != this->end(); ++it)
17430
        {
17431
            if (it->first == key)
17432
            {
17433
                return {it, false};
17434
            }
17435
        }
17436
        Container::emplace_back(key, t);
17437
        return {--this->end(), true};
17438
    }
17439
17440
    T& operator[](const Key& key)
17441
    {
17442
        return emplace(key, T{}).first->second;
17443
    }
17444
17445
    const T& operator[](const Key& key) const
17446
    {
17447
        return at(key);
17448
    }
17449
17450
    T& at(const Key& key)
17451
    {
17452
        for (auto it = this->begin(); it != this->end(); ++it)
17453
        {
17454
            if (it->first == key)
17455
            {
17456
                return it->second;
17457
            }
17458
        }
17459
17460
        JSON_THROW(std::out_of_range("key not found"));
17461
    }
17462
17463
    const T& at(const Key& key) const
17464
    {
17465
        for (auto it = this->begin(); it != this->end(); ++it)
17466
        {
17467
            if (it->first == key)
17468
            {
17469
                return it->second;
17470
            }
17471
        }
17472
17473
        JSON_THROW(std::out_of_range("key not found"));
17474
    }
17475
17476
    size_type erase(const Key& key)
17477
    {
17478
        for (auto it = this->begin(); it != this->end(); ++it)
17479
        {
17480
            if (it->first == key)
17481
            {
17482
                // Since we cannot move const Keys, re-construct them in place
17483
                for (auto next = it; ++next != this->end(); ++it)
17484
                {
17485
                    it->~value_type(); // Destroy but keep allocation
17486
                    new (&*it) value_type{std::move(*next)};
17487
                }
17488
                Container::pop_back();
17489
                return 1;
17490
            }
17491
        }
17492
        return 0;
17493
    }
17494
17495
    iterator erase(iterator pos)
17496
    {
17497
        auto it = pos;
17498
17499
        // Since we cannot move const Keys, re-construct them in place
17500
        for (auto next = it; ++next != this->end(); ++it)
17501
        {
17502
            it->~value_type(); // Destroy but keep allocation
17503
            new (&*it) value_type{std::move(*next)};
17504
        }
17505
        Container::pop_back();
17506
        return pos;
17507
    }
17508
17509
    size_type count(const Key& key) const
17510
    {
17511
        for (auto it = this->begin(); it != this->end(); ++it)
17512
        {
17513
            if (it->first == key)
17514
            {
17515
                return 1;
17516
            }
17517
        }
17518
        return 0;
17519
    }
17520
17521
    iterator find(const Key& key)
17522
    {
17523
        for (auto it = this->begin(); it != this->end(); ++it)
17524
        {
17525
            if (it->first == key)
17526
            {
17527
                return it;
17528
            }
17529
        }
17530
        return Container::end();
17531
    }
17532
17533
    const_iterator find(const Key& key) const
17534
    {
17535
        for (auto it = this->begin(); it != this->end(); ++it)
17536
        {
17537
            if (it->first == key)
17538
            {
17539
                return it;
17540
            }
17541
        }
17542
        return Container::end();
17543
    }
17544
17545
    std::pair<iterator, bool> insert( value_type&& value )
17546
    {
17547
        return emplace(value.first, std::move(value.second));
17548
    }
17549
17550
    std::pair<iterator, bool> insert( const value_type& value )
17551
    {
17552
        for (auto it = this->begin(); it != this->end(); ++it)
17553
        {
17554
            if (it->first == value.first)
17555
            {
17556
                return {it, false};
17557
            }
17558
        }
17559
        Container::push_back(value);
17560
        return {--this->end(), true};
17561
    }
17562
17563
    template<typename InputIt>
17564
    using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17565
            std::input_iterator_tag>::value>::type;
17566
17567
    template<typename InputIt, typename = require_input_iter<InputIt>>
17568
    void insert(InputIt first, InputIt last)
17569
    {
17570
        for (auto it = first; it != last; ++it)
17571
        {
17572
            insert(*it);
17573
        }
17574
    }
17575
};
17576
17577
}  // namespace nlohmann
17578
17579
17580
#if defined(JSON_HAS_CPP_17)
17581
    #include <string_view>
17582
#endif
17583
17584
/*!
17585
@brief namespace for Niels Lohmann
17586
@see https://github.com/nlohmann
17587
@since version 1.0.0
17588
*/
17589
namespace nlohmann
17590
{
17591
17592
/*!
17593
@brief a class to store JSON values
17594
17595
@tparam ObjectType type for JSON objects (`std::map` by default; will be used
17596
in @ref object_t)
17597
@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
17598
in @ref array_t)
17599
@tparam StringType type for JSON strings and object keys (`std::string` by
17600
default; will be used in @ref string_t)
17601
@tparam BooleanType type for JSON booleans (`bool` by default; will be used
17602
in @ref boolean_t)
17603
@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
17604
default; will be used in @ref number_integer_t)
17605
@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
17606
`uint64_t` by default; will be used in @ref number_unsigned_t)
17607
@tparam NumberFloatType type for JSON floating-point numbers (`double` by
17608
default; will be used in @ref number_float_t)
17609
@tparam BinaryType type for packed binary data for compatibility with binary
17610
serialization formats (`std::vector<std::uint8_t>` by default; will be used in
17611
@ref binary_t)
17612
@tparam AllocatorType type of the allocator to use (`std::allocator` by
17613
default)
17614
@tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
17615
and `from_json()` (@ref adl_serializer by default)
17616
17617
@requirement The class satisfies the following concept requirements:
17618
- Basic
17619
 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
17620
   JSON values can be default constructed. The result will be a JSON null
17621
   value.
17622
 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
17623
   A JSON value can be constructed from an rvalue argument.
17624
 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
17625
   A JSON value can be copy-constructed from an lvalue expression.
17626
 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
17627
   A JSON value van be assigned from an rvalue argument.
17628
 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
17629
   A JSON value can be copy-assigned from an lvalue expression.
17630
 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
17631
   JSON values can be destructed.
17632
- Layout
17633
 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
17634
   JSON values have
17635
   [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
17636
   All non-static data members are private and standard layout types, the
17637
   class has no virtual functions or (virtual) base classes.
17638
- Library-wide
17639
 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
17640
   JSON values can be compared with `==`, see @ref
17641
   operator==(const_reference,const_reference).
17642
 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
17643
   JSON values can be compared with `<`, see @ref
17644
   operator<(const_reference,const_reference).
17645
 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
17646
   Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
17647
   other compatible types, using unqualified function call @ref swap().
17648
 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
17649
   JSON values can be compared against `std::nullptr_t` objects which are used
17650
   to model the `null` value.
17651
- Container
17652
 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
17653
   JSON values can be used like STL containers and provide iterator access.
17654
 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
17655
   JSON values can be used like STL containers and provide reverse iterator
17656
   access.
17657
17658
@invariant The member variables @a m_value and @a m_type have the following
17659
relationship:
17660
- If `m_type == value_t::object`, then `m_value.object != nullptr`.
17661
- If `m_type == value_t::array`, then `m_value.array != nullptr`.
17662
- If `m_type == value_t::string`, then `m_value.string != nullptr`.
17663
The invariants are checked by member function assert_invariant().
17664
17665
@internal
17666
@note ObjectType trick from https://stackoverflow.com/a/9860911
17667
@endinternal
17668
17669
@see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange
17670
Format](https://tools.ietf.org/html/rfc8259)
17671
17672
@since version 1.0.0
17673
17674
@nosubgrouping
17675
*/
17676
NLOHMANN_BASIC_JSON_TPL_DECLARATION
17677
class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17678
{
17679
  private:
17680
    template<detail::value_t> friend struct detail::external_constructor;
17681
    friend ::nlohmann::json_pointer<basic_json>;
17682
17683
    template<typename BasicJsonType, typename InputType>
17684
    friend class ::nlohmann::detail::parser;
17685
    friend ::nlohmann::detail::serializer<basic_json>;
17686
    template<typename BasicJsonType>
17687
    friend class ::nlohmann::detail::iter_impl;
17688
    template<typename BasicJsonType, typename CharType>
17689
    friend class ::nlohmann::detail::binary_writer;
17690
    template<typename BasicJsonType, typename InputType, typename SAX>
17691
    friend class ::nlohmann::detail::binary_reader;
17692
    template<typename BasicJsonType>
17693
    friend class ::nlohmann::detail::json_sax_dom_parser;
17694
    template<typename BasicJsonType>
17695
    friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17696
    friend class ::nlohmann::detail::exception;
17697
17698
    /// workaround type for MSVC
17699
    using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17700
17701
  JSON_PRIVATE_UNLESS_TESTED:
17702
    // convenience aliases for types residing in namespace detail;
17703
    using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17704
17705
    template<typename InputAdapterType>
17706
    static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17707
        InputAdapterType adapter,
17708
        detail::parser_callback_t<basic_json>cb = nullptr,
17709
        const bool allow_exceptions = true,
17710
        const bool ignore_comments = false
17711
                                 )
17712
1.82k
    {
17713
1.82k
        return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17714
1.82k
                std::move(cb), allow_exceptions, ignore_comments);
17715
1.82k
    }
17716
17717
  private:
17718
    using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17719
    template<typename BasicJsonType>
17720
    using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17721
    template<typename BasicJsonType>
17722
    using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17723
    template<typename Iterator>
17724
    using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17725
    template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17726
17727
    template<typename CharType>
17728
    using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17729
17730
    template<typename InputType>
17731
    using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
17732
    template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17733
17734
  JSON_PRIVATE_UNLESS_TESTED:
17735
    using serializer = ::nlohmann::detail::serializer<basic_json>;
17736
17737
  public:
17738
    using value_t = detail::value_t;
17739
    /// JSON Pointer, see @ref nlohmann::json_pointer
17740
    using json_pointer = ::nlohmann::json_pointer<basic_json>;
17741
    template<typename T, typename SFINAE>
17742
    using json_serializer = JSONSerializer<T, SFINAE>;
17743
    /// how to treat decoding errors
17744
    using error_handler_t = detail::error_handler_t;
17745
    /// how to treat CBOR tags
17746
    using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17747
    /// helper type for initializer lists of basic_json values
17748
    using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17749
17750
    using input_format_t = detail::input_format_t;
17751
    /// SAX interface type, see @ref nlohmann::json_sax
17752
    using json_sax_t = json_sax<basic_json>;
17753
17754
    ////////////////
17755
    // exceptions //
17756
    ////////////////
17757
17758
    /// @name exceptions
17759
    /// Classes to implement user-defined exceptions.
17760
    /// @{
17761
17762
    /// @copydoc detail::exception
17763
    using exception = detail::exception;
17764
    /// @copydoc detail::parse_error
17765
    using parse_error = detail::parse_error;
17766
    /// @copydoc detail::invalid_iterator
17767
    using invalid_iterator = detail::invalid_iterator;
17768
    /// @copydoc detail::type_error
17769
    using type_error = detail::type_error;
17770
    /// @copydoc detail::out_of_range
17771
    using out_of_range = detail::out_of_range;
17772
    /// @copydoc detail::other_error
17773
    using other_error = detail::other_error;
17774
17775
    /// @}
17776
17777
17778
    /////////////////////
17779
    // container types //
17780
    /////////////////////
17781
17782
    /// @name container types
17783
    /// The canonic container types to use @ref basic_json like any other STL
17784
    /// container.
17785
    /// @{
17786
17787
    /// the type of elements in a basic_json container
17788
    using value_type = basic_json;
17789
17790
    /// the type of an element reference
17791
    using reference = value_type&;
17792
    /// the type of an element const reference
17793
    using const_reference = const value_type&;
17794
17795
    /// a type to represent differences between iterators
17796
    using difference_type = std::ptrdiff_t;
17797
    /// a type to represent container sizes
17798
    using size_type = std::size_t;
17799
17800
    /// the allocator type
17801
    using allocator_type = AllocatorType<basic_json>;
17802
17803
    /// the type of an element pointer
17804
    using pointer = typename std::allocator_traits<allocator_type>::pointer;
17805
    /// the type of an element const pointer
17806
    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17807
17808
    /// an iterator for a basic_json container
17809
    using iterator = iter_impl<basic_json>;
17810
    /// a const iterator for a basic_json container
17811
    using const_iterator = iter_impl<const basic_json>;
17812
    /// a reverse iterator for a basic_json container
17813
    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
17814
    /// a const reverse iterator for a basic_json container
17815
    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
17816
17817
    /// @}
17818
17819
17820
    /*!
17821
    @brief returns the allocator associated with the container
17822
    */
17823
    static allocator_type get_allocator()
17824
    {
17825
        return allocator_type();
17826
    }
17827
17828
    /*!
17829
    @brief returns version information on the library
17830
17831
    This function returns a JSON object with information about the library,
17832
    including the version number and information on the platform and compiler.
17833
17834
    @return JSON object holding version information
17835
    key         | description
17836
    ----------- | ---------------
17837
    `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).
17838
    `copyright` | The copyright line for the library as string.
17839
    `name`      | The name of the library as string.
17840
    `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
17841
    `url`       | The URL of the project as string.
17842
    `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).
17843
17844
    @liveexample{The following code shows an example output of the `meta()`
17845
    function.,meta}
17846
17847
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17848
    changes to any JSON value.
17849
17850
    @complexity Constant.
17851
17852
    @since 2.1.0
17853
    */
17854
    JSON_HEDLEY_WARN_UNUSED_RESULT
17855
    static basic_json meta()
17856
    {
17857
        basic_json result;
17858
17859
        result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17860
        result["name"] = "JSON for Modern C++";
17861
        result["url"] = "https://github.com/nlohmann/json";
17862
        result["version"]["string"] =
17863
            std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17864
            std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17865
            std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17866
        result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17867
        result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17868
        result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17869
17870
#ifdef _WIN32
17871
        result["platform"] = "win32";
17872
#elif defined __linux__
17873
        result["platform"] = "linux";
17874
#elif defined __APPLE__
17875
        result["platform"] = "apple";
17876
#elif defined __unix__
17877
        result["platform"] = "unix";
17878
#else
17879
        result["platform"] = "unknown";
17880
#endif
17881
17882
#if defined(__ICC) || defined(__INTEL_COMPILER)
17883
        result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17884
#elif defined(__clang__)
17885
        result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17886
#elif defined(__GNUC__) || defined(__GNUG__)
17887
        result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17888
#elif defined(__HP_cc) || defined(__HP_aCC)
17889
        result["compiler"] = "hp"
17890
#elif defined(__IBMCPP__)
17891
        result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17892
#elif defined(_MSC_VER)
17893
        result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17894
#elif defined(__PGI)
17895
        result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17896
#elif defined(__SUNPRO_CC)
17897
        result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17898
#else
17899
        result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17900
#endif
17901
17902
#ifdef __cplusplus
17903
        result["compiler"]["c++"] = std::to_string(__cplusplus);
17904
#else
17905
        result["compiler"]["c++"] = "unknown";
17906
#endif
17907
        return result;
17908
    }
17909
17910
17911
    ///////////////////////////
17912
    // JSON value data types //
17913
    ///////////////////////////
17914
17915
    /// @name JSON value data types
17916
    /// The data types to store a JSON value. These types are derived from
17917
    /// the template arguments passed to class @ref basic_json.
17918
    /// @{
17919
17920
#if defined(JSON_HAS_CPP_14)
17921
    // Use transparent comparator if possible, combined with perfect forwarding
17922
    // on find() and count() calls prevents unnecessary string construction.
17923
    using object_comparator_t = std::less<>;
17924
#else
17925
    using object_comparator_t = std::less<StringType>;
17926
#endif
17927
17928
    /*!
17929
    @brief a type for an object
17930
17931
    [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:
17932
    > An object is an unordered collection of zero or more name/value pairs,
17933
    > where a name is a string and a value is a string, number, boolean, null,
17934
    > object, or array.
17935
17936
    To store objects in C++, a type is defined by the template parameters
17937
    described below.
17938
17939
    @tparam ObjectType  the container to store objects (e.g., `std::map` or
17940
    `std::unordered_map`)
17941
    @tparam StringType the type of the keys or names (e.g., `std::string`).
17942
    The comparison function `std::less<StringType>` is used to order elements
17943
    inside the container.
17944
    @tparam AllocatorType the allocator to use for objects (e.g.,
17945
    `std::allocator`)
17946
17947
    #### Default type
17948
17949
    With the default values for @a ObjectType (`std::map`), @a StringType
17950
    (`std::string`), and @a AllocatorType (`std::allocator`), the default
17951
    value for @a object_t is:
17952
17953
    @code {.cpp}
17954
    std::map<
17955
      std::string, // key_type
17956
      basic_json, // value_type
17957
      std::less<std::string>, // key_compare
17958
      std::allocator<std::pair<const std::string, basic_json>> // allocator_type
17959
    >
17960
    @endcode
17961
17962
    #### Behavior
17963
17964
    The choice of @a object_t influences the behavior of the JSON class. With
17965
    the default type, objects have the following behavior:
17966
17967
    - When all names are unique, objects will be interoperable in the sense
17968
      that all software implementations receiving that object will agree on
17969
      the name-value mappings.
17970
    - When the names within an object are not unique, it is unspecified which
17971
      one of the values for a given key will be chosen. For instance,
17972
      `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
17973
      `{"key": 2}`.
17974
    - Internally, name/value pairs are stored in lexicographical order of the
17975
      names. Objects will also be serialized (see @ref dump) in this order.
17976
      For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
17977
      and serialized as `{"a": 2, "b": 1}`.
17978
    - When comparing objects, the order of the name/value pairs is irrelevant.
17979
      This makes objects interoperable in the sense that they will not be
17980
      affected by these differences. For instance, `{"b": 1, "a": 2}` and
17981
      `{"a": 2, "b": 1}` will be treated as equal.
17982
17983
    #### Limits
17984
17985
    [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
17986
    > An implementation may set limits on the maximum depth of nesting.
17987
17988
    In this class, the object's limit of nesting is not explicitly constrained.
17989
    However, a maximum depth of nesting may be introduced by the compiler or
17990
    runtime environment. A theoretical limit can be queried by calling the
17991
    @ref max_size function of a JSON object.
17992
17993
    #### Storage
17994
17995
    Objects are stored as pointers in a @ref basic_json type. That is, for any
17996
    access to object values, a pointer of type `object_t*` must be
17997
    dereferenced.
17998
17999
    @sa see @ref array_t -- type for an array value
18000
18001
    @since version 1.0.0
18002
18003
    @note The order name/value pairs are added to the object is *not*
18004
    preserved by the library. Therefore, iterating an object may return
18005
    name/value pairs in a different order than they were originally stored. In
18006
    fact, keys will be traversed in alphabetical order as `std::map` with
18007
    `std::less` is used by default. Please note this behavior conforms to [RFC
18008
    8259](https://tools.ietf.org/html/rfc8259), because any order implements the
18009
    specified "unordered" nature of JSON objects.
18010
    */
18011
    using object_t = ObjectType<StringType,
18012
          basic_json,
18013
          object_comparator_t,
18014
          AllocatorType<std::pair<const StringType,
18015
          basic_json>>>;
18016
18017
    /*!
18018
    @brief a type for an array
18019
18020
    [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:
18021
    > An array is an ordered sequence of zero or more values.
18022
18023
    To store objects in C++, a type is defined by the template parameters
18024
    explained below.
18025
18026
    @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
18027
    `std::list`)
18028
    @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
18029
18030
    #### Default type
18031
18032
    With the default values for @a ArrayType (`std::vector`) and @a
18033
    AllocatorType (`std::allocator`), the default value for @a array_t is:
18034
18035
    @code {.cpp}
18036
    std::vector<
18037
      basic_json, // value_type
18038
      std::allocator<basic_json> // allocator_type
18039
    >
18040
    @endcode
18041
18042
    #### Limits
18043
18044
    [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18045
    > An implementation may set limits on the maximum depth of nesting.
18046
18047
    In this class, the array's limit of nesting is not explicitly constrained.
18048
    However, a maximum depth of nesting may be introduced by the compiler or
18049
    runtime environment. A theoretical limit can be queried by calling the
18050
    @ref max_size function of a JSON array.
18051
18052
    #### Storage
18053
18054
    Arrays are stored as pointers in a @ref basic_json type. That is, for any
18055
    access to array values, a pointer of type `array_t*` must be dereferenced.
18056
18057
    @sa see @ref object_t -- type for an object value
18058
18059
    @since version 1.0.0
18060
    */
18061
    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18062
18063
    /*!
18064
    @brief a type for a string
18065
18066
    [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:
18067
    > A string is a sequence of zero or more Unicode characters.
18068
18069
    To store objects in C++, a type is defined by the template parameter
18070
    described below. Unicode values are split by the JSON class into
18071
    byte-sized characters during deserialization.
18072
18073
    @tparam StringType  the container to store strings (e.g., `std::string`).
18074
    Note this container is used for keys/names in objects, see @ref object_t.
18075
18076
    #### Default type
18077
18078
    With the default values for @a StringType (`std::string`), the default
18079
    value for @a string_t is:
18080
18081
    @code {.cpp}
18082
    std::string
18083
    @endcode
18084
18085
    #### Encoding
18086
18087
    Strings are stored in UTF-8 encoding. Therefore, functions like
18088
    `std::string::size()` or `std::string::length()` return the number of
18089
    bytes in the string rather than the number of characters or glyphs.
18090
18091
    #### String comparison
18092
18093
    [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
18094
    > Software implementations are typically required to test names of object
18095
    > members for equality. Implementations that transform the textual
18096
    > representation into sequences of Unicode code units and then perform the
18097
    > comparison numerically, code unit by code unit, are interoperable in the
18098
    > sense that implementations will agree in all cases on equality or
18099
    > inequality of two strings. For example, implementations that compare
18100
    > strings with escaped characters unconverted may incorrectly find that
18101
    > `"a\\b"` and `"a\u005Cb"` are not equal.
18102
18103
    This implementation is interoperable as it does compare strings code unit
18104
    by code unit.
18105
18106
    #### Storage
18107
18108
    String values are stored as pointers in a @ref basic_json type. That is,
18109
    for any access to string values, a pointer of type `string_t*` must be
18110
    dereferenced.
18111
18112
    @since version 1.0.0
18113
    */
18114
    using string_t = StringType;
18115
18116
    /*!
18117
    @brief a type for a boolean
18118
18119
    [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a
18120
    type which differentiates the two literals `true` and `false`.
18121
18122
    To store objects in C++, a type is defined by the template parameter @a
18123
    BooleanType which chooses the type to use.
18124
18125
    #### Default type
18126
18127
    With the default values for @a BooleanType (`bool`), the default value for
18128
    @a boolean_t is:
18129
18130
    @code {.cpp}
18131
    bool
18132
    @endcode
18133
18134
    #### Storage
18135
18136
    Boolean values are stored directly inside a @ref basic_json type.
18137
18138
    @since version 1.0.0
18139
    */
18140
    using boolean_t = BooleanType;
18141
18142
    /*!
18143
    @brief a type for a number (integer)
18144
18145
    [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18146
    > The representation of numbers is similar to that used in most
18147
    > programming languages. A number is represented in base 10 using decimal
18148
    > digits. It contains an integer component that may be prefixed with an
18149
    > optional minus sign, which may be followed by a fraction part and/or an
18150
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
18151
    > cannot be represented in the grammar below (such as Infinity and NaN)
18152
    > are not permitted.
18153
18154
    This description includes both integer and floating-point numbers.
18155
    However, C++ allows more precise storage if it is known whether the number
18156
    is a signed integer, an unsigned integer or a floating-point number.
18157
    Therefore, three different types, @ref number_integer_t, @ref
18158
    number_unsigned_t and @ref number_float_t are used.
18159
18160
    To store integer numbers in C++, a type is defined by the template
18161
    parameter @a NumberIntegerType which chooses the type to use.
18162
18163
    #### Default type
18164
18165
    With the default values for @a NumberIntegerType (`int64_t`), the default
18166
    value for @a number_integer_t is:
18167
18168
    @code {.cpp}
18169
    int64_t
18170
    @endcode
18171
18172
    #### Default behavior
18173
18174
    - The restrictions about leading zeros is not enforced in C++. Instead,
18175
      leading zeros in integer literals lead to an interpretation as octal
18176
      number. Internally, the value will be stored as decimal number. For
18177
      instance, the C++ integer literal `010` will be serialized to `8`.
18178
      During deserialization, leading zeros yield an error.
18179
    - Not-a-number (NaN) values will be serialized to `null`.
18180
18181
    #### Limits
18182
18183
    [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18184
    > An implementation may set limits on the range and precision of numbers.
18185
18186
    When the default type is used, the maximal integer number that can be
18187
    stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
18188
    that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
18189
    that are out of range will yield over/underflow when used in a
18190
    constructor. During deserialization, too large or small integer numbers
18191
    will be automatically be stored as @ref number_unsigned_t or @ref
18192
    number_float_t.
18193
18194
    [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18195
    > Note that when such software is used, numbers that are integers and are
18196
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18197
    > that implementations will agree exactly on their numeric values.
18198
18199
    As this range is a subrange of the exactly supported range [INT64_MIN,
18200
    INT64_MAX], this class's integer type is interoperable.
18201
18202
    #### Storage
18203
18204
    Integer number values are stored directly inside a @ref basic_json type.
18205
18206
    @sa see @ref number_float_t -- type for number values (floating-point)
18207
18208
    @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18209
18210
    @since version 1.0.0
18211
    */
18212
    using number_integer_t = NumberIntegerType;
18213
18214
    /*!
18215
    @brief a type for a number (unsigned)
18216
18217
    [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18218
    > The representation of numbers is similar to that used in most
18219
    > programming languages. A number is represented in base 10 using decimal
18220
    > digits. It contains an integer component that may be prefixed with an
18221
    > optional minus sign, which may be followed by a fraction part and/or an
18222
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
18223
    > cannot be represented in the grammar below (such as Infinity and NaN)
18224
    > are not permitted.
18225
18226
    This description includes both integer and floating-point numbers.
18227
    However, C++ allows more precise storage if it is known whether the number
18228
    is a signed integer, an unsigned integer or a floating-point number.
18229
    Therefore, three different types, @ref number_integer_t, @ref
18230
    number_unsigned_t and @ref number_float_t are used.
18231
18232
    To store unsigned integer numbers in C++, a type is defined by the
18233
    template parameter @a NumberUnsignedType which chooses the type to use.
18234
18235
    #### Default type
18236
18237
    With the default values for @a NumberUnsignedType (`uint64_t`), the
18238
    default value for @a number_unsigned_t is:
18239
18240
    @code {.cpp}
18241
    uint64_t
18242
    @endcode
18243
18244
    #### Default behavior
18245
18246
    - The restrictions about leading zeros is not enforced in C++. Instead,
18247
      leading zeros in integer literals lead to an interpretation as octal
18248
      number. Internally, the value will be stored as decimal number. For
18249
      instance, the C++ integer literal `010` will be serialized to `8`.
18250
      During deserialization, leading zeros yield an error.
18251
    - Not-a-number (NaN) values will be serialized to `null`.
18252
18253
    #### Limits
18254
18255
    [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18256
    > An implementation may set limits on the range and precision of numbers.
18257
18258
    When the default type is used, the maximal integer number that can be
18259
    stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
18260
    number that can be stored is `0`. Integer numbers that are out of range
18261
    will yield over/underflow when used in a constructor. During
18262
    deserialization, too large or small integer numbers will be automatically
18263
    be stored as @ref number_integer_t or @ref number_float_t.
18264
18265
    [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18266
    > Note that when such software is used, numbers that are integers and are
18267
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18268
    > that implementations will agree exactly on their numeric values.
18269
18270
    As this range is a subrange (when considered in conjunction with the
18271
    number_integer_t type) of the exactly supported range [0, UINT64_MAX],
18272
    this class's integer type is interoperable.
18273
18274
    #### Storage
18275
18276
    Integer number values are stored directly inside a @ref basic_json type.
18277
18278
    @sa see @ref number_float_t -- type for number values (floating-point)
18279
    @sa see @ref number_integer_t -- type for number values (integer)
18280
18281
    @since version 2.0.0
18282
    */
18283
    using number_unsigned_t = NumberUnsignedType;
18284
18285
    /*!
18286
    @brief a type for a number (floating-point)
18287
18288
    [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18289
    > The representation of numbers is similar to that used in most
18290
    > programming languages. A number is represented in base 10 using decimal
18291
    > digits. It contains an integer component that may be prefixed with an
18292
    > optional minus sign, which may be followed by a fraction part and/or an
18293
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
18294
    > cannot be represented in the grammar below (such as Infinity and NaN)
18295
    > are not permitted.
18296
18297
    This description includes both integer and floating-point numbers.
18298
    However, C++ allows more precise storage if it is known whether the number
18299
    is a signed integer, an unsigned integer or a floating-point number.
18300
    Therefore, three different types, @ref number_integer_t, @ref
18301
    number_unsigned_t and @ref number_float_t are used.
18302
18303
    To store floating-point numbers in C++, a type is defined by the template
18304
    parameter @a NumberFloatType which chooses the type to use.
18305
18306
    #### Default type
18307
18308
    With the default values for @a NumberFloatType (`double`), the default
18309
    value for @a number_float_t is:
18310
18311
    @code {.cpp}
18312
    double
18313
    @endcode
18314
18315
    #### Default behavior
18316
18317
    - The restrictions about leading zeros is not enforced in C++. Instead,
18318
      leading zeros in floating-point literals will be ignored. Internally,
18319
      the value will be stored as decimal number. For instance, the C++
18320
      floating-point literal `01.2` will be serialized to `1.2`. During
18321
      deserialization, leading zeros yield an error.
18322
    - Not-a-number (NaN) values will be serialized to `null`.
18323
18324
    #### Limits
18325
18326
    [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
18327
    > This specification allows implementations to set limits on the range and
18328
    > precision of numbers accepted. Since software that implements IEEE
18329
    > 754-2008 binary64 (double precision) numbers is generally available and
18330
    > widely used, good interoperability can be achieved by implementations
18331
    > that expect no more precision or range than these provide, in the sense
18332
    > that implementations will approximate JSON numbers within the expected
18333
    > precision.
18334
18335
    This implementation does exactly follow this approach, as it uses double
18336
    precision floating-point numbers. Note values smaller than
18337
    `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
18338
    will be stored as NaN internally and be serialized to `null`.
18339
18340
    #### Storage
18341
18342
    Floating-point number values are stored directly inside a @ref basic_json
18343
    type.
18344
18345
    @sa see @ref number_integer_t -- type for number values (integer)
18346
18347
    @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18348
18349
    @since version 1.0.0
18350
    */
18351
    using number_float_t = NumberFloatType;
18352
18353
    /*!
18354
    @brief a type for a packed binary type
18355
18356
    This type is a type designed to carry binary data that appears in various
18357
    serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
18358
    BSON's generic binary subtype. This type is NOT a part of standard JSON and
18359
    exists solely for compatibility with these binary types. As such, it is
18360
    simply defined as an ordered sequence of zero or more byte values.
18361
18362
    Additionally, as an implementation detail, the subtype of the binary data is
18363
    carried around as a `std::uint8_t`, which is compatible with both of the
18364
    binary data formats that use binary subtyping, (though the specific
18365
    numbering is incompatible with each other, and it is up to the user to
18366
    translate between them).
18367
18368
    [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
18369
    as:
18370
    > Major type 2: a byte string. The string's length in bytes is represented
18371
    > following the rules for positive integers (major type 0).
18372
18373
    [MessagePack's documentation on the bin type
18374
    family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
18375
    describes this type as:
18376
    > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
18377
    > in addition to the size of the byte array.
18378
18379
    [BSON's specifications](http://bsonspec.org/spec.html) describe several
18380
    binary types; however, this type is intended to represent the generic binary
18381
    type which has the description:
18382
    > Generic binary subtype - This is the most commonly used binary subtype and
18383
    > should be the 'default' for drivers and tools.
18384
18385
    None of these impose any limitations on the internal representation other
18386
    than the basic unit of storage be some type of array whose parts are
18387
    decomposable into bytes.
18388
18389
    The default representation of this binary format is a
18390
    `std::vector<std::uint8_t>`, which is a very common way to represent a byte
18391
    array in modern C++.
18392
18393
    #### Default type
18394
18395
    The default values for @a BinaryType is `std::vector<std::uint8_t>`
18396
18397
    #### Storage
18398
18399
    Binary Arrays are stored as pointers in a @ref basic_json type. That is,
18400
    for any access to array values, a pointer of the type `binary_t*` must be
18401
    dereferenced.
18402
18403
    #### Notes on subtypes
18404
18405
    - CBOR
18406
       - Binary values are represented as byte strings. Subtypes are serialized
18407
         as tagged values.
18408
    - MessagePack
18409
       - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
18410
         or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
18411
         is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
18412
         The subtype is then added as singed 8-bit integer.
18413
       - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
18414
    - BSON
18415
       - If a subtype is given, it is used and added as unsigned 8-bit integer.
18416
       - If no subtype is given, the generic binary subtype 0x00 is used.
18417
18418
    @sa see @ref binary -- create a binary array
18419
18420
    @since version 3.8.0
18421
    */
18422
    using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
18423
    /// @}
18424
18425
  private:
18426
18427
    /// helper for exception-safe object creation
18428
    template<typename T, typename... Args>
18429
    JSON_HEDLEY_RETURNS_NON_NULL
18430
    static T* create(Args&& ... args)
18431
7.30M
    {
18432
7.30M
        AllocatorType<T> alloc;
18433
7.30M
        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18434
18435
7.30M
        auto deleter = [&](T * obj)
18436
7.30M
        {
18437
0
            AllocatorTraits::deallocate(alloc, obj, 1);
18438
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::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
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > >>()::{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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > >*)#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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >>()::{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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >*)#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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::create<nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >>()::{lambda(nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*)#1}::operator()(nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const* const&>(char const* 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
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > >*)#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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >*)#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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::create<nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const&>(nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const&)::{lambda(nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >*)#1}::operator()(nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >, nlohmann::detail::json_ref<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<unsigned char, std::__1::allocator<unsigned char> > > > const*, nlohmann::detail::json_ref<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<unsigned char, std::__1::allocator<unsigned char> > > > const*>(nlohmann::detail::json_ref<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<unsigned char, std::__1::allocator<unsigned char> > > > const*&&, nlohmann::detail::json_ref<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<unsigned char, std::__1::allocator<unsigned char> > > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >*)#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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >*) const
18439
7.30M
        std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18440
7.30M
        AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18441
7.30M
        JSON_ASSERT(obj != nullptr);
18442
0
        return obj.release();
18443
7.30M
    }
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::vector<unsigned char, std::__1::allocator<unsigned char> > >::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&)
Line
Count
Source
18431
71.5k
    {
18432
71.5k
        AllocatorType<T> alloc;
18433
71.5k
        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18434
18435
71.5k
        auto deleter = [&](T * obj)
18436
71.5k
        {
18437
71.5k
            AllocatorTraits::deallocate(alloc, obj, 1);
18438
71.5k
        };
18439
71.5k
        std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18440
71.5k
        AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18441
71.5k
        JSON_ASSERT(obj != nullptr);
18442
0
        return obj.release();
18443
71.5k
    }
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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned 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::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > >>()
Line
Count
Source
18431
1.55M
    {
18432
1.55M
        AllocatorType<T> alloc;
18433
1.55M
        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18434
18435
1.55M
        auto deleter = [&](T * obj)
18436
1.55M
        {
18437
1.55M
            AllocatorTraits::deallocate(alloc, obj, 1);
18438
1.55M
        };
18439
1.55M
        std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18440
1.55M
        AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18441
1.55M
        JSON_ASSERT(obj != nullptr);
18442
0
        return obj.release();
18443
1.55M
    }
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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned 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::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >>()
Line
Count
Source
18431
5.67M
    {
18432
5.67M
        AllocatorType<T> alloc;
18433
5.67M
        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18434
18435
5.67M
        auto deleter = [&](T * obj)
18436
5.67M
        {
18437
5.67M
            AllocatorTraits::deallocate(alloc, obj, 1);
18438
5.67M
        };
18439
5.67M
        std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18440
5.67M
        AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18441
5.67M
        JSON_ASSERT(obj != nullptr);
18442
0
        return obj.release();
18443
5.67M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const (&) [1]>(char const (&) [1])
Unexecuted instantiation: nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned 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::vector<unsigned char, std::__1::allocator<unsigned char> > >::create<nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >>()
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const* const&>(char const* const&)
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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned 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::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > > > > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned 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::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >, 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > > const&)
Unexecuted instantiation: nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned 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::vector<unsigned char, std::__1::allocator<unsigned char> > >::create<nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const&>(nlohmann::byte_container_with_subtype<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > 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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned 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::vector<unsigned char, std::__1::allocator<unsigned char> > >::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::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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<unsigned char, std::__1::allocator<unsigned char> > > > >, nlohmann::detail::json_ref<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<unsigned char, std::__1::allocator<unsigned char> > > > const*, nlohmann::detail::json_ref<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<unsigned char, std::__1::allocator<unsigned char> > > > const*>(nlohmann::detail::json_ref<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<unsigned char, std::__1::allocator<unsigned char> > > > const*&&, nlohmann::detail::json_ref<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<unsigned char, std::__1::allocator<unsigned char> > > > const*&&)
18444
18445
    ////////////////////////
18446
    // JSON value storage //
18447
    ////////////////////////
18448
18449
  JSON_PRIVATE_UNLESS_TESTED:
18450
    /*!
18451
    @brief a JSON value
18452
18453
    The actual storage for a JSON value of the @ref basic_json class. This
18454
    union combines the different storage types for the JSON value types
18455
    defined in @ref value_t.
18456
18457
    JSON type | value_t type    | used type
18458
    --------- | --------------- | ------------------------
18459
    object    | object          | pointer to @ref object_t
18460
    array     | array           | pointer to @ref array_t
18461
    string    | string          | pointer to @ref string_t
18462
    boolean   | boolean         | @ref boolean_t
18463
    number    | number_integer  | @ref number_integer_t
18464
    number    | number_unsigned | @ref number_unsigned_t
18465
    number    | number_float    | @ref number_float_t
18466
    binary    | binary          | pointer to @ref binary_t
18467
    null      | null            | *no value is stored*
18468
18469
    @note Variable-length types (objects, arrays, and strings) are stored as
18470
    pointers. The size of the union should not exceed 64 bits if the default
18471
    value types are used.
18472
18473
    @since version 1.0.0
18474
    */
18475
    union json_value
18476
    {
18477
        /// object (stored with pointer to save storage)
18478
        object_t* object;
18479
        /// array (stored with pointer to save storage)
18480
        array_t* array;
18481
        /// string (stored with pointer to save storage)
18482
        string_t* string;
18483
        /// binary (stored with pointer to save storage)
18484
        binary_t* binary;
18485
        /// boolean
18486
        boolean_t boolean;
18487
        /// number (integer)
18488
        number_integer_t number_integer;
18489
        /// number (unsigned integer)
18490
        number_unsigned_t number_unsigned;
18491
        /// number (floating-point)
18492
        number_float_t number_float;
18493
18494
        /// default constructor (for null values)
18495
        json_value() = default;
18496
        /// constructor for booleans
18497
22.8k
        json_value(boolean_t v) noexcept : boolean(v) {}
18498
        /// constructor for numbers (integer)
18499
20.4k
        json_value(number_integer_t v) noexcept : number_integer(v) {}
18500
        /// constructor for numbers (unsigned)
18501
6.13M
        json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18502
        /// constructor for numbers (floating-point)
18503
50.0k
        json_value(number_float_t v) noexcept : number_float(v) {}
18504
        /// constructor for empty values of a given type
18505
        json_value(value_t t)
18506
7.74M
        {
18507
7.74M
            switch (t)
18508
7.74M
            {
18509
1.55M
                case value_t::object:
18510
1.55M
                {
18511
1.55M
                    object = create<object_t>();
18512
1.55M
                    break;
18513
0
                }
18514
18515
5.67M
                case value_t::array:
18516
5.67M
                {
18517
5.67M
                    array = create<array_t>();
18518
5.67M
                    break;
18519
0
                }
18520
18521
0
                case value_t::string:
18522
0
                {
18523
0
                    string = create<string_t>("");
18524
0
                    break;
18525
0
                }
18526
18527
0
                case value_t::binary:
18528
0
                {
18529
0
                    binary = create<binary_t>();
18530
0
                    break;
18531
0
                }
18532
18533
0
                case value_t::boolean:
18534
0
                {
18535
0
                    boolean = boolean_t(false);
18536
0
                    break;
18537
0
                }
18538
18539
0
                case value_t::number_integer:
18540
0
                {
18541
0
                    number_integer = number_integer_t(0);
18542
0
                    break;
18543
0
                }
18544
18545
0
                case value_t::number_unsigned:
18546
0
                {
18547
0
                    number_unsigned = number_unsigned_t(0);
18548
0
                    break;
18549
0
                }
18550
18551
0
                case value_t::number_float:
18552
0
                {
18553
0
                    number_float = number_float_t(0.0);
18554
0
                    break;
18555
0
                }
18556
18557
511k
                case value_t::null:
18558
511k
                {
18559
511k
                    object = nullptr;  // silence warning, see #821
18560
511k
                    break;
18561
0
                }
18562
18563
0
                case value_t::discarded:
18564
0
                default:
18565
0
                {
18566
0
                    object = nullptr;  // silence warning, see #821
18567
0
                    if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18568
0
                    {
18569
0
                        JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json())); // LCOV_EXCL_LINE
18570
0
                    }
18571
0
                    break;
18572
0
                }
18573
7.74M
            }
18574
7.74M
        }
18575
18576
        /// constructor for strings
18577
        json_value(const string_t& value)
18578
71.5k
        {
18579
71.5k
            string = create<string_t>(value);
18580
71.5k
        }
18581
18582
        /// constructor for rvalue strings
18583
        json_value(string_t&& value)
18584
        {
18585
            string = create<string_t>(std::move(value));
18586
        }
18587
18588
        /// constructor for objects
18589
        json_value(const object_t& value)
18590
0
        {
18591
0
            object = create<object_t>(value);
18592
0
        }
18593
18594
        /// constructor for rvalue objects
18595
        json_value(object_t&& value)
18596
        {
18597
            object = create<object_t>(std::move(value));
18598
        }
18599
18600
        /// constructor for arrays
18601
        json_value(const array_t& value)
18602
0
        {
18603
0
            array = create<array_t>(value);
18604
0
        }
18605
18606
        /// constructor for rvalue arrays
18607
        json_value(array_t&& value)
18608
        {
18609
            array = create<array_t>(std::move(value));
18610
        }
18611
18612
        /// constructor for binary arrays
18613
        json_value(const typename binary_t::container_type& value)
18614
        {
18615
            binary = create<binary_t>(value);
18616
        }
18617
18618
        /// constructor for rvalue binary arrays
18619
        json_value(typename binary_t::container_type&& value)
18620
        {
18621
            binary = create<binary_t>(std::move(value));
18622
        }
18623
18624
        /// constructor for binary arrays (internal type)
18625
        json_value(const binary_t& value)
18626
0
        {
18627
0
            binary = create<binary_t>(value);
18628
0
        }
18629
18630
        /// constructor for rvalue binary arrays (internal type)
18631
        json_value(binary_t&& value)
18632
        {
18633
            binary = create<binary_t>(std::move(value));
18634
        }
18635
18636
        void destroy(value_t t)
18637
68.7M
        {
18638
68.7M
            if (t == value_t::array || t == value_t::object)
18639
7.23M
            {
18640
                // flatten the current json_value to a heap-allocated stack
18641
7.23M
                std::vector<basic_json> stack;
18642
18643
                // move the top-level items to stack
18644
7.23M
                if (t == value_t::array)
18645
5.67M
                {
18646
5.67M
                    stack.reserve(array->size());
18647
5.67M
                    std::move(array->begin(), array->end(), std::back_inserter(stack));
18648
5.67M
                }
18649
1.55M
                else
18650
1.55M
                {
18651
1.55M
                    stack.reserve(object->size());
18652
1.55M
                    for (auto&& it : *object)
18653
5.80k
                    {
18654
5.80k
                        stack.push_back(std::move(it.second));
18655
5.80k
                    }
18656
1.55M
                }
18657
18658
20.7M
                while (!stack.empty())
18659
13.5M
                {
18660
                    // move the last item to local variable to be processed
18661
13.5M
                    basic_json current_item(std::move(stack.back()));
18662
13.5M
                    stack.pop_back();
18663
18664
                    // if current_item is array/object, move
18665
                    // its children to the stack to be processed later
18666
13.5M
                    if (current_item.is_array())
18667
5.67M
                    {
18668
5.67M
                        std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18669
18670
5.67M
                        current_item.m_value.array->clear();
18671
5.67M
                    }
18672
7.86M
                    else if (current_item.is_object())
18673
1.54M
                    {
18674
1.54M
                        for (auto&& it : *current_item.m_value.object)
18675
478k
                        {
18676
478k
                            stack.push_back(std::move(it.second));
18677
478k
                        }
18678
18679
1.54M
                        current_item.m_value.object->clear();
18680
1.54M
                    }
18681
18682
                    // it's now safe that current_item get destructed
18683
                    // since it doesn't have any children
18684
13.5M
                }
18685
7.23M
            }
18686
18687
68.7M
            switch (t)
18688
68.7M
            {
18689
1.55M
                case value_t::object:
18690
1.55M
                {
18691
1.55M
                    AllocatorType<object_t> alloc;
18692
1.55M
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18693
1.55M
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18694
1.55M
                    break;
18695
0
                }
18696
18697
5.67M
                case value_t::array:
18698
5.67M
                {
18699
5.67M
                    AllocatorType<array_t> alloc;
18700
5.67M
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18701
5.67M
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18702
5.67M
                    break;
18703
0
                }
18704
18705
71.5k
                case value_t::string:
18706
71.5k
                {
18707
71.5k
                    AllocatorType<string_t> alloc;
18708
71.5k
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18709
71.5k
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18710
71.5k
                    break;
18711
0
                }
18712
18713
0
                case value_t::binary:
18714
0
                {
18715
0
                    AllocatorType<binary_t> alloc;
18716
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18717
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18718
0
                    break;
18719
0
                }
18720
18721
55.2M
                case value_t::null:
18722
55.2M
                case value_t::boolean:
18723
55.2M
                case value_t::number_integer:
18724
61.3M
                case value_t::number_unsigned:
18725
61.4M
                case value_t::number_float:
18726
61.4M
                case value_t::discarded:
18727
61.4M
                default:
18728
61.4M
                {
18729
61.4M
                    break;
18730
61.4M
                }
18731
68.7M
            }
18732
68.7M
        }
18733
    };
18734
18735
  private:
18736
    /*!
18737
    @brief checks the class invariants
18738
18739
    This function asserts the class invariants. It needs to be called at the
18740
    end of every constructor to make sure that created objects respect the
18741
    invariant. Furthermore, it has to be called each time the type of a JSON
18742
    value is changed, because the invariant expresses a relationship between
18743
    @a m_type and @a m_value.
18744
18745
    Furthermore, the parent relation is checked for arrays and objects: If
18746
    @a check_parents true and the value is an array or object, then the
18747
    container's elements must have the current value as parent.
18748
18749
    @param[in] check_parents  whether the parent relation should be checked.
18750
               The value is true by default and should only be set to false
18751
               during destruction of objects when the invariant does not
18752
               need to hold.
18753
    */
18754
    void assert_invariant(bool check_parents = true) const noexcept
18755
181M
    {
18756
181M
        JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18757
181M
        JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18758
181M
        JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18759
181M
        JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18760
18761
#if JSON_DIAGNOSTICS
18762
        JSON_TRY
18763
        {
18764
            // cppcheck-suppress assertWithSideEffect
18765
            JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18766
            {
18767
                return j.m_parent == this;
18768
            }));
18769
        }
18770
        JSON_CATCH(...) {} // LCOV_EXCL_LINE
18771
#endif
18772
0
        static_cast<void>(check_parents);
18773
181M
    }
18774
18775
    void set_parents()
18776
56.5M
    {
18777
#if JSON_DIAGNOSTICS
18778
        switch (m_type)
18779
        {
18780
            case value_t::array:
18781
            {
18782
                for (auto& element : *m_value.array)
18783
                {
18784
                    element.m_parent = this;
18785
                }
18786
                break;
18787
            }
18788
18789
            case value_t::object:
18790
            {
18791
                for (auto& element : *m_value.object)
18792
                {
18793
                    element.second.m_parent = this;
18794
                }
18795
                break;
18796
            }
18797
18798
            case value_t::null:
18799
            case value_t::string:
18800
            case value_t::boolean:
18801
            case value_t::number_integer:
18802
            case value_t::number_unsigned:
18803
            case value_t::number_float:
18804
            case value_t::binary:
18805
            case value_t::discarded:
18806
            default:
18807
                break;
18808
        }
18809
#endif
18810
56.5M
    }
18811
18812
    iterator set_parents(iterator it, typename iterator::difference_type count)
18813
    {
18814
#if JSON_DIAGNOSTICS
18815
        for (typename iterator::difference_type i = 0; i < count; ++i)
18816
        {
18817
            (it + i)->m_parent = this;
18818
        }
18819
#else
18820
        static_cast<void>(count);
18821
#endif
18822
        return it;
18823
    }
18824
18825
    reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18826
0
    {
18827
#if JSON_DIAGNOSTICS
18828
        if (old_capacity != std::size_t(-1))
18829
        {
18830
            // see https://github.com/nlohmann/json/issues/2838
18831
            JSON_ASSERT(type() == value_t::array);
18832
            if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18833
            {
18834
                // capacity has changed: update all parents
18835
                set_parents();
18836
                return j;
18837
            }
18838
        }
18839
18840
        // ordered_json uses a vector internally, so pointers could have
18841
        // been invalidated; see https://github.com/nlohmann/json/issues/2962
18842
#ifdef JSON_HEDLEY_MSVC_VERSION
18843
#pragma warning(push )
18844
#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18845
#endif
18846
        if (detail::is_ordered_map<object_t>::value)
18847
        {
18848
            set_parents();
18849
            return j;
18850
        }
18851
#ifdef JSON_HEDLEY_MSVC_VERSION
18852
#pragma warning( pop )
18853
#endif
18854
18855
        j.m_parent = this;
18856
#else
18857
0
        static_cast<void>(j);
18858
0
        static_cast<void>(old_capacity);
18859
0
#endif
18860
0
        return j;
18861
0
    }
18862
18863
  public:
18864
    //////////////////////////
18865
    // JSON parser callback //
18866
    //////////////////////////
18867
18868
    /*!
18869
    @brief parser event types
18870
18871
    The parser callback distinguishes the following events:
18872
    - `object_start`: the parser read `{` and started to process a JSON object
18873
    - `key`: the parser read a key of a value in an object
18874
    - `object_end`: the parser read `}` and finished processing a JSON object
18875
    - `array_start`: the parser read `[` and started to process a JSON array
18876
    - `array_end`: the parser read `]` and finished processing a JSON array
18877
    - `value`: the parser finished reading a JSON value
18878
18879
    @image html callback_events.png "Example when certain parse events are triggered"
18880
18881
    @sa see @ref parser_callback_t for more information and examples
18882
    */
18883
    using parse_event_t = detail::parse_event_t;
18884
18885
    /*!
18886
    @brief per-element parser callback type
18887
18888
    With a parser callback function, the result of parsing a JSON text can be
18889
    influenced. When passed to @ref parse, it is called on certain events
18890
    (passed as @ref parse_event_t via parameter @a event) with a set recursion
18891
    depth @a depth and context JSON value @a parsed. The return value of the
18892
    callback function is a boolean indicating whether the element that emitted
18893
    the callback shall be kept or not.
18894
18895
    We distinguish six scenarios (determined by the event type) in which the
18896
    callback function can be called. The following table describes the values
18897
    of the parameters @a depth, @a event, and @a parsed.
18898
18899
    parameter @a event | description | parameter @a depth | parameter @a parsed
18900
    ------------------ | ----------- | ------------------ | -------------------
18901
    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
18902
    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
18903
    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
18904
    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
18905
    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
18906
    parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
18907
18908
    @image html callback_events.png "Example when certain parse events are triggered"
18909
18910
    Discarding a value (i.e., returning `false`) has different effects
18911
    depending on the context in which function was called:
18912
18913
    - Discarded values in structured types are skipped. That is, the parser
18914
      will behave as if the discarded value was never read.
18915
    - In case a value outside a structured type is skipped, it is replaced
18916
      with `null`. This case happens if the top-level element is skipped.
18917
18918
    @param[in] depth  the depth of the recursion during parsing
18919
18920
    @param[in] event  an event of type parse_event_t indicating the context in
18921
    the callback function has been called
18922
18923
    @param[in,out] parsed  the current intermediate parse result; note that
18924
    writing to this value has no effect for parse_event_t::key events
18925
18926
    @return Whether the JSON value which called the function during parsing
18927
    should be kept (`true`) or not (`false`). In the latter case, it is either
18928
    skipped completely or replaced by an empty discarded object.
18929
18930
    @sa see @ref parse for examples
18931
18932
    @since version 1.0.0
18933
    */
18934
    using parser_callback_t = detail::parser_callback_t<basic_json>;
18935
18936
    //////////////////
18937
    // constructors //
18938
    //////////////////
18939
18940
    /// @name constructors and destructors
18941
    /// Constructors of class @ref basic_json, copy/move constructor, copy
18942
    /// assignment, static functions creating objects, and the destructor.
18943
    /// @{
18944
18945
    /*!
18946
    @brief create an empty value with a given type
18947
18948
    Create an empty JSON value with a given type. The value will be default
18949
    initialized with an empty value which depends on the type:
18950
18951
    Value type  | initial value
18952
    ----------- | -------------
18953
    null        | `null`
18954
    boolean     | `false`
18955
    string      | `""`
18956
    number      | `0`
18957
    object      | `{}`
18958
    array       | `[]`
18959
    binary      | empty array
18960
18961
    @param[in] v  the type of the value to create
18962
18963
    @complexity Constant.
18964
18965
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18966
    changes to any JSON value.
18967
18968
    @liveexample{The following code shows the constructor for different @ref
18969
    value_t values,basic_json__value_t}
18970
18971
    @sa see @ref clear() -- restores the postcondition of this constructor
18972
18973
    @since version 1.0.0
18974
    */
18975
    basic_json(const value_t v)
18976
        : m_type(v), m_value(v)
18977
7.74M
    {
18978
7.74M
        assert_invariant();
18979
7.74M
    }
18980
18981
    /*!
18982
    @brief create a null object
18983
18984
    Create a `null` JSON value. It either takes a null pointer as parameter
18985
    (explicitly creating `null`) or no parameter (implicitly creating `null`).
18986
    The passed null pointer itself is not read -- it is only used to choose
18987
    the right constructor.
18988
18989
    @complexity Constant.
18990
18991
    @exceptionsafety No-throw guarantee: this constructor never throws
18992
    exceptions.
18993
18994
    @liveexample{The following code shows the constructor with and without a
18995
    null pointer parameter.,basic_json__nullptr_t}
18996
18997
    @since version 1.0.0
18998
    */
18999
    basic_json(std::nullptr_t = nullptr) noexcept
19000
        : basic_json(value_t::null)
19001
511k
    {
19002
511k
        assert_invariant();
19003
511k
    }
19004
19005
    /*!
19006
    @brief create a JSON value
19007
19008
    This is a "catch all" constructor for all compatible JSON types; that is,
19009
    types for which a `to_json()` method exists. The constructor forwards the
19010
    parameter @a val to that method (to `json_serializer<U>::to_json` method
19011
    with `U = uncvref_t<CompatibleType>`, to be exact).
19012
19013
    Template type @a CompatibleType includes, but is not limited to, the
19014
    following types:
19015
    - **arrays**: @ref array_t and all kinds of compatible containers such as
19016
      `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
19017
      `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
19018
      `std::multiset`, and `std::unordered_multiset` with a `value_type` from
19019
      which a @ref basic_json value can be constructed.
19020
    - **objects**: @ref object_t and all kinds of compatible associative
19021
      containers such as `std::map`, `std::unordered_map`, `std::multimap`,
19022
      and `std::unordered_multimap` with a `key_type` compatible to
19023
      @ref string_t and a `value_type` from which a @ref basic_json value can
19024
      be constructed.
19025
    - **strings**: @ref string_t, string literals, and all compatible string
19026
      containers can be used.
19027
    - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
19028
      @ref number_float_t, and all convertible number types such as `int`,
19029
      `size_t`, `int64_t`, `float` or `double` can be used.
19030
    - **boolean**: @ref boolean_t / `bool` can be used.
19031
    - **binary**: @ref binary_t / `std::vector<std::uint8_t>` may be used,
19032
      unfortunately because string literals cannot be distinguished from binary
19033
      character arrays by the C++ type system, all types compatible with `const
19034
      char*` will be directed to the string constructor instead.  This is both
19035
      for backwards compatibility, and due to the fact that a binary type is not
19036
      a standard JSON type.
19037
19038
    See the examples below.
19039
19040
    @tparam CompatibleType a type such that:
19041
    - @a CompatibleType is not derived from `std::istream`,
19042
    - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
19043
         constructors),
19044
    - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
19045
    - @a CompatibleType is not a @ref basic_json nested type (e.g.,
19046
         @ref json_pointer, @ref iterator, etc ...)
19047
    - `json_serializer<U>` has a `to_json(basic_json_t&, CompatibleType&&)` method
19048
19049
    @tparam U = `uncvref_t<CompatibleType>`
19050
19051
    @param[in] val the value to be forwarded to the respective constructor
19052
19053
    @complexity Usually linear in the size of the passed @a val, also
19054
                depending on the implementation of the called `to_json()`
19055
                method.
19056
19057
    @exceptionsafety Depends on the called constructor. For types directly
19058
    supported by the library (i.e., all types for which no `to_json()` function
19059
    was provided), strong guarantee holds: if an exception is thrown, there are
19060
    no changes to any JSON value.
19061
19062
    @liveexample{The following code shows the constructor with several
19063
    compatible types.,basic_json__CompatibleType}
19064
19065
    @since version 2.1.0
19066
    */
19067
    template < typename CompatibleType,
19068
               typename U = detail::uncvref_t<CompatibleType>,
19069
               detail::enable_if_t <
19070
                   !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
19071
    basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19072
                JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
19073
                                           std::forward<CompatibleType>(val))))
19074
6.29M
    {
19075
6.29M
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19076
6.29M
        set_parents();
19077
6.29M
        assert_invariant();
19078
6.29M
    }
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<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<unsigned long&, unsigned long, 0>(unsigned long&)
Line
Count
Source
19074
6.13M
    {
19075
6.13M
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19076
6.13M
        set_parents();
19077
6.13M
        assert_invariant();
19078
6.13M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<double const&, double, 0>(double 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<int const&, int, 0>(int 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<bool const&, bool, 0>(bool 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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<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> >, 0>(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::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<double&, double, 0>(double&)
Line
Count
Source
19074
50.0k
    {
19075
50.0k
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19076
50.0k
        set_parents();
19077
50.0k
        assert_invariant();
19078
50.0k
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<int&, int, 0>(int&)
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<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<bool&, bool, 0>(bool&)
Line
Count
Source
19074
22.8k
    {
19075
22.8k
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19076
22.8k
        set_parents();
19077
22.8k
        assert_invariant();
19078
22.8k
    }
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<unsigned char, std::__1::allocator<unsigned char> > >::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> >&)
Line
Count
Source
19074
71.5k
    {
19075
71.5k
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19076
71.5k
        set_parents();
19077
71.5k
        assert_invariant();
19078
71.5k
    }
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<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<long&, long, 0>(long&)
Line
Count
Source
19074
20.4k
    {
19075
20.4k
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19076
20.4k
        set_parents();
19077
20.4k
        assert_invariant();
19078
20.4k
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<char const*&, char const*, 0>(char const*&)
19079
19080
    /*!
19081
    @brief create a JSON value from an existing one
19082
19083
    This is a constructor for existing @ref basic_json types.
19084
    It does not hijack copy/move constructors, since the parameter has different
19085
    template arguments than the current ones.
19086
19087
    The constructor tries to convert the internal @ref m_value of the parameter.
19088
19089
    @tparam BasicJsonType a type such that:
19090
    - @a BasicJsonType is a @ref basic_json type.
19091
    - @a BasicJsonType has different template arguments than @ref basic_json_t.
19092
19093
    @param[in] val the @ref basic_json value to be converted.
19094
19095
    @complexity Usually linear in the size of the passed @a val, also
19096
                depending on the implementation of the called `to_json()`
19097
                method.
19098
19099
    @exceptionsafety Depends on the called constructor. For types directly
19100
    supported by the library (i.e., all types for which no `to_json()` function
19101
    was provided), strong guarantee holds: if an exception is thrown, there are
19102
    no changes to any JSON value.
19103
19104
    @since version 3.2.0
19105
    */
19106
    template < typename BasicJsonType,
19107
               detail::enable_if_t <
19108
                   detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19109
    basic_json(const BasicJsonType& val)
19110
    {
19111
        using other_boolean_t = typename BasicJsonType::boolean_t;
19112
        using other_number_float_t = typename BasicJsonType::number_float_t;
19113
        using other_number_integer_t = typename BasicJsonType::number_integer_t;
19114
        using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19115
        using other_string_t = typename BasicJsonType::string_t;
19116
        using other_object_t = typename BasicJsonType::object_t;
19117
        using other_array_t = typename BasicJsonType::array_t;
19118
        using other_binary_t = typename BasicJsonType::binary_t;
19119
19120
        switch (val.type())
19121
        {
19122
            case value_t::boolean:
19123
                JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19124
                break;
19125
            case value_t::number_float:
19126
                JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19127
                break;
19128
            case value_t::number_integer:
19129
                JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19130
                break;
19131
            case value_t::number_unsigned:
19132
                JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19133
                break;
19134
            case value_t::string:
19135
                JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19136
                break;
19137
            case value_t::object:
19138
                JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19139
                break;
19140
            case value_t::array:
19141
                JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19142
                break;
19143
            case value_t::binary:
19144
                JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19145
                break;
19146
            case value_t::null:
19147
                *this = nullptr;
19148
                break;
19149
            case value_t::discarded:
19150
                m_type = value_t::discarded;
19151
                break;
19152
            default:            // LCOV_EXCL_LINE
19153
                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19154
        }
19155
        set_parents();
19156
        assert_invariant();
19157
    }
19158
19159
    /*!
19160
    @brief create a container (array or object) from an initializer list
19161
19162
    Creates a JSON value of type array or object from the passed initializer
19163
    list @a init. In case @a type_deduction is `true` (default), the type of
19164
    the JSON value to be created is deducted from the initializer list @a init
19165
    according to the following rules:
19166
19167
    1. If the list is empty, an empty JSON object value `{}` is created.
19168
    2. If the list consists of pairs whose first element is a string, a JSON
19169
       object value is created where the first elements of the pairs are
19170
       treated as keys and the second elements are as values.
19171
    3. In all other cases, an array is created.
19172
19173
    The rules aim to create the best fit between a C++ initializer list and
19174
    JSON values. The rationale is as follows:
19175
19176
    1. The empty initializer list is written as `{}` which is exactly an empty
19177
       JSON object.
19178
    2. C++ has no way of describing mapped types other than to list a list of
19179
       pairs. As JSON requires that keys must be of type string, rule 2 is the
19180
       weakest constraint one can pose on initializer lists to interpret them
19181
       as an object.
19182
    3. In all other cases, the initializer list could not be interpreted as
19183
       JSON object type, so interpreting it as JSON array type is safe.
19184
19185
    With the rules described above, the following JSON values cannot be
19186
    expressed by an initializer list:
19187
19188
    - the empty array (`[]`): use @ref array(initializer_list_t)
19189
      with an empty initializer list in this case
19190
    - arrays whose elements satisfy rule 2: use @ref
19191
      array(initializer_list_t) with the same initializer list
19192
      in this case
19193
19194
    @note When used without parentheses around an empty initializer list, @ref
19195
    basic_json() is called instead of this function, yielding the JSON null
19196
    value.
19197
19198
    @param[in] init  initializer list with JSON values
19199
19200
    @param[in] type_deduction internal parameter; when set to `true`, the type
19201
    of the JSON value is deducted from the initializer list @a init; when set
19202
    to `false`, the type provided via @a manual_type is forced. This mode is
19203
    used by the functions @ref array(initializer_list_t) and
19204
    @ref object(initializer_list_t).
19205
19206
    @param[in] manual_type internal parameter; when @a type_deduction is set
19207
    to `false`, the created JSON value will use the provided type (only @ref
19208
    value_t::array and @ref value_t::object are valid); when @a type_deduction
19209
    is set to `true`, this parameter has no effect
19210
19211
    @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
19212
    `value_t::object`, but @a init contains an element which is not a pair
19213
    whose first element is a string. In this case, the constructor could not
19214
    create an object. If @a type_deduction would have be `true`, an array
19215
    would have been created. See @ref object(initializer_list_t)
19216
    for an example.
19217
19218
    @complexity Linear in the size of the initializer list @a init.
19219
19220
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19221
    changes to any JSON value.
19222
19223
    @liveexample{The example below shows how JSON values are created from
19224
    initializer lists.,basic_json__list_init_t}
19225
19226
    @sa see @ref array(initializer_list_t) -- create a JSON array
19227
    value from an initializer list
19228
    @sa see @ref object(initializer_list_t) -- create a JSON object
19229
    value from an initializer list
19230
19231
    @since version 1.0.0
19232
    */
19233
    basic_json(initializer_list_t init,
19234
               bool type_deduction = true,
19235
               value_t manual_type = value_t::array)
19236
0
    {
19237
        // check if each element is an array with two elements whose first
19238
        // element is a string
19239
0
        bool is_an_object = std::all_of(init.begin(), init.end(),
19240
0
                                        [](const detail::json_ref<basic_json>& element_ref)
19241
0
        {
19242
0
            return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19243
0
        });
19244
19245
        // adjust type if type deduction is not wanted
19246
0
        if (!type_deduction)
19247
0
        {
19248
            // if array is wanted, do not create an object though possible
19249
0
            if (manual_type == value_t::array)
19250
0
            {
19251
0
                is_an_object = false;
19252
0
            }
19253
19254
            // if object is wanted but impossible, throw an exception
19255
0
            if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19256
0
            {
19257
0
                JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19258
0
            }
19259
0
        }
19260
19261
0
        if (is_an_object)
19262
0
        {
19263
            // the initializer list is a list of pairs -> create object
19264
0
            m_type = value_t::object;
19265
0
            m_value = value_t::object;
19266
19267
0
            for (auto& element_ref : init)
19268
0
            {
19269
0
                auto element = element_ref.moved_or_copied();
19270
0
                m_value.object->emplace(
19271
0
                    std::move(*((*element.m_value.array)[0].m_value.string)),
19272
0
                    std::move((*element.m_value.array)[1]));
19273
0
            }
19274
0
        }
19275
0
        else
19276
0
        {
19277
            // the initializer list describes an array -> create array
19278
0
            m_type = value_t::array;
19279
0
            m_value.array = create<array_t>(init.begin(), init.end());
19280
0
        }
19281
19282
0
        set_parents();
19283
0
        assert_invariant();
19284
0
    }
19285
19286
    /*!
19287
    @brief explicitly create a binary array (without subtype)
19288
19289
    Creates a JSON binary array value from a given binary container. Binary
19290
    values are part of various binary formats, such as CBOR, MessagePack, and
19291
    BSON. This constructor is used to create a value for serialization to those
19292
    formats.
19293
19294
    @note Note, this function exists because of the difficulty in correctly
19295
    specifying the correct template overload in the standard value ctor, as both
19296
    JSON arrays and JSON binary arrays are backed with some form of a
19297
    `std::vector`. Because JSON binary arrays are a non-standard extension it
19298
    was decided that it would be best to prevent automatic initialization of a
19299
    binary array type, for backwards compatibility and so it does not happen on
19300
    accident.
19301
19302
    @param[in] init container containing bytes to use as binary type
19303
19304
    @return JSON binary array value
19305
19306
    @complexity Linear in the size of @a init.
19307
19308
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19309
    changes to any JSON value.
19310
19311
    @since version 3.8.0
19312
    */
19313
    JSON_HEDLEY_WARN_UNUSED_RESULT
19314
    static basic_json binary(const typename binary_t::container_type& init)
19315
    {
19316
        auto res = basic_json();
19317
        res.m_type = value_t::binary;
19318
        res.m_value = init;
19319
        return res;
19320
    }
19321
19322
    /*!
19323
    @brief explicitly create a binary array (with subtype)
19324
19325
    Creates a JSON binary array value from a given binary container. Binary
19326
    values are part of various binary formats, such as CBOR, MessagePack, and
19327
    BSON. This constructor is used to create a value for serialization to those
19328
    formats.
19329
19330
    @note Note, this function exists because of the difficulty in correctly
19331
    specifying the correct template overload in the standard value ctor, as both
19332
    JSON arrays and JSON binary arrays are backed with some form of a
19333
    `std::vector`. Because JSON binary arrays are a non-standard extension it
19334
    was decided that it would be best to prevent automatic initialization of a
19335
    binary array type, for backwards compatibility and so it does not happen on
19336
    accident.
19337
19338
    @param[in] init container containing bytes to use as binary type
19339
    @param[in] subtype subtype to use in MessagePack and BSON
19340
19341
    @return JSON binary array value
19342
19343
    @complexity Linear in the size of @a init.
19344
19345
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19346
    changes to any JSON value.
19347
19348
    @since version 3.8.0
19349
    */
19350
    JSON_HEDLEY_WARN_UNUSED_RESULT
19351
    static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19352
    {
19353
        auto res = basic_json();
19354
        res.m_type = value_t::binary;
19355
        res.m_value = binary_t(init, subtype);
19356
        return res;
19357
    }
19358
19359
    /// @copydoc binary(const typename binary_t::container_type&)
19360
    JSON_HEDLEY_WARN_UNUSED_RESULT
19361
    static basic_json binary(typename binary_t::container_type&& init)
19362
    {
19363
        auto res = basic_json();
19364
        res.m_type = value_t::binary;
19365
        res.m_value = std::move(init);
19366
        return res;
19367
    }
19368
19369
    /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type)
19370
    JSON_HEDLEY_WARN_UNUSED_RESULT
19371
    static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19372
    {
19373
        auto res = basic_json();
19374
        res.m_type = value_t::binary;
19375
        res.m_value = binary_t(std::move(init), subtype);
19376
        return res;
19377
    }
19378
19379
    /*!
19380
    @brief explicitly create an array from an initializer list
19381
19382
    Creates a JSON array value from a given initializer list. That is, given a
19383
    list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
19384
    initializer list is empty, the empty array `[]` is created.
19385
19386
    @note This function is only needed to express two edge cases that cannot
19387
    be realized with the initializer list constructor (@ref
19388
    basic_json(initializer_list_t, bool, value_t)). These cases
19389
    are:
19390
    1. creating an array whose elements are all pairs whose first element is a
19391
    string -- in this case, the initializer list constructor would create an
19392
    object, taking the first elements as keys
19393
    2. creating an empty array -- passing the empty initializer list to the
19394
    initializer list constructor yields an empty object
19395
19396
    @param[in] init  initializer list with JSON values to create an array from
19397
    (optional)
19398
19399
    @return JSON array value
19400
19401
    @complexity Linear in the size of @a init.
19402
19403
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19404
    changes to any JSON value.
19405
19406
    @liveexample{The following code shows an example for the `array`
19407
    function.,array}
19408
19409
    @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19410
    create a JSON value from an initializer list
19411
    @sa see @ref object(initializer_list_t) -- create a JSON object
19412
    value from an initializer list
19413
19414
    @since version 1.0.0
19415
    */
19416
    JSON_HEDLEY_WARN_UNUSED_RESULT
19417
    static basic_json array(initializer_list_t init = {})
19418
    {
19419
        return basic_json(init, false, value_t::array);
19420
    }
19421
19422
    /*!
19423
    @brief explicitly create an object from an initializer list
19424
19425
    Creates a JSON object value from a given initializer list. The initializer
19426
    lists elements must be pairs, and their first elements must be strings. If
19427
    the initializer list is empty, the empty object `{}` is created.
19428
19429
    @note This function is only added for symmetry reasons. In contrast to the
19430
    related function @ref array(initializer_list_t), there are
19431
    no cases which can only be expressed by this function. That is, any
19432
    initializer list @a init can also be passed to the initializer list
19433
    constructor @ref basic_json(initializer_list_t, bool, value_t).
19434
19435
    @param[in] init  initializer list to create an object from (optional)
19436
19437
    @return JSON object value
19438
19439
    @throw type_error.301 if @a init is not a list of pairs whose first
19440
    elements are strings. In this case, no object can be created. When such a
19441
    value is passed to @ref basic_json(initializer_list_t, bool, value_t),
19442
    an array would have been created from the passed initializer list @a init.
19443
    See example below.
19444
19445
    @complexity Linear in the size of @a init.
19446
19447
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19448
    changes to any JSON value.
19449
19450
    @liveexample{The following code shows an example for the `object`
19451
    function.,object}
19452
19453
    @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19454
    create a JSON value from an initializer list
19455
    @sa see @ref array(initializer_list_t) -- create a JSON array
19456
    value from an initializer list
19457
19458
    @since version 1.0.0
19459
    */
19460
    JSON_HEDLEY_WARN_UNUSED_RESULT
19461
    static basic_json object(initializer_list_t init = {})
19462
0
    {
19463
0
        return basic_json(init, false, value_t::object);
19464
0
    }
19465
19466
    /*!
19467
    @brief construct an array with count copies of given value
19468
19469
    Constructs a JSON array value by creating @a cnt copies of a passed value.
19470
    In case @a cnt is `0`, an empty array is created.
19471
19472
    @param[in] cnt  the number of JSON copies of @a val to create
19473
    @param[in] val  the JSON value to copy
19474
19475
    @post `std::distance(begin(),end()) == cnt` holds.
19476
19477
    @complexity Linear in @a cnt.
19478
19479
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19480
    changes to any JSON value.
19481
19482
    @liveexample{The following code shows examples for the @ref
19483
    basic_json(size_type\, const basic_json&)
19484
    constructor.,basic_json__size_type_basic_json}
19485
19486
    @since version 1.0.0
19487
    */
19488
    basic_json(size_type cnt, const basic_json& val)
19489
        : m_type(value_t::array)
19490
    {
19491
        m_value.array = create<array_t>(cnt, val);
19492
        set_parents();
19493
        assert_invariant();
19494
    }
19495
19496
    /*!
19497
    @brief construct a JSON container given an iterator range
19498
19499
    Constructs the JSON value with the contents of the range `[first, last)`.
19500
    The semantics depends on the different types a JSON value can have:
19501
    - In case of a null type, invalid_iterator.206 is thrown.
19502
    - In case of other primitive types (number, boolean, or string), @a first
19503
      must be `begin()` and @a last must be `end()`. In this case, the value is
19504
      copied. Otherwise, invalid_iterator.204 is thrown.
19505
    - In case of structured types (array, object), the constructor behaves as
19506
      similar versions for `std::vector` or `std::map`; that is, a JSON array
19507
      or object is constructed from the values in the range.
19508
19509
    @tparam InputIT an input iterator type (@ref iterator or @ref
19510
    const_iterator)
19511
19512
    @param[in] first begin of the range to copy from (included)
19513
    @param[in] last end of the range to copy from (excluded)
19514
19515
    @pre Iterators @a first and @a last must be initialized. **This
19516
         precondition is enforced with an assertion (see warning).** If
19517
         assertions are switched off, a violation of this precondition yields
19518
         undefined behavior.
19519
19520
    @pre Range `[first, last)` is valid. Usually, this precondition cannot be
19521
         checked efficiently. Only certain edge cases are detected; see the
19522
         description of the exceptions below. A violation of this precondition
19523
         yields undefined behavior.
19524
19525
    @warning A precondition is enforced with a runtime assertion that will
19526
             result in calling `std::abort` if this precondition is not met.
19527
             Assertions can be disabled by defining `NDEBUG` at compile time.
19528
             See https://en.cppreference.com/w/cpp/error/assert for more
19529
             information.
19530
19531
    @throw invalid_iterator.201 if iterators @a first and @a last are not
19532
    compatible (i.e., do not belong to the same JSON value). In this case,
19533
    the range `[first, last)` is undefined.
19534
    @throw invalid_iterator.204 if iterators @a first and @a last belong to a
19535
    primitive type (number, boolean, or string), but @a first does not point
19536
    to the first element any more. In this case, the range `[first, last)` is
19537
    undefined. See example code below.
19538
    @throw invalid_iterator.206 if iterators @a first and @a last belong to a
19539
    null value. In this case, the range `[first, last)` is undefined.
19540
19541
    @complexity Linear in distance between @a first and @a last.
19542
19543
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19544
    changes to any JSON value.
19545
19546
    @liveexample{The example below shows several ways to create JSON values by
19547
    specifying a subrange with iterators.,basic_json__InputIt_InputIt}
19548
19549
    @since version 1.0.0
19550
    */
19551
    template < class InputIT, typename std::enable_if <
19552
                   std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19553
                   std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19554
    basic_json(InputIT first, InputIT last)
19555
    {
19556
        JSON_ASSERT(first.m_object != nullptr);
19557
        JSON_ASSERT(last.m_object != nullptr);
19558
19559
        // make sure iterator fits the current value
19560
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19561
        {
19562
            JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19563
        }
19564
19565
        // copy type from first iterator
19566
        m_type = first.m_object->m_type;
19567
19568
        // check if iterator range is complete for primitive values
19569
        switch (m_type)
19570
        {
19571
            case value_t::boolean:
19572
            case value_t::number_float:
19573
            case value_t::number_integer:
19574
            case value_t::number_unsigned:
19575
            case value_t::string:
19576
            {
19577
                if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19578
                                         || !last.m_it.primitive_iterator.is_end()))
19579
                {
19580
                    JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19581
                }
19582
                break;
19583
            }
19584
19585
            case value_t::null:
19586
            case value_t::object:
19587
            case value_t::array:
19588
            case value_t::binary:
19589
            case value_t::discarded:
19590
            default:
19591
                break;
19592
        }
19593
19594
        switch (m_type)
19595
        {
19596
            case value_t::number_integer:
19597
            {
19598
                m_value.number_integer = first.m_object->m_value.number_integer;
19599
                break;
19600
            }
19601
19602
            case value_t::number_unsigned:
19603
            {
19604
                m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19605
                break;
19606
            }
19607
19608
            case value_t::number_float:
19609
            {
19610
                m_value.number_float = first.m_object->m_value.number_float;
19611
                break;
19612
            }
19613
19614
            case value_t::boolean:
19615
            {
19616
                m_value.boolean = first.m_object->m_value.boolean;
19617
                break;
19618
            }
19619
19620
            case value_t::string:
19621
            {
19622
                m_value = *first.m_object->m_value.string;
19623
                break;
19624
            }
19625
19626
            case value_t::object:
19627
            {
19628
                m_value.object = create<object_t>(first.m_it.object_iterator,
19629
                                                  last.m_it.object_iterator);
19630
                break;
19631
            }
19632
19633
            case value_t::array:
19634
            {
19635
                m_value.array = create<array_t>(first.m_it.array_iterator,
19636
                                                last.m_it.array_iterator);
19637
                break;
19638
            }
19639
19640
            case value_t::binary:
19641
            {
19642
                m_value = *first.m_object->m_value.binary;
19643
                break;
19644
            }
19645
19646
            case value_t::null:
19647
            case value_t::discarded:
19648
            default:
19649
                JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19650
        }
19651
19652
        set_parents();
19653
        assert_invariant();
19654
    }
19655
19656
19657
    ///////////////////////////////////////
19658
    // other constructors and destructor //
19659
    ///////////////////////////////////////
19660
19661
    template<typename JsonRef,
19662
             detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19663
                                 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19664
0
    basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19665
19666
    /*!
19667
    @brief copy constructor
19668
19669
    Creates a copy of a given JSON value.
19670
19671
    @param[in] other  the JSON value to copy
19672
19673
    @post `*this == other`
19674
19675
    @complexity Linear in the size of @a other.
19676
19677
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19678
    changes to any JSON value.
19679
19680
    @requirement This function helps `basic_json` satisfying the
19681
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19682
    requirements:
19683
    - The complexity is linear.
19684
    - As postcondition, it holds: `other == basic_json(other)`.
19685
19686
    @liveexample{The following code shows an example for the copy
19687
    constructor.,basic_json__basic_json}
19688
19689
    @since version 1.0.0
19690
    */
19691
    basic_json(const basic_json& other)
19692
        : m_type(other.m_type)
19693
0
    {
19694
        // check of passed value is valid
19695
0
        other.assert_invariant();
19696
19697
0
        switch (m_type)
19698
0
        {
19699
0
            case value_t::object:
19700
0
            {
19701
0
                m_value = *other.m_value.object;
19702
0
                break;
19703
0
            }
19704
19705
0
            case value_t::array:
19706
0
            {
19707
0
                m_value = *other.m_value.array;
19708
0
                break;
19709
0
            }
19710
19711
0
            case value_t::string:
19712
0
            {
19713
0
                m_value = *other.m_value.string;
19714
0
                break;
19715
0
            }
19716
19717
0
            case value_t::boolean:
19718
0
            {
19719
0
                m_value = other.m_value.boolean;
19720
0
                break;
19721
0
            }
19722
19723
0
            case value_t::number_integer:
19724
0
            {
19725
0
                m_value = other.m_value.number_integer;
19726
0
                break;
19727
0
            }
19728
19729
0
            case value_t::number_unsigned:
19730
0
            {
19731
0
                m_value = other.m_value.number_unsigned;
19732
0
                break;
19733
0
            }
19734
19735
0
            case value_t::number_float:
19736
0
            {
19737
0
                m_value = other.m_value.number_float;
19738
0
                break;
19739
0
            }
19740
19741
0
            case value_t::binary:
19742
0
            {
19743
0
                m_value = *other.m_value.binary;
19744
0
                break;
19745
0
            }
19746
19747
0
            case value_t::null:
19748
0
            case value_t::discarded:
19749
0
            default:
19750
0
                break;
19751
0
        }
19752
19753
0
        set_parents();
19754
0
        assert_invariant();
19755
0
    }
19756
19757
    /*!
19758
    @brief move constructor
19759
19760
    Move constructor. Constructs a JSON value with the contents of the given
19761
    value @a other using move semantics. It "steals" the resources from @a
19762
    other and leaves it as JSON null value.
19763
19764
    @param[in,out] other  value to move to this object
19765
19766
    @post `*this` has the same value as @a other before the call.
19767
    @post @a other is a JSON null value.
19768
19769
    @complexity Constant.
19770
19771
    @exceptionsafety No-throw guarantee: this constructor never throws
19772
    exceptions.
19773
19774
    @requirement This function helps `basic_json` satisfying the
19775
    [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
19776
    requirements.
19777
19778
    @liveexample{The code below shows the move constructor explicitly called
19779
    via std::move.,basic_json__moveconstructor}
19780
19781
    @since version 1.0.0
19782
    */
19783
    basic_json(basic_json&& other) noexcept
19784
        : m_type(std::move(other.m_type)),
19785
          m_value(std::move(other.m_value))
19786
48.4M
    {
19787
        // check that passed value is valid
19788
48.4M
        other.assert_invariant(false);
19789
19790
        // invalidate payload
19791
48.4M
        other.m_type = value_t::null;
19792
48.4M
        other.m_value = {};
19793
19794
48.4M
        set_parents();
19795
48.4M
        assert_invariant();
19796
48.4M
    }
19797
19798
    /*!
19799
    @brief copy assignment
19800
19801
    Copy assignment operator. Copies a JSON value via the "copy and swap"
19802
    strategy: It is expressed in terms of the copy constructor, destructor,
19803
    and the `swap()` member function.
19804
19805
    @param[in] other  value to copy from
19806
19807
    @complexity Linear.
19808
19809
    @requirement This function helps `basic_json` satisfying the
19810
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19811
    requirements:
19812
    - The complexity is linear.
19813
19814
    @liveexample{The code below shows and example for the copy assignment. It
19815
    creates a copy of value `a` which is then swapped with `b`. Finally\, the
19816
    copy of `a` (which is the null value after the swap) is
19817
    destroyed.,basic_json__copyassignment}
19818
19819
    @since version 1.0.0
19820
    */
19821
    basic_json& operator=(basic_json other) noexcept (
19822
        std::is_nothrow_move_constructible<value_t>::value&&
19823
        std::is_nothrow_move_assignable<value_t>::value&&
19824
        std::is_nothrow_move_constructible<json_value>::value&&
19825
        std::is_nothrow_move_assignable<json_value>::value
19826
    )
19827
491k
    {
19828
        // check that passed value is valid
19829
491k
        other.assert_invariant();
19830
19831
491k
        using std::swap;
19832
491k
        swap(m_type, other.m_type);
19833
491k
        swap(m_value, other.m_value);
19834
19835
491k
        set_parents();
19836
491k
        assert_invariant();
19837
491k
        return *this;
19838
491k
    }
19839
19840
    /*!
19841
    @brief destructor
19842
19843
    Destroys the JSON value and frees all allocated memory.
19844
19845
    @complexity Linear.
19846
19847
    @requirement This function helps `basic_json` satisfying the
19848
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19849
    requirements:
19850
    - The complexity is linear.
19851
    - All stored elements are destroyed and all memory is freed.
19852
19853
    @since version 1.0.0
19854
    */
19855
    ~basic_json() noexcept
19856
62.4M
    {
19857
62.4M
        assert_invariant(false);
19858
62.4M
        m_value.destroy(m_type);
19859
62.4M
    }
19860
19861
    /// @}
19862
19863
  public:
19864
    ///////////////////////
19865
    // object inspection //
19866
    ///////////////////////
19867
19868
    /// @name object inspection
19869
    /// Functions to inspect the type of a JSON value.
19870
    /// @{
19871
19872
    /*!
19873
    @brief serialization
19874
19875
    Serialization function for JSON values. The function tries to mimic
19876
    Python's `json.dumps()` function, and currently supports its @a indent
19877
    and @a ensure_ascii parameters.
19878
19879
    @param[in] indent If indent is nonnegative, then array elements and object
19880
    members will be pretty-printed with that indent level. An indent level of
19881
    `0` will only insert newlines. `-1` (the default) selects the most compact
19882
    representation.
19883
    @param[in] indent_char The character to use for indentation if @a indent is
19884
    greater than `0`. The default is ` ` (space).
19885
    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
19886
    in the output are escaped with `\uXXXX` sequences, and the result consists
19887
    of ASCII characters only.
19888
    @param[in] error_handler  how to react on decoding errors; there are three
19889
    possible values: `strict` (throws and exception in case a decoding error
19890
    occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
19891
    and `ignore` (ignore invalid UTF-8 sequences during serialization; all
19892
    bytes are copied to the output unchanged).
19893
19894
    @return string containing the serialization of the JSON value
19895
19896
    @throw type_error.316 if a string stored inside the JSON value is not
19897
                          UTF-8 encoded and @a error_handler is set to strict
19898
19899
    @note Binary values are serialized as object containing two keys:
19900
      - "bytes": an array of bytes as integers
19901
      - "subtype": the subtype as integer or "null" if the binary has no subtype
19902
19903
    @complexity Linear.
19904
19905
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19906
    changes in the JSON value.
19907
19908
    @liveexample{The following example shows the effect of different @a indent\,
19909
    @a indent_char\, and @a ensure_ascii parameters to the result of the
19910
    serialization.,dump}
19911
19912
    @see https://docs.python.org/2/library/json.html#json.dump
19913
19914
    @since version 1.0.0; indentation character @a indent_char, option
19915
           @a ensure_ascii and exceptions added in version 3.0.0; error
19916
           handlers added in version 3.4.0; serialization of binary values added
19917
           in version 3.8.0.
19918
    */
19919
    string_t dump(const int indent = -1,
19920
                  const char indent_char = ' ',
19921
                  const bool ensure_ascii = false,
19922
                  const error_handler_t error_handler = error_handler_t::strict) const
19923
0
    {
19924
0
        string_t result;
19925
0
        serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19926
19927
0
        if (indent >= 0)
19928
0
        {
19929
0
            s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19930
0
        }
19931
0
        else
19932
0
        {
19933
0
            s.dump(*this, false, ensure_ascii, 0);
19934
0
        }
19935
19936
0
        return result;
19937
0
    }
19938
19939
    /*!
19940
    @brief return the type of the JSON value (explicit)
19941
19942
    Return the type of the JSON value as a value from the @ref value_t
19943
    enumeration.
19944
19945
    @return the type of the JSON value
19946
            Value type                | return value
19947
            ------------------------- | -------------------------
19948
            null                      | value_t::null
19949
            boolean                   | value_t::boolean
19950
            string                    | value_t::string
19951
            number (integer)          | value_t::number_integer
19952
            number (unsigned integer) | value_t::number_unsigned
19953
            number (floating-point)   | value_t::number_float
19954
            object                    | value_t::object
19955
            array                     | value_t::array
19956
            binary                    | value_t::binary
19957
            discarded                 | value_t::discarded
19958
19959
    @complexity Constant.
19960
19961
    @exceptionsafety No-throw guarantee: this member function never throws
19962
    exceptions.
19963
19964
    @liveexample{The following code exemplifies `type()` for all JSON
19965
    types.,type}
19966
19967
    @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
19968
    @sa see @ref type_name() -- return the type as string
19969
19970
    @since version 1.0.0
19971
    */
19972
    constexpr value_t type() const noexcept
19973
1.79M
    {
19974
1.79M
        return m_type;
19975
1.79M
    }
19976
19977
    /*!
19978
    @brief return whether type is primitive
19979
19980
    This function returns true if and only if the JSON type is primitive
19981
    (string, number, boolean, or null).
19982
19983
    @return `true` if type is primitive (string, number, boolean, or null),
19984
    `false` otherwise.
19985
19986
    @complexity Constant.
19987
19988
    @exceptionsafety No-throw guarantee: this member function never throws
19989
    exceptions.
19990
19991
    @liveexample{The following code exemplifies `is_primitive()` for all JSON
19992
    types.,is_primitive}
19993
19994
    @sa see @ref is_structured() -- returns whether JSON value is structured
19995
    @sa see @ref is_null() -- returns whether JSON value is `null`
19996
    @sa see @ref is_string() -- returns whether JSON value is a string
19997
    @sa see @ref is_boolean() -- returns whether JSON value is a boolean
19998
    @sa see @ref is_number() -- returns whether JSON value is a number
19999
    @sa see @ref is_binary() -- returns whether JSON value is a binary array
20000
20001
    @since version 1.0.0
20002
    */
20003
    constexpr bool is_primitive() const noexcept
20004
    {
20005
        return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20006
    }
20007
20008
    /*!
20009
    @brief return whether type is structured
20010
20011
    This function returns true if and only if the JSON type is structured
20012
    (array or object).
20013
20014
    @return `true` if type is structured (array or object), `false` otherwise.
20015
20016
    @complexity Constant.
20017
20018
    @exceptionsafety No-throw guarantee: this member function never throws
20019
    exceptions.
20020
20021
    @liveexample{The following code exemplifies `is_structured()` for all JSON
20022
    types.,is_structured}
20023
20024
    @sa see @ref is_primitive() -- returns whether value is primitive
20025
    @sa see @ref is_array() -- returns whether value is an array
20026
    @sa see @ref is_object() -- returns whether value is an object
20027
20028
    @since version 1.0.0
20029
    */
20030
    constexpr bool is_structured() const noexcept
20031
0
    {
20032
0
        return is_array() || is_object();
20033
0
    }
20034
20035
    /*!
20036
    @brief return whether value is null
20037
20038
    This function returns true if and only if the JSON value is null.
20039
20040
    @return `true` if type is null, `false` otherwise.
20041
20042
    @complexity Constant.
20043
20044
    @exceptionsafety No-throw guarantee: this member function never throws
20045
    exceptions.
20046
20047
    @liveexample{The following code exemplifies `is_null()` for all JSON
20048
    types.,is_null}
20049
20050
    @since version 1.0.0
20051
    */
20052
    constexpr bool is_null() const noexcept
20053
0
    {
20054
0
        return m_type == value_t::null;
20055
0
    }
20056
20057
    /*!
20058
    @brief return whether value is a boolean
20059
20060
    This function returns true if and only if the JSON value is a boolean.
20061
20062
    @return `true` if type is boolean, `false` otherwise.
20063
20064
    @complexity Constant.
20065
20066
    @exceptionsafety No-throw guarantee: this member function never throws
20067
    exceptions.
20068
20069
    @liveexample{The following code exemplifies `is_boolean()` for all JSON
20070
    types.,is_boolean}
20071
20072
    @since version 1.0.0
20073
    */
20074
    constexpr bool is_boolean() const noexcept
20075
1.88k
    {
20076
1.88k
        return m_type == value_t::boolean;
20077
1.88k
    }
20078
20079
    /*!
20080
    @brief return whether value is a number
20081
20082
    This function returns true if and only if the JSON value is a number. This
20083
    includes both integer (signed and unsigned) and floating-point values.
20084
20085
    @return `true` if type is number (regardless whether integer, unsigned
20086
    integer or floating-type), `false` otherwise.
20087
20088
    @complexity Constant.
20089
20090
    @exceptionsafety No-throw guarantee: this member function never throws
20091
    exceptions.
20092
20093
    @liveexample{The following code exemplifies `is_number()` for all JSON
20094
    types.,is_number}
20095
20096
    @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20097
    integer number
20098
    @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20099
    number
20100
    @sa see @ref is_number_float() -- check if value is a floating-point number
20101
20102
    @since version 1.0.0
20103
    */
20104
    constexpr bool is_number() const noexcept
20105
747k
    {
20106
747k
        return is_number_integer() || is_number_float();
20107
747k
    }
20108
20109
    /*!
20110
    @brief return whether value is an integer number
20111
20112
    This function returns true if and only if the JSON value is a signed or
20113
    unsigned integer number. This excludes floating-point values.
20114
20115
    @return `true` if type is an integer or unsigned integer number, `false`
20116
    otherwise.
20117
20118
    @complexity Constant.
20119
20120
    @exceptionsafety No-throw guarantee: this member function never throws
20121
    exceptions.
20122
20123
    @liveexample{The following code exemplifies `is_number_integer()` for all
20124
    JSON types.,is_number_integer}
20125
20126
    @sa see @ref is_number() -- check if value is a number
20127
    @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20128
    number
20129
    @sa see @ref is_number_float() -- check if value is a floating-point number
20130
20131
    @since version 1.0.0
20132
    */
20133
    constexpr bool is_number_integer() const noexcept
20134
754k
    {
20135
754k
        return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20136
754k
    }
20137
20138
    /*!
20139
    @brief return whether value is an unsigned integer number
20140
20141
    This function returns true if and only if the JSON value is an unsigned
20142
    integer number. This excludes floating-point and signed integer values.
20143
20144
    @return `true` if type is an unsigned integer number, `false` otherwise.
20145
20146
    @complexity Constant.
20147
20148
    @exceptionsafety No-throw guarantee: this member function never throws
20149
    exceptions.
20150
20151
    @liveexample{The following code exemplifies `is_number_unsigned()` for all
20152
    JSON types.,is_number_unsigned}
20153
20154
    @sa see @ref is_number() -- check if value is a number
20155
    @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20156
    integer number
20157
    @sa see @ref is_number_float() -- check if value is a floating-point number
20158
20159
    @since version 2.0.0
20160
    */
20161
    constexpr bool is_number_unsigned() const noexcept
20162
2.09M
    {
20163
2.09M
        return m_type == value_t::number_unsigned;
20164
2.09M
    }
20165
20166
    /*!
20167
    @brief return whether value is a floating-point number
20168
20169
    This function returns true if and only if the JSON value is a
20170
    floating-point number. This excludes signed and unsigned integer values.
20171
20172
    @return `true` if type is a floating-point number, `false` otherwise.
20173
20174
    @complexity Constant.
20175
20176
    @exceptionsafety No-throw guarantee: this member function never throws
20177
    exceptions.
20178
20179
    @liveexample{The following code exemplifies `is_number_float()` for all
20180
    JSON types.,is_number_float}
20181
20182
    @sa see @ref is_number() -- check if value is number
20183
    @sa see @ref is_number_integer() -- check if value is an integer number
20184
    @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20185
    number
20186
20187
    @since version 1.0.0
20188
    */
20189
    constexpr bool is_number_float() const noexcept
20190
13.0k
    {
20191
13.0k
        return m_type == value_t::number_float;
20192
13.0k
    }
20193
20194
    /*!
20195
    @brief return whether value is an object
20196
20197
    This function returns true if and only if the JSON value is an object.
20198
20199
    @return `true` if type is object, `false` otherwise.
20200
20201
    @complexity Constant.
20202
20203
    @exceptionsafety No-throw guarantee: this member function never throws
20204
    exceptions.
20205
20206
    @liveexample{The following code exemplifies `is_object()` for all JSON
20207
    types.,is_object}
20208
20209
    @since version 1.0.0
20210
    */
20211
    constexpr bool is_object() const noexcept
20212
24.4M
    {
20213
24.4M
        return m_type == value_t::object;
20214
24.4M
    }
20215
20216
    /*!
20217
    @brief return whether value is an array
20218
20219
    This function returns true if and only if the JSON value is an array.
20220
20221
    @return `true` if type is array, `false` otherwise.
20222
20223
    @complexity Constant.
20224
20225
    @exceptionsafety No-throw guarantee: this member function never throws
20226
    exceptions.
20227
20228
    @liveexample{The following code exemplifies `is_array()` for all JSON
20229
    types.,is_array}
20230
20231
    @since version 1.0.0
20232
    */
20233
    constexpr bool is_array() const noexcept
20234
40.6M
    {
20235
40.6M
        return m_type == value_t::array;
20236
40.6M
    }
20237
20238
    /*!
20239
    @brief return whether value is a string
20240
20241
    This function returns true if and only if the JSON value is a string.
20242
20243
    @return `true` if type is string, `false` otherwise.
20244
20245
    @complexity Constant.
20246
20247
    @exceptionsafety No-throw guarantee: this member function never throws
20248
    exceptions.
20249
20250
    @liveexample{The following code exemplifies `is_string()` for all JSON
20251
    types.,is_string}
20252
20253
    @since version 1.0.0
20254
    */
20255
    constexpr bool is_string() const noexcept
20256
146k
    {
20257
146k
        return m_type == value_t::string;
20258
146k
    }
20259
20260
    /*!
20261
    @brief return whether value is a binary array
20262
20263
    This function returns true if and only if the JSON value is a binary array.
20264
20265
    @return `true` if type is binary array, `false` otherwise.
20266
20267
    @complexity Constant.
20268
20269
    @exceptionsafety No-throw guarantee: this member function never throws
20270
    exceptions.
20271
20272
    @liveexample{The following code exemplifies `is_binary()` for all JSON
20273
    types.,is_binary}
20274
20275
    @since version 3.8.0
20276
    */
20277
    constexpr bool is_binary() const noexcept
20278
0
    {
20279
0
        return m_type == value_t::binary;
20280
0
    }
20281
20282
    /*!
20283
    @brief return whether value is discarded
20284
20285
    This function returns true if and only if the JSON value was discarded
20286
    during parsing with a callback function (see @ref parser_callback_t).
20287
20288
    @note This function will always be `false` for JSON values after parsing.
20289
    That is, discarded values can only occur during parsing, but will be
20290
    removed when inside a structured value or replaced by null in other cases.
20291
20292
    @return `true` if type is discarded, `false` otherwise.
20293
20294
    @complexity Constant.
20295
20296
    @exceptionsafety No-throw guarantee: this member function never throws
20297
    exceptions.
20298
20299
    @liveexample{The following code exemplifies `is_discarded()` for all JSON
20300
    types.,is_discarded}
20301
20302
    @since version 1.0.0
20303
    */
20304
    constexpr bool is_discarded() const noexcept
20305
0
    {
20306
0
        return m_type == value_t::discarded;
20307
0
    }
20308
20309
    /*!
20310
    @brief return the type of the JSON value (implicit)
20311
20312
    Implicitly return the type of the JSON value as a value from the @ref
20313
    value_t enumeration.
20314
20315
    @return the type of the JSON value
20316
20317
    @complexity Constant.
20318
20319
    @exceptionsafety No-throw guarantee: this member function never throws
20320
    exceptions.
20321
20322
    @liveexample{The following code exemplifies the @ref value_t operator for
20323
    all JSON types.,operator__value_t}
20324
20325
    @sa see @ref type() -- return the type of the JSON value (explicit)
20326
    @sa see @ref type_name() -- return the type as string
20327
20328
    @since version 1.0.0
20329
    */
20330
    constexpr operator value_t() const noexcept
20331
2.10M
    {
20332
2.10M
        return m_type;
20333
2.10M
    }
20334
20335
    /// @}
20336
20337
  private:
20338
    //////////////////
20339
    // value access //
20340
    //////////////////
20341
20342
    /// get a boolean (explicit)
20343
    boolean_t get_impl(boolean_t* /*unused*/) const
20344
    {
20345
        if (JSON_HEDLEY_LIKELY(is_boolean()))
20346
        {
20347
            return m_value.boolean;
20348
        }
20349
20350
        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20351
    }
20352
20353
    /// get a pointer to the value (object)
20354
    object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20355
    {
20356
        return is_object() ? m_value.object : nullptr;
20357
    }
20358
20359
    /// get a pointer to the value (object)
20360
    constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20361
    {
20362
        return is_object() ? m_value.object : nullptr;
20363
    }
20364
20365
    /// get a pointer to the value (array)
20366
    array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20367
    {
20368
        return is_array() ? m_value.array : nullptr;
20369
    }
20370
20371
    /// get a pointer to the value (array)
20372
    constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20373
    {
20374
        return is_array() ? m_value.array : nullptr;
20375
    }
20376
20377
    /// get a pointer to the value (string)
20378
    string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20379
    {
20380
        return is_string() ? m_value.string : nullptr;
20381
    }
20382
20383
    /// get a pointer to the value (string)
20384
    constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20385
73.0k
    {
20386
73.0k
        return is_string() ? m_value.string : nullptr;
20387
73.0k
    }
20388
20389
    /// get a pointer to the value (boolean)
20390
    boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20391
    {
20392
        return is_boolean() ? &m_value.boolean : nullptr;
20393
    }
20394
20395
    /// get a pointer to the value (boolean)
20396
    constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20397
485
    {
20398
485
        return is_boolean() ? &m_value.boolean : nullptr;
20399
485
    }
20400
20401
    /// get a pointer to the value (integer number)
20402
    number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20403
    {
20404
        return is_number_integer() ? &m_value.number_integer : nullptr;
20405
    }
20406
20407
    /// get a pointer to the value (integer number)
20408
    constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20409
6.84k
    {
20410
6.84k
        return is_number_integer() ? &m_value.number_integer : nullptr;
20411
6.84k
    }
20412
20413
    /// get a pointer to the value (unsigned number)
20414
    number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20415
    {
20416
        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20417
    }
20418
20419
    /// get a pointer to the value (unsigned number)
20420
    constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20421
2.09M
    {
20422
2.09M
        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20423
2.09M
    }
20424
20425
    /// get a pointer to the value (floating-point number)
20426
    number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20427
    {
20428
        return is_number_float() ? &m_value.number_float : nullptr;
20429
    }
20430
20431
    /// get a pointer to the value (floating-point number)
20432
    constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20433
4.88k
    {
20434
4.88k
        return is_number_float() ? &m_value.number_float : nullptr;
20435
4.88k
    }
20436
20437
    /// get a pointer to the value (binary)
20438
    binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20439
    {
20440
        return is_binary() ? m_value.binary : nullptr;
20441
    }
20442
20443
    /// get a pointer to the value (binary)
20444
    constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20445
0
    {
20446
0
        return is_binary() ? m_value.binary : nullptr;
20447
0
    }
20448
20449
    /*!
20450
    @brief helper function to implement get_ref()
20451
20452
    This function helps to implement get_ref() without code duplication for
20453
    const and non-const overloads
20454
20455
    @tparam ThisType will be deduced as `basic_json` or `const basic_json`
20456
20457
    @throw type_error.303 if ReferenceType does not match underlying value
20458
    type of the current JSON
20459
    */
20460
    template<typename ReferenceType, typename ThisType>
20461
    static ReferenceType get_ref_impl(ThisType& obj)
20462
0
    {
20463
0
        // delegate the call to get_ptr<>()
20464
0
        auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20465
0
20466
0
        if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20467
0
        {
20468
0
            return *ptr;
20469
0
        }
20470
0
20471
0
        JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20472
0
    }
20473
20474
  public:
20475
    /// @name value access
20476
    /// Direct access to the stored value of a JSON value.
20477
    /// @{
20478
20479
    /*!
20480
    @brief get a pointer value (implicit)
20481
20482
    Implicit pointer access to the internally stored JSON value. No copies are
20483
    made.
20484
20485
    @warning Writing data to the pointee of the result yields an undefined
20486
    state.
20487
20488
    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20489
    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20490
    @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
20491
    assertion.
20492
20493
    @return pointer to the internally stored JSON value if the requested
20494
    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20495
20496
    @complexity Constant.
20497
20498
    @liveexample{The example below shows how pointers to internal values of a
20499
    JSON value can be requested. Note that no type conversions are made and a
20500
    `nullptr` is returned if the value and the requested pointer type does not
20501
    match.,get_ptr}
20502
20503
    @since version 1.0.0
20504
    */
20505
    template<typename PointerType, typename std::enable_if<
20506
                 std::is_pointer<PointerType>::value, int>::type = 0>
20507
    auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20508
    {
20509
        // delegate the call to get_impl_ptr<>()
20510
        return get_impl_ptr(static_cast<PointerType>(nullptr));
20511
    }
20512
20513
    /*!
20514
    @brief get a pointer value (implicit)
20515
    @copydoc get_ptr()
20516
    */
20517
    template < typename PointerType, typename std::enable_if <
20518
                   std::is_pointer<PointerType>::value&&
20519
                   std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20520
    constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20521
2.18M
    {
20522
        // delegate the call to get_impl_ptr<>() const
20523
2.18M
        return get_impl_ptr(static_cast<PointerType>(nullptr));
20524
2.18M
    }
_ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKbLi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Line
Count
Source
20521
485
    {
20522
        // delegate the call to get_impl_ptr<>() const
20523
485
        return get_impl_ptr(static_cast<PointerType>(nullptr));
20524
485
    }
_ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKmLi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Line
Count
Source
20521
2.09M
    {
20522
        // delegate the call to get_impl_ptr<>() const
20523
2.09M
        return get_impl_ptr(static_cast<PointerType>(nullptr));
20524
2.09M
    }
_ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKlLi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Line
Count
Source
20521
6.84k
    {
20522
        // delegate the call to get_impl_ptr<>() const
20523
6.84k
        return get_impl_ptr(static_cast<PointerType>(nullptr));
20524
6.84k
    }
_ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKdLi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Line
Count
Source
20521
4.88k
    {
20522
        // delegate the call to get_impl_ptr<>() const
20523
4.88k
        return get_impl_ptr(static_cast<PointerType>(nullptr));
20524
4.88k
    }
_ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKS9_Li0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Line
Count
Source
20521
73.0k
    {
20522
        // delegate the call to get_impl_ptr<>() const
20523
73.0k
        return get_impl_ptr(static_cast<PointerType>(nullptr));
20524
73.0k
    }
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKNS_27byte_container_with_subtypeISC_EELi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISM_EEEEv
20525
20526
  private:
20527
    /*!
20528
    @brief get a value (explicit)
20529
20530
    Explicit type conversion between the JSON value and a compatible value
20531
    which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20532
    and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20533
    The value is converted by calling the @ref json_serializer<ValueType>
20534
    `from_json()` method.
20535
20536
    The function is equivalent to executing
20537
    @code {.cpp}
20538
    ValueType ret;
20539
    JSONSerializer<ValueType>::from_json(*this, ret);
20540
    return ret;
20541
    @endcode
20542
20543
    This overloads is chosen if:
20544
    - @a ValueType is not @ref basic_json,
20545
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
20546
      `void from_json(const basic_json&, ValueType&)`, and
20547
    - @ref json_serializer<ValueType> does not have a `from_json()` method of
20548
      the form `ValueType from_json(const basic_json&)`
20549
20550
    @tparam ValueType the returned value type
20551
20552
    @return copy of the JSON value, converted to @a ValueType
20553
20554
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
20555
20556
    @liveexample{The example below shows several conversions from JSON values
20557
    to other types. There a few things to note: (1) Floating-point numbers can
20558
    be converted to integers\, (2) A JSON array can be converted to a standard
20559
    `std::vector<short>`\, (3) A JSON object can be converted to C++
20560
    associative containers such as `std::unordered_map<std::string\,
20561
    json>`.,get__ValueType_const}
20562
20563
    @since version 2.1.0
20564
    */
20565
    template < typename ValueType,
20566
               detail::enable_if_t <
20567
                   detail::is_default_constructible<ValueType>::value&&
20568
                   detail::has_from_json<basic_json_t, ValueType>::value,
20569
                   int > = 0 >
20570
    ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20571
                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20572
2.18M
    {
20573
2.18M
        auto ret = ValueType();
20574
2.18M
        JSONSerializer<ValueType>::from_json(*this, ret);
20575
2.18M
        return ret;
20576
2.18M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::get_impl<bool, 0>(nlohmann::detail::priority_tag<0u>) const
Line
Count
Source
20572
485
    {
20573
485
        auto ret = ValueType();
20574
485
        JSONSerializer<ValueType>::from_json(*this, ret);
20575
485
        return ret;
20576
485
    }
long 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<unsigned char, std::__1::allocator<unsigned char> > >::get_impl<long, 0>(nlohmann::detail::priority_tag<0u>) const
Line
Count
Source
20572
1.36M
    {
20573
1.36M
        auto ret = ValueType();
20574
1.36M
        JSONSerializer<ValueType>::from_json(*this, ret);
20575
1.36M
        return ret;
20576
1.36M
    }
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, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::get_impl<double, 0>(nlohmann::detail::priority_tag<0u>) const
Line
Count
Source
20572
743k
    {
20573
743k
        auto ret = ValueType();
20574
743k
        JSONSerializer<ValueType>::from_json(*this, ret);
20575
743k
        return ret;
20576
743k
    }
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::vector<unsigned char, std::__1::allocator<unsigned char> > >::get_impl<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, 0>(nlohmann::detail::priority_tag<0u>) const
Line
Count
Source
20572
73.0k
    {
20573
73.0k
        auto ret = ValueType();
20574
73.0k
        JSONSerializer<ValueType>::from_json(*this, ret);
20575
73.0k
        return ret;
20576
73.0k
    }
Unexecuted instantiation: unsigned long 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<unsigned char, std::__1::allocator<unsigned char> > >::get_impl<unsigned long, 0>(nlohmann::detail::priority_tag<0u>) const
20577
20578
    /*!
20579
    @brief get a value (explicit); special case
20580
20581
    Explicit type conversion between the JSON value and a compatible value
20582
    which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20583
    and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20584
    The value is converted by calling the @ref json_serializer<ValueType>
20585
    `from_json()` method.
20586
20587
    The function is equivalent to executing
20588
    @code {.cpp}
20589
    return JSONSerializer<ValueType>::from_json(*this);
20590
    @endcode
20591
20592
    This overloads is chosen if:
20593
    - @a ValueType is not @ref basic_json and
20594
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
20595
      `ValueType from_json(const basic_json&)`
20596
20597
    @note If @ref json_serializer<ValueType> has both overloads of
20598
    `from_json()`, this one is chosen.
20599
20600
    @tparam ValueType the returned value type
20601
20602
    @return copy of the JSON value, converted to @a ValueType
20603
20604
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
20605
20606
    @since version 2.1.0
20607
    */
20608
    template < typename ValueType,
20609
               detail::enable_if_t <
20610
                   detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20611
                   int > = 0 >
20612
    ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20613
                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20614
    {
20615
        return JSONSerializer<ValueType>::from_json(*this);
20616
    }
20617
20618
    /*!
20619
    @brief get special-case overload
20620
20621
    This overloads converts the current @ref basic_json in a different
20622
    @ref basic_json type
20623
20624
    @tparam BasicJsonType == @ref basic_json
20625
20626
    @return a copy of *this, converted into @a BasicJsonType
20627
20628
    @complexity Depending on the implementation of the called `from_json()`
20629
                method.
20630
20631
    @since version 3.2.0
20632
    */
20633
    template < typename BasicJsonType,
20634
               detail::enable_if_t <
20635
                   detail::is_basic_json<BasicJsonType>::value,
20636
                   int > = 0 >
20637
    BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20638
    {
20639
        return *this;
20640
    }
20641
20642
    /*!
20643
    @brief get special-case overload
20644
20645
    This overloads avoids a lot of template boilerplate, it can be seen as the
20646
    identity method
20647
20648
    @tparam BasicJsonType == @ref basic_json
20649
20650
    @return a copy of *this
20651
20652
    @complexity Constant.
20653
20654
    @since version 2.1.0
20655
    */
20656
    template<typename BasicJsonType,
20657
             detail::enable_if_t<
20658
                 std::is_same<BasicJsonType, basic_json_t>::value,
20659
                 int> = 0>
20660
    basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20661
    {
20662
        return *this;
20663
    }
20664
20665
    /*!
20666
    @brief get a pointer value (explicit)
20667
    @copydoc get()
20668
    */
20669
    template<typename PointerType,
20670
             detail::enable_if_t<
20671
                 std::is_pointer<PointerType>::value,
20672
                 int> = 0>
20673
    constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20674
    -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20675
    {
20676
        // delegate the call to get_ptr
20677
        return get_ptr<PointerType>();
20678
    }
20679
20680
  public:
20681
    /*!
20682
    @brief get a (pointer) value (explicit)
20683
20684
    Performs explicit type conversion between the JSON value and a compatible value if required.
20685
20686
    - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
20687
    No copies are made.
20688
20689
    - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
20690
    from the current @ref basic_json.
20691
20692
    - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
20693
    method.
20694
20695
    @tparam ValueTypeCV the provided value type
20696
    @tparam ValueType the returned value type
20697
20698
    @return copy of the JSON value, converted to @tparam ValueType if necessary
20699
20700
    @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
20701
20702
    @since version 2.1.0
20703
    */
20704
    template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20705
#if defined(JSON_HAS_CPP_14)
20706
    constexpr
20707
#endif
20708
    auto get() const noexcept(
20709
    noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20710
    -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20711
2.18M
    {
20712
        // we cannot static_assert on ValueTypeCV being non-const, because
20713
        // there is support for get<const basic_json_t>(), which is why we
20714
        // still need the uncvref
20715
2.18M
        static_assert(!std::is_reference<ValueTypeCV>::value,
20716
2.18M
                      "get() cannot be used with reference types, you might want to use get_ref()");
20717
2.18M
        return get_impl<ValueType>(detail::priority_tag<4> {});
20718
2.18M
    }
decltype ((((std::__1::declval<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<unsigned char, std::__1::allocator<unsigned char> > > const&>)()).(get_impl<bool>))(nlohmann::detail::priority_tag<4u>{})) 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<unsigned char, std::__1::allocator<unsigned char> > >::get<bool, bool>() const
Line
Count
Source
20711
485
    {
20712
        // we cannot static_assert on ValueTypeCV being non-const, because
20713
        // there is support for get<const basic_json_t>(), which is why we
20714
        // still need the uncvref
20715
485
        static_assert(!std::is_reference<ValueTypeCV>::value,
20716
485
                      "get() cannot be used with reference types, you might want to use get_ref()");
20717
485
        return get_impl<ValueType>(detail::priority_tag<4> {});
20718
485
    }
decltype ((((std::__1::declval<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<unsigned char, std::__1::allocator<unsigned char> > > const&>)()).(get_impl<long>))(nlohmann::detail::priority_tag<4u>{})) 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<unsigned char, std::__1::allocator<unsigned char> > >::get<long, long>() const
Line
Count
Source
20711
1.36M
    {
20712
        // we cannot static_assert on ValueTypeCV being non-const, because
20713
        // there is support for get<const basic_json_t>(), which is why we
20714
        // still need the uncvref
20715
1.36M
        static_assert(!std::is_reference<ValueTypeCV>::value,
20716
1.36M
                      "get() cannot be used with reference types, you might want to use get_ref()");
20717
1.36M
        return get_impl<ValueType>(detail::priority_tag<4> {});
20718
1.36M
    }
decltype ((((std::__1::declval<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<unsigned char, std::__1::allocator<unsigned char> > > const&>)()).(get_impl<double>))(nlohmann::detail::priority_tag<4u>{})) 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<unsigned char, std::__1::allocator<unsigned char> > >::get<double, double>() const
Line
Count
Source
20711
743k
    {
20712
        // we cannot static_assert on ValueTypeCV being non-const, because
20713
        // there is support for get<const basic_json_t>(), which is why we
20714
        // still need the uncvref
20715
743k
        static_assert(!std::is_reference<ValueTypeCV>::value,
20716
743k
                      "get() cannot be used with reference types, you might want to use get_ref()");
20717
743k
        return get_impl<ValueType>(detail::priority_tag<4> {});
20718
743k
    }
decltype ((((std::__1::declval<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<unsigned char, std::__1::allocator<unsigned char> > > const&>)()).(get_impl<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >))(nlohmann::detail::priority_tag<4u>{})) 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<unsigned char, std::__1::allocator<unsigned char> > >::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> > >() const
Line
Count
Source
20711
73.0k
    {
20712
        // we cannot static_assert on ValueTypeCV being non-const, because
20713
        // there is support for get<const basic_json_t>(), which is why we
20714
        // still need the uncvref
20715
73.0k
        static_assert(!std::is_reference<ValueTypeCV>::value,
20716
73.0k
                      "get() cannot be used with reference types, you might want to use get_ref()");
20717
73.0k
        return get_impl<ValueType>(detail::priority_tag<4> {});
20718
73.0k
    }
Unexecuted instantiation: decltype ((((std::__1::declval<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<unsigned char, std::__1::allocator<unsigned char> > > const&>)()).(get_impl<unsigned long>))(nlohmann::detail::priority_tag<4u>{})) 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<unsigned char, std::__1::allocator<unsigned char> > >::get<unsigned long, unsigned long>() const
20719
20720
    /*!
20721
    @brief get a pointer value (explicit)
20722
20723
    Explicit pointer access to the internally stored JSON value. No copies are
20724
    made.
20725
20726
    @warning The pointer becomes invalid if the underlying JSON object
20727
    changes.
20728
20729
    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20730
    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20731
    @ref number_unsigned_t, or @ref number_float_t.
20732
20733
    @return pointer to the internally stored JSON value if the requested
20734
    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20735
20736
    @complexity Constant.
20737
20738
    @liveexample{The example below shows how pointers to internal values of a
20739
    JSON value can be requested. Note that no type conversions are made and a
20740
    `nullptr` is returned if the value and the requested pointer type does not
20741
    match.,get__PointerType}
20742
20743
    @sa see @ref get_ptr() for explicit pointer-member access
20744
20745
    @since version 1.0.0
20746
    */
20747
    template<typename PointerType, typename std::enable_if<
20748
                 std::is_pointer<PointerType>::value, int>::type = 0>
20749
    auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20750
    {
20751
        // delegate the call to get_ptr
20752
        return get_ptr<PointerType>();
20753
    }
20754
20755
    /*!
20756
    @brief get a value (explicit)
20757
20758
    Explicit type conversion between the JSON value and a compatible value.
20759
    The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
20760
    `from_json()` method.
20761
20762
    The function is equivalent to executing
20763
    @code {.cpp}
20764
    ValueType v;
20765
    JSONSerializer<ValueType>::from_json(*this, v);
20766
    @endcode
20767
20768
    This overloads is chosen if:
20769
    - @a ValueType is not @ref basic_json,
20770
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
20771
      `void from_json(const basic_json&, ValueType&)`, and
20772
20773
    @tparam ValueType the input parameter type.
20774
20775
    @return the input parameter, allowing chaining calls.
20776
20777
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
20778
20779
    @liveexample{The example below shows several conversions from JSON values
20780
    to other types. There a few things to note: (1) Floating-point numbers can
20781
    be converted to integers\, (2) A JSON array can be converted to a standard
20782
    `std::vector<short>`\, (3) A JSON object can be converted to C++
20783
    associative containers such as `std::unordered_map<std::string\,
20784
    json>`.,get_to}
20785
20786
    @since version 3.3.0
20787
    */
20788
    template < typename ValueType,
20789
               detail::enable_if_t <
20790
                   !detail::is_basic_json<ValueType>::value&&
20791
                   detail::has_from_json<basic_json_t, ValueType>::value,
20792
                   int > = 0 >
20793
    ValueType & get_to(ValueType& v) const noexcept(noexcept(
20794
                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20795
    {
20796
        JSONSerializer<ValueType>::from_json(*this, v);
20797
        return v;
20798
    }
20799
20800
    // specialization to allow to call get_to with a basic_json value
20801
    // see https://github.com/nlohmann/json/issues/2175
20802
    template<typename ValueType,
20803
             detail::enable_if_t <
20804
                 detail::is_basic_json<ValueType>::value,
20805
                 int> = 0>
20806
    ValueType & get_to(ValueType& v) const
20807
    {
20808
        v = *this;
20809
        return v;
20810
    }
20811
20812
    template <
20813
        typename T, std::size_t N,
20814
        typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20815
        detail::enable_if_t <
20816
            detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20817
    Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20818
    noexcept(noexcept(JSONSerializer<Array>::from_json(
20819
                          std::declval<const basic_json_t&>(), v)))
20820
    {
20821
        JSONSerializer<Array>::from_json(*this, v);
20822
        return v;
20823
    }
20824
20825
    /*!
20826
    @brief get a reference value (implicit)
20827
20828
    Implicit reference access to the internally stored JSON value. No copies
20829
    are made.
20830
20831
    @warning Writing data to the referee of the result yields an undefined
20832
    state.
20833
20834
    @tparam ReferenceType reference type; must be a reference to @ref array_t,
20835
    @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
20836
    @ref number_float_t. Enforced by static assertion.
20837
20838
    @return reference to the internally stored JSON value if the requested
20839
    reference type @a ReferenceType fits to the JSON value; throws
20840
    type_error.303 otherwise
20841
20842
    @throw type_error.303 in case passed type @a ReferenceType is incompatible
20843
    with the stored JSON value; see example below
20844
20845
    @complexity Constant.
20846
20847
    @liveexample{The example shows several calls to `get_ref()`.,get_ref}
20848
20849
    @since version 1.1.0
20850
    */
20851
    template<typename ReferenceType, typename std::enable_if<
20852
                 std::is_reference<ReferenceType>::value, int>::type = 0>
20853
    ReferenceType get_ref()
20854
    {
20855
        // delegate call to get_ref_impl
20856
        return get_ref_impl<ReferenceType>(*this);
20857
    }
20858
20859
    /*!
20860
    @brief get a reference value (implicit)
20861
    @copydoc get_ref()
20862
    */
20863
    template < typename ReferenceType, typename std::enable_if <
20864
                   std::is_reference<ReferenceType>::value&&
20865
                   std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20866
    ReferenceType get_ref() const
20867
0
    {
20868
0
        // delegate call to get_ref_impl
20869
0
        return get_ref_impl<ReferenceType>(*this);
20870
0
    }
20871
20872
    /*!
20873
    @brief get a value (implicit)
20874
20875
    Implicit type conversion between the JSON value and a compatible value.
20876
    The call is realized by calling @ref get() const.
20877
20878
    @tparam ValueType non-pointer type compatible to the JSON value, for
20879
    instance `int` for JSON integer numbers, `bool` for JSON booleans, or
20880
    `std::vector` types for JSON arrays. The character type of @ref string_t
20881
    as well as an initializer list of this type is excluded to avoid
20882
    ambiguities as these types implicitly convert to `std::string`.
20883
20884
    @return copy of the JSON value, converted to type @a ValueType
20885
20886
    @throw type_error.302 in case passed type @a ValueType is incompatible
20887
    to the JSON value type (e.g., the JSON value is of type boolean, but a
20888
    string is requested); see example below
20889
20890
    @complexity Linear in the size of the JSON value.
20891
20892
    @liveexample{The example below shows several conversions from JSON values
20893
    to other types. There a few things to note: (1) Floating-point numbers can
20894
    be converted to integers\, (2) A JSON array can be converted to a standard
20895
    `std::vector<short>`\, (3) A JSON object can be converted to C++
20896
    associative containers such as `std::unordered_map<std::string\,
20897
    json>`.,operator__ValueType}
20898
20899
    @since version 1.0.0
20900
    */
20901
    template < typename ValueType, typename std::enable_if <
20902
                   detail::conjunction <
20903
                       detail::negation<std::is_pointer<ValueType>>,
20904
                       detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
20905
                                        detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
20906
                                        detail::negation<detail::is_basic_json<ValueType>>,
20907
                                        detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
20908
20909
#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20910
                                                detail::negation<std::is_same<ValueType, std::string_view>>,
20911
#endif
20912
                                                detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
20913
                                                >::value, int >::type = 0 >
20914
                                        JSON_EXPLICIT operator ValueType() const
20915
    {
20916
        // delegate the call to get<>() const
20917
        return get<ValueType>();
20918
    }
20919
20920
    /*!
20921
    @return reference to the binary value
20922
20923
    @throw type_error.302 if the value is not binary
20924
20925
    @sa see @ref is_binary() to check if the value is binary
20926
20927
    @since version 3.8.0
20928
    */
20929
    binary_t& get_binary()
20930
    {
20931
        if (!is_binary())
20932
        {
20933
            JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20934
        }
20935
20936
        return *get_ptr<binary_t*>();
20937
    }
20938
20939
    /// @copydoc get_binary()
20940
    const binary_t& get_binary() const
20941
0
    {
20942
0
        if (!is_binary())
20943
0
        {
20944
0
            JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20945
0
        }
20946
0
20947
0
        return *get_ptr<const binary_t*>();
20948
0
    }
20949
20950
    /// @}
20951
20952
20953
    ////////////////////
20954
    // element access //
20955
    ////////////////////
20956
20957
    /// @name element access
20958
    /// Access to the JSON value.
20959
    /// @{
20960
20961
    /*!
20962
    @brief access specified array element with bounds checking
20963
20964
    Returns a reference to the element at specified location @a idx, with
20965
    bounds checking.
20966
20967
    @param[in] idx  index of the element to access
20968
20969
    @return reference to the element at index @a idx
20970
20971
    @throw type_error.304 if the JSON value is not an array; in this case,
20972
    calling `at` with an index makes no sense. See example below.
20973
    @throw out_of_range.401 if the index @a idx is out of range of the array;
20974
    that is, `idx >= size()`. See example below.
20975
20976
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20977
    changes in the JSON value.
20978
20979
    @complexity Constant.
20980
20981
    @since version 1.0.0
20982
20983
    @liveexample{The example below shows how array elements can be read and
20984
    written using `at()`. It also demonstrates the different exceptions that
20985
    can be thrown.,at__size_type}
20986
    */
20987
    reference at(size_type idx)
20988
    {
20989
        // at only works for arrays
20990
        if (JSON_HEDLEY_LIKELY(is_array()))
20991
        {
20992
            JSON_TRY
20993
            {
20994
                return set_parent(m_value.array->at(idx));
20995
            }
20996
            JSON_CATCH (std::out_of_range&)
20997
            {
20998
                // create better exception explanation
20999
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21000
            }
21001
        }
21002
        else
21003
        {
21004
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21005
        }
21006
    }
21007
21008
    /*!
21009
    @brief access specified array element with bounds checking
21010
21011
    Returns a const reference to the element at specified location @a idx,
21012
    with bounds checking.
21013
21014
    @param[in] idx  index of the element to access
21015
21016
    @return const reference to the element at index @a idx
21017
21018
    @throw type_error.304 if the JSON value is not an array; in this case,
21019
    calling `at` with an index makes no sense. See example below.
21020
    @throw out_of_range.401 if the index @a idx is out of range of the array;
21021
    that is, `idx >= size()`. See example below.
21022
21023
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21024
    changes in the JSON value.
21025
21026
    @complexity Constant.
21027
21028
    @since version 1.0.0
21029
21030
    @liveexample{The example below shows how array elements can be read using
21031
    `at()`. It also demonstrates the different exceptions that can be thrown.,
21032
    at__size_type_const}
21033
    */
21034
    const_reference at(size_type idx) const
21035
    {
21036
        // at only works for arrays
21037
        if (JSON_HEDLEY_LIKELY(is_array()))
21038
        {
21039
            JSON_TRY
21040
            {
21041
                return m_value.array->at(idx);
21042
            }
21043
            JSON_CATCH (std::out_of_range&)
21044
            {
21045
                // create better exception explanation
21046
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21047
            }
21048
        }
21049
        else
21050
        {
21051
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21052
        }
21053
    }
21054
21055
    /*!
21056
    @brief access specified object element with bounds checking
21057
21058
    Returns a reference to the element at with specified key @a key, with
21059
    bounds checking.
21060
21061
    @param[in] key  key of the element to access
21062
21063
    @return reference to the element at key @a key
21064
21065
    @throw type_error.304 if the JSON value is not an object; in this case,
21066
    calling `at` with a key makes no sense. See example below.
21067
    @throw out_of_range.403 if the key @a key is is not stored in the object;
21068
    that is, `find(key) == end()`. See example below.
21069
21070
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21071
    changes in the JSON value.
21072
21073
    @complexity Logarithmic in the size of the container.
21074
21075
    @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21076
    access by reference
21077
    @sa see @ref value() for access by value with a default value
21078
21079
    @since version 1.0.0
21080
21081
    @liveexample{The example below shows how object elements can be read and
21082
    written using `at()`. It also demonstrates the different exceptions that
21083
    can be thrown.,at__object_t_key_type}
21084
    */
21085
    reference at(const typename object_t::key_type& key)
21086
    {
21087
        // at only works for objects
21088
        if (JSON_HEDLEY_LIKELY(is_object()))
21089
        {
21090
            JSON_TRY
21091
            {
21092
                return set_parent(m_value.object->at(key));
21093
            }
21094
            JSON_CATCH (std::out_of_range&)
21095
            {
21096
                // create better exception explanation
21097
                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21098
            }
21099
        }
21100
        else
21101
        {
21102
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21103
        }
21104
    }
21105
21106
    /*!
21107
    @brief access specified object element with bounds checking
21108
21109
    Returns a const reference to the element at with specified key @a key,
21110
    with bounds checking.
21111
21112
    @param[in] key  key of the element to access
21113
21114
    @return const reference to the element at key @a key
21115
21116
    @throw type_error.304 if the JSON value is not an object; in this case,
21117
    calling `at` with a key makes no sense. See example below.
21118
    @throw out_of_range.403 if the key @a key is is not stored in the object;
21119
    that is, `find(key) == end()`. See example below.
21120
21121
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21122
    changes in the JSON value.
21123
21124
    @complexity Logarithmic in the size of the container.
21125
21126
    @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21127
    access by reference
21128
    @sa see @ref value() for access by value with a default value
21129
21130
    @since version 1.0.0
21131
21132
    @liveexample{The example below shows how object elements can be read using
21133
    `at()`. It also demonstrates the different exceptions that can be thrown.,
21134
    at__object_t_key_type_const}
21135
    */
21136
    const_reference at(const typename object_t::key_type& key) const
21137
    {
21138
        // at only works for objects
21139
        if (JSON_HEDLEY_LIKELY(is_object()))
21140
        {
21141
            JSON_TRY
21142
            {
21143
                return m_value.object->at(key);
21144
            }
21145
            JSON_CATCH (std::out_of_range&)
21146
            {
21147
                // create better exception explanation
21148
                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21149
            }
21150
        }
21151
        else
21152
        {
21153
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21154
        }
21155
    }
21156
21157
    /*!
21158
    @brief access specified array element
21159
21160
    Returns a reference to the element at specified location @a idx.
21161
21162
    @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
21163
    then the array is silently filled up with `null` values to make `idx` a
21164
    valid reference to the last stored element.
21165
21166
    @param[in] idx  index of the element to access
21167
21168
    @return reference to the element at index @a idx
21169
21170
    @throw type_error.305 if the JSON value is not an array or null; in that
21171
    cases, using the [] operator with an index makes no sense.
21172
21173
    @complexity Constant if @a idx is in the range of the array. Otherwise
21174
    linear in `idx - size()`.
21175
21176
    @liveexample{The example below shows how array elements can be read and
21177
    written using `[]` operator. Note the addition of `null`
21178
    values.,operatorarray__size_type}
21179
21180
    @since version 1.0.0
21181
    */
21182
    reference operator[](size_type idx)
21183
    {
21184
        // implicitly convert null value to an empty array
21185
        if (is_null())
21186
        {
21187
            m_type = value_t::array;
21188
            m_value.array = create<array_t>();
21189
            assert_invariant();
21190
        }
21191
21192
        // operator[] only works for arrays
21193
        if (JSON_HEDLEY_LIKELY(is_array()))
21194
        {
21195
            // fill up array with null values if given idx is outside range
21196
            if (idx >= m_value.array->size())
21197
            {
21198
#if JSON_DIAGNOSTICS
21199
                // remember array size & capacity before resizing
21200
                const auto old_size = m_value.array->size();
21201
                const auto old_capacity = m_value.array->capacity();
21202
#endif
21203
                m_value.array->resize(idx + 1);
21204
21205
#if JSON_DIAGNOSTICS
21206
                if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
21207
                {
21208
                    // capacity has changed: update all parents
21209
                    set_parents();
21210
                }
21211
                else
21212
                {
21213
                    // set parent for values added above
21214
                    set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21215
                }
21216
#endif
21217
                assert_invariant();
21218
            }
21219
21220
            return m_value.array->operator[](idx);
21221
        }
21222
21223
        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21224
    }
21225
21226
    /*!
21227
    @brief access specified array element
21228
21229
    Returns a const reference to the element at specified location @a idx.
21230
21231
    @param[in] idx  index of the element to access
21232
21233
    @return const reference to the element at index @a idx
21234
21235
    @throw type_error.305 if the JSON value is not an array; in that case,
21236
    using the [] operator with an index makes no sense.
21237
21238
    @complexity Constant.
21239
21240
    @liveexample{The example below shows how array elements can be read using
21241
    the `[]` operator.,operatorarray__size_type_const}
21242
21243
    @since version 1.0.0
21244
    */
21245
    const_reference operator[](size_type idx) const
21246
0
    {
21247
        // const operator[] only works for arrays
21248
0
        if (JSON_HEDLEY_LIKELY(is_array()))
21249
0
        {
21250
0
            return m_value.array->operator[](idx);
21251
0
        }
21252
21253
0
        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21254
0
    }
21255
21256
    /*!
21257
    @brief access specified object element
21258
21259
    Returns a reference to the element at with specified key @a key.
21260
21261
    @note If @a key is not found in the object, then it is silently added to
21262
    the object and filled with a `null` value to make `key` a valid reference.
21263
    In case the value was `null` before, it is converted to an object.
21264
21265
    @param[in] key  key of the element to access
21266
21267
    @return reference to the element at key @a key
21268
21269
    @throw type_error.305 if the JSON value is not an object or null; in that
21270
    cases, using the [] operator with a key makes no sense.
21271
21272
    @complexity Logarithmic in the size of the container.
21273
21274
    @liveexample{The example below shows how object elements can be read and
21275
    written using the `[]` operator.,operatorarray__key_type}
21276
21277
    @sa see @ref at(const typename object_t::key_type&) for access by reference
21278
    with range checking
21279
    @sa see @ref value() for access by value with a default value
21280
21281
    @since version 1.0.0
21282
    */
21283
    reference operator[](const typename object_t::key_type& key)
21284
0
    {
21285
        // implicitly convert null value to an empty object
21286
0
        if (is_null())
21287
0
        {
21288
0
            m_type = value_t::object;
21289
0
            m_value.object = create<object_t>();
21290
0
            assert_invariant();
21291
0
        }
21292
21293
        // operator[] only works for objects
21294
0
        if (JSON_HEDLEY_LIKELY(is_object()))
21295
0
        {
21296
0
            return set_parent(m_value.object->operator[](key));
21297
0
        }
21298
21299
0
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21300
0
    }
21301
21302
    /*!
21303
    @brief read-only access specified object element
21304
21305
    Returns a const reference to the element at with specified key @a key. No
21306
    bounds checking is performed.
21307
21308
    @warning If the element with key @a key does not exist, the behavior is
21309
    undefined.
21310
21311
    @param[in] key  key of the element to access
21312
21313
    @return const reference to the element at key @a key
21314
21315
    @pre The element with key @a key must exist. **This precondition is
21316
         enforced with an assertion.**
21317
21318
    @throw type_error.305 if the JSON value is not an object; in that case,
21319
    using the [] operator with a key makes no sense.
21320
21321
    @complexity Logarithmic in the size of the container.
21322
21323
    @liveexample{The example below shows how object elements can be read using
21324
    the `[]` operator.,operatorarray__key_type_const}
21325
21326
    @sa see @ref at(const typename object_t::key_type&) for access by reference
21327
    with range checking
21328
    @sa see @ref value() for access by value with a default value
21329
21330
    @since version 1.0.0
21331
    */
21332
    const_reference operator[](const typename object_t::key_type& key) const
21333
    {
21334
        // const operator[] only works for objects
21335
        if (JSON_HEDLEY_LIKELY(is_object()))
21336
        {
21337
            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21338
            return m_value.object->find(key)->second;
21339
        }
21340
21341
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21342
    }
21343
21344
    /*!
21345
    @brief access specified object element
21346
21347
    Returns a reference to the element at with specified key @a key.
21348
21349
    @note If @a key is not found in the object, then it is silently added to
21350
    the object and filled with a `null` value to make `key` a valid reference.
21351
    In case the value was `null` before, it is converted to an object.
21352
21353
    @param[in] key  key of the element to access
21354
21355
    @return reference to the element at key @a key
21356
21357
    @throw type_error.305 if the JSON value is not an object or null; in that
21358
    cases, using the [] operator with a key makes no sense.
21359
21360
    @complexity Logarithmic in the size of the container.
21361
21362
    @liveexample{The example below shows how object elements can be read and
21363
    written using the `[]` operator.,operatorarray__key_type}
21364
21365
    @sa see @ref at(const typename object_t::key_type&) for access by reference
21366
    with range checking
21367
    @sa see @ref value() for access by value with a default value
21368
21369
    @since version 1.1.0
21370
    */
21371
    template<typename T>
21372
    JSON_HEDLEY_NON_NULL(2)
21373
    reference operator[](T* key)
21374
0
    {
21375
        // implicitly convert null to object
21376
0
        if (is_null())
21377
0
        {
21378
0
            m_type = value_t::object;
21379
0
            m_value = value_t::object;
21380
0
            assert_invariant();
21381
0
        }
21382
21383
        // at only works for objects
21384
0
        if (JSON_HEDLEY_LIKELY(is_object()))
21385
0
        {
21386
0
            return set_parent(m_value.object->operator[](key));
21387
0
        }
21388
21389
0
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21390
0
    }
21391
21392
    /*!
21393
    @brief read-only access specified object element
21394
21395
    Returns a const reference to the element at with specified key @a key. No
21396
    bounds checking is performed.
21397
21398
    @warning If the element with key @a key does not exist, the behavior is
21399
    undefined.
21400
21401
    @param[in] key  key of the element to access
21402
21403
    @return const reference to the element at key @a key
21404
21405
    @pre The element with key @a key must exist. **This precondition is
21406
         enforced with an assertion.**
21407
21408
    @throw type_error.305 if the JSON value is not an object; in that case,
21409
    using the [] operator with a key makes no sense.
21410
21411
    @complexity Logarithmic in the size of the container.
21412
21413
    @liveexample{The example below shows how object elements can be read using
21414
    the `[]` operator.,operatorarray__key_type_const}
21415
21416
    @sa see @ref at(const typename object_t::key_type&) for access by reference
21417
    with range checking
21418
    @sa see @ref value() for access by value with a default value
21419
21420
    @since version 1.1.0
21421
    */
21422
    template<typename T>
21423
    JSON_HEDLEY_NON_NULL(2)
21424
    const_reference operator[](T* key) const
21425
    {
21426
        // at only works for objects
21427
        if (JSON_HEDLEY_LIKELY(is_object()))
21428
        {
21429
            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21430
            return m_value.object->find(key)->second;
21431
        }
21432
21433
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21434
    }
21435
21436
    /*!
21437
    @brief access specified object element with default value
21438
21439
    Returns either a copy of an object's element at the specified key @a key
21440
    or a given default value if no element with key @a key exists.
21441
21442
    The function is basically equivalent to executing
21443
    @code {.cpp}
21444
    try {
21445
        return at(key);
21446
    } catch(out_of_range) {
21447
        return default_value;
21448
    }
21449
    @endcode
21450
21451
    @note Unlike @ref at(const typename object_t::key_type&), this function
21452
    does not throw if the given key @a key was not found.
21453
21454
    @note Unlike @ref operator[](const typename object_t::key_type& key), this
21455
    function does not implicitly add an element to the position defined by @a
21456
    key. This function is furthermore also applicable to const objects.
21457
21458
    @param[in] key  key of the element to access
21459
    @param[in] default_value  the value to return if @a key is not found
21460
21461
    @tparam ValueType type compatible to JSON values, for instance `int` for
21462
    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21463
    JSON arrays. Note the type of the expected value at @a key and the default
21464
    value @a default_value must be compatible.
21465
21466
    @return copy of the element at key @a key or @a default_value if @a key
21467
    is not found
21468
21469
    @throw type_error.302 if @a default_value does not match the type of the
21470
    value at @a key
21471
    @throw type_error.306 if the JSON value is not an object; in that case,
21472
    using `value()` with a key makes no sense.
21473
21474
    @complexity Logarithmic in the size of the container.
21475
21476
    @liveexample{The example below shows how object elements can be queried
21477
    with a default value.,basic_json__value}
21478
21479
    @sa see @ref at(const typename object_t::key_type&) for access by reference
21480
    with range checking
21481
    @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21482
    access by reference
21483
21484
    @since version 1.0.0
21485
    */
21486
    // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21487
    template < class ValueType, typename std::enable_if <
21488
                   detail::is_getable<basic_json_t, ValueType>::value
21489
                   && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21490
    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21491
    {
21492
        // at only works for objects
21493
        if (JSON_HEDLEY_LIKELY(is_object()))
21494
        {
21495
            // if key is found, return value and given default value otherwise
21496
            const auto it = find(key);
21497
            if (it != end())
21498
            {
21499
                return it->template get<ValueType>();
21500
            }
21501
21502
            return default_value;
21503
        }
21504
21505
        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21506
    }
21507
21508
    /*!
21509
    @brief overload for a default value of type const char*
21510
    @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
21511
    */
21512
    string_t value(const typename object_t::key_type& key, const char* default_value) const
21513
    {
21514
        return value(key, string_t(default_value));
21515
    }
21516
21517
    /*!
21518
    @brief access specified object element via JSON Pointer with default value
21519
21520
    Returns either a copy of an object's element at the specified key @a key
21521
    or a given default value if no element with key @a key exists.
21522
21523
    The function is basically equivalent to executing
21524
    @code {.cpp}
21525
    try {
21526
        return at(ptr);
21527
    } catch(out_of_range) {
21528
        return default_value;
21529
    }
21530
    @endcode
21531
21532
    @note Unlike @ref at(const json_pointer&), this function does not throw
21533
    if the given key @a key was not found.
21534
21535
    @param[in] ptr  a JSON pointer to the element to access
21536
    @param[in] default_value  the value to return if @a ptr found no value
21537
21538
    @tparam ValueType type compatible to JSON values, for instance `int` for
21539
    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21540
    JSON arrays. Note the type of the expected value at @a key and the default
21541
    value @a default_value must be compatible.
21542
21543
    @return copy of the element at key @a key or @a default_value if @a key
21544
    is not found
21545
21546
    @throw type_error.302 if @a default_value does not match the type of the
21547
    value at @a ptr
21548
    @throw type_error.306 if the JSON value is not an object; in that case,
21549
    using `value()` with a key makes no sense.
21550
21551
    @complexity Logarithmic in the size of the container.
21552
21553
    @liveexample{The example below shows how object elements can be queried
21554
    with a default value.,basic_json__value_ptr}
21555
21556
    @sa see @ref operator[](const json_pointer&) for unchecked access by reference
21557
21558
    @since version 2.0.2
21559
    */
21560
    template<class ValueType, typename std::enable_if<
21561
                 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21562
    ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21563
    {
21564
        // at only works for objects
21565
        if (JSON_HEDLEY_LIKELY(is_object()))
21566
        {
21567
            // if pointer resolves a value, return it or use default value
21568
            JSON_TRY
21569
            {
21570
                return ptr.get_checked(this).template get<ValueType>();
21571
            }
21572
            JSON_INTERNAL_CATCH (out_of_range&)
21573
            {
21574
                return default_value;
21575
            }
21576
        }
21577
21578
        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21579
    }
21580
21581
    /*!
21582
    @brief overload for a default value of type const char*
21583
    @copydoc basic_json::value(const json_pointer&, ValueType) const
21584
    */
21585
    JSON_HEDLEY_NON_NULL(3)
21586
    string_t value(const json_pointer& ptr, const char* default_value) const
21587
    {
21588
        return value(ptr, string_t(default_value));
21589
    }
21590
21591
    /*!
21592
    @brief access the first element
21593
21594
    Returns a reference to the first element in the container. For a JSON
21595
    container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
21596
21597
    @return In case of a structured type (array or object), a reference to the
21598
    first element is returned. In case of number, string, boolean, or binary
21599
    values, a reference to the value is returned.
21600
21601
    @complexity Constant.
21602
21603
    @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21604
    or an empty array or object (undefined behavior, **guarded by
21605
    assertions**).
21606
    @post The JSON value remains unchanged.
21607
21608
    @throw invalid_iterator.214 when called on `null` value
21609
21610
    @liveexample{The following code shows an example for `front()`.,front}
21611
21612
    @sa see @ref back() -- access the last element
21613
21614
    @since version 1.0.0
21615
    */
21616
    reference front()
21617
    {
21618
        return *begin();
21619
    }
21620
21621
    /*!
21622
    @copydoc basic_json::front()
21623
    */
21624
    const_reference front() const
21625
    {
21626
        return *cbegin();
21627
    }
21628
21629
    /*!
21630
    @brief access the last element
21631
21632
    Returns a reference to the last element in the container. For a JSON
21633
    container `c`, the expression `c.back()` is equivalent to
21634
    @code {.cpp}
21635
    auto tmp = c.end();
21636
    --tmp;
21637
    return *tmp;
21638
    @endcode
21639
21640
    @return In case of a structured type (array or object), a reference to the
21641
    last element is returned. In case of number, string, boolean, or binary
21642
    values, a reference to the value is returned.
21643
21644
    @complexity Constant.
21645
21646
    @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21647
    or an empty array or object (undefined behavior, **guarded by
21648
    assertions**).
21649
    @post The JSON value remains unchanged.
21650
21651
    @throw invalid_iterator.214 when called on a `null` value. See example
21652
    below.
21653
21654
    @liveexample{The following code shows an example for `back()`.,back}
21655
21656
    @sa see @ref front() -- access the first element
21657
21658
    @since version 1.0.0
21659
    */
21660
    reference back()
21661
    {
21662
        auto tmp = end();
21663
        --tmp;
21664
        return *tmp;
21665
    }
21666
21667
    /*!
21668
    @copydoc basic_json::back()
21669
    */
21670
    const_reference back() const
21671
    {
21672
        auto tmp = cend();
21673
        --tmp;
21674
        return *tmp;
21675
    }
21676
21677
    /*!
21678
    @brief remove element given an iterator
21679
21680
    Removes the element specified by iterator @a pos. The iterator @a pos must
21681
    be valid and dereferenceable. Thus the `end()` iterator (which is valid,
21682
    but is not dereferenceable) cannot be used as a value for @a pos.
21683
21684
    If called on a primitive type other than `null`, the resulting JSON value
21685
    will be `null`.
21686
21687
    @param[in] pos iterator to the element to remove
21688
    @return Iterator following the last removed element. If the iterator @a
21689
    pos refers to the last element, the `end()` iterator is returned.
21690
21691
    @tparam IteratorType an @ref iterator or @ref const_iterator
21692
21693
    @post Invalidates iterators and references at or after the point of the
21694
    erase, including the `end()` iterator.
21695
21696
    @throw type_error.307 if called on a `null` value; example: `"cannot use
21697
    erase() with null"`
21698
    @throw invalid_iterator.202 if called on an iterator which does not belong
21699
    to the current JSON value; example: `"iterator does not fit current
21700
    value"`
21701
    @throw invalid_iterator.205 if called on a primitive type with invalid
21702
    iterator (i.e., any iterator which is not `begin()`); example: `"iterator
21703
    out of range"`
21704
21705
    @complexity The complexity depends on the type:
21706
    - objects: amortized constant
21707
    - arrays: linear in distance between @a pos and the end of the container
21708
    - strings and binary: linear in the length of the member
21709
    - other types: constant
21710
21711
    @liveexample{The example shows the result of `erase()` for different JSON
21712
    types.,erase__IteratorType}
21713
21714
    @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21715
    the given range
21716
    @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21717
    from an object at the given key
21718
    @sa see @ref erase(const size_type) -- removes the element from an array at
21719
    the given index
21720
21721
    @since version 1.0.0
21722
    */
21723
    template < class IteratorType, typename std::enable_if <
21724
                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21725
                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21726
               = 0 >
21727
    IteratorType erase(IteratorType pos)
21728
0
    {
21729
        // make sure iterator fits the current value
21730
0
        if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21731
0
        {
21732
0
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21733
0
        }
21734
21735
0
        IteratorType result = end();
21736
21737
0
        switch (m_type)
21738
0
        {
21739
0
            case value_t::boolean:
21740
0
            case value_t::number_float:
21741
0
            case value_t::number_integer:
21742
0
            case value_t::number_unsigned:
21743
0
            case value_t::string:
21744
0
            case value_t::binary:
21745
0
            {
21746
0
                if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21747
0
                {
21748
0
                    JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21749
0
                }
21750
21751
0
                if (is_string())
21752
0
                {
21753
0
                    AllocatorType<string_t> alloc;
21754
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21755
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21756
0
                    m_value.string = nullptr;
21757
0
                }
21758
0
                else if (is_binary())
21759
0
                {
21760
0
                    AllocatorType<binary_t> alloc;
21761
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21762
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21763
0
                    m_value.binary = nullptr;
21764
0
                }
21765
21766
0
                m_type = value_t::null;
21767
0
                assert_invariant();
21768
0
                break;
21769
0
            }
21770
21771
0
            case value_t::object:
21772
0
            {
21773
0
                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21774
0
                break;
21775
0
            }
21776
21777
0
            case value_t::array:
21778
0
            {
21779
0
                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21780
0
                break;
21781
0
            }
21782
21783
0
            case value_t::null:
21784
0
            case value_t::discarded:
21785
0
            default:
21786
0
                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21787
0
        }
21788
21789
0
        return result;
21790
0
    }
21791
21792
    /*!
21793
    @brief remove elements given an iterator range
21794
21795
    Removes the element specified by the range `[first; last)`. The iterator
21796
    @a first does not need to be dereferenceable if `first == last`: erasing
21797
    an empty range is a no-op.
21798
21799
    If called on a primitive type other than `null`, the resulting JSON value
21800
    will be `null`.
21801
21802
    @param[in] first iterator to the beginning of the range to remove
21803
    @param[in] last iterator past the end of the range to remove
21804
    @return Iterator following the last removed element. If the iterator @a
21805
    second refers to the last element, the `end()` iterator is returned.
21806
21807
    @tparam IteratorType an @ref iterator or @ref const_iterator
21808
21809
    @post Invalidates iterators and references at or after the point of the
21810
    erase, including the `end()` iterator.
21811
21812
    @throw type_error.307 if called on a `null` value; example: `"cannot use
21813
    erase() with null"`
21814
    @throw invalid_iterator.203 if called on iterators which does not belong
21815
    to the current JSON value; example: `"iterators do not fit current value"`
21816
    @throw invalid_iterator.204 if called on a primitive type with invalid
21817
    iterators (i.e., if `first != begin()` and `last != end()`); example:
21818
    `"iterators out of range"`
21819
21820
    @complexity The complexity depends on the type:
21821
    - objects: `log(size()) + std::distance(first, last)`
21822
    - arrays: linear in the distance between @a first and @a last, plus linear
21823
      in the distance between @a last and end of the container
21824
    - strings and binary: linear in the length of the member
21825
    - other types: constant
21826
21827
    @liveexample{The example shows the result of `erase()` for different JSON
21828
    types.,erase__IteratorType_IteratorType}
21829
21830
    @sa see @ref erase(IteratorType) -- removes the element at a given position
21831
    @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21832
    from an object at the given key
21833
    @sa see @ref erase(const size_type) -- removes the element from an array at
21834
    the given index
21835
21836
    @since version 1.0.0
21837
    */
21838
    template < class IteratorType, typename std::enable_if <
21839
                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21840
                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21841
               = 0 >
21842
    IteratorType erase(IteratorType first, IteratorType last)
21843
    {
21844
        // make sure iterator fits the current value
21845
        if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21846
        {
21847
            JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21848
        }
21849
21850
        IteratorType result = end();
21851
21852
        switch (m_type)
21853
        {
21854
            case value_t::boolean:
21855
            case value_t::number_float:
21856
            case value_t::number_integer:
21857
            case value_t::number_unsigned:
21858
            case value_t::string:
21859
            case value_t::binary:
21860
            {
21861
                if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21862
                                       || !last.m_it.primitive_iterator.is_end()))
21863
                {
21864
                    JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21865
                }
21866
21867
                if (is_string())
21868
                {
21869
                    AllocatorType<string_t> alloc;
21870
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21871
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21872
                    m_value.string = nullptr;
21873
                }
21874
                else if (is_binary())
21875
                {
21876
                    AllocatorType<binary_t> alloc;
21877
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21878
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21879
                    m_value.binary = nullptr;
21880
                }
21881
21882
                m_type = value_t::null;
21883
                assert_invariant();
21884
                break;
21885
            }
21886
21887
            case value_t::object:
21888
            {
21889
                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21890
                                              last.m_it.object_iterator);
21891
                break;
21892
            }
21893
21894
            case value_t::array:
21895
            {
21896
                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21897
                                             last.m_it.array_iterator);
21898
                break;
21899
            }
21900
21901
            case value_t::null:
21902
            case value_t::discarded:
21903
            default:
21904
                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21905
        }
21906
21907
        return result;
21908
    }
21909
21910
    /*!
21911
    @brief remove element from a JSON object given a key
21912
21913
    Removes elements from a JSON object with the key value @a key.
21914
21915
    @param[in] key value of the elements to remove
21916
21917
    @return Number of elements removed. If @a ObjectType is the default
21918
    `std::map` type, the return value will always be `0` (@a key was not
21919
    found) or `1` (@a key was found).
21920
21921
    @post References and iterators to the erased elements are invalidated.
21922
    Other references and iterators are not affected.
21923
21924
    @throw type_error.307 when called on a type other than JSON object;
21925
    example: `"cannot use erase() with null"`
21926
21927
    @complexity `log(size()) + count(key)`
21928
21929
    @liveexample{The example shows the effect of `erase()`.,erase__key_type}
21930
21931
    @sa see @ref erase(IteratorType) -- removes the element at a given position
21932
    @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21933
    the given range
21934
    @sa see @ref erase(const size_type) -- removes the element from an array at
21935
    the given index
21936
21937
    @since version 1.0.0
21938
    */
21939
    size_type erase(const typename object_t::key_type& key)
21940
    {
21941
        // this erase only works for objects
21942
        if (JSON_HEDLEY_LIKELY(is_object()))
21943
        {
21944
            return m_value.object->erase(key);
21945
        }
21946
21947
        JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21948
    }
21949
21950
    /*!
21951
    @brief remove element from a JSON array given an index
21952
21953
    Removes element from a JSON array at the index @a idx.
21954
21955
    @param[in] idx index of the element to remove
21956
21957
    @throw type_error.307 when called on a type other than JSON object;
21958
    example: `"cannot use erase() with null"`
21959
    @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
21960
    is out of range"`
21961
21962
    @complexity Linear in distance between @a idx and the end of the container.
21963
21964
    @liveexample{The example shows the effect of `erase()`.,erase__size_type}
21965
21966
    @sa see @ref erase(IteratorType) -- removes the element at a given position
21967
    @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21968
    the given range
21969
    @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21970
    from an object at the given key
21971
21972
    @since version 1.0.0
21973
    */
21974
    void erase(const size_type idx)
21975
    {
21976
        // this erase only works for arrays
21977
        if (JSON_HEDLEY_LIKELY(is_array()))
21978
        {
21979
            if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21980
            {
21981
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21982
            }
21983
21984
            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21985
        }
21986
        else
21987
        {
21988
            JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21989
        }
21990
    }
21991
21992
    /// @}
21993
21994
21995
    ////////////
21996
    // lookup //
21997
    ////////////
21998
21999
    /// @name lookup
22000
    /// @{
22001
22002
    /*!
22003
    @brief find an element in a JSON object
22004
22005
    Finds an element in a JSON object with key equivalent to @a key. If the
22006
    element is not found or the JSON value is not an object, end() is
22007
    returned.
22008
22009
    @note This method always returns @ref end() when executed on a JSON type
22010
          that is not an object.
22011
22012
    @param[in] key key value of the element to search for.
22013
22014
    @return Iterator to an element with key equivalent to @a key. If no such
22015
    element is found or the JSON value is not an object, past-the-end (see
22016
    @ref end()) iterator is returned.
22017
22018
    @complexity Logarithmic in the size of the JSON object.
22019
22020
    @liveexample{The example shows how `find()` is used.,find__key_type}
22021
22022
    @sa see @ref contains(KeyT&&) const -- checks whether a key exists
22023
22024
    @since version 1.0.0
22025
    */
22026
    template<typename KeyT>
22027
    iterator find(KeyT&& key)
22028
0
    {
22029
0
        auto result = end();
22030
22031
0
        if (is_object())
22032
0
        {
22033
0
            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22034
0
        }
22035
22036
0
        return result;
22037
0
    }
22038
22039
    /*!
22040
    @brief find an element in a JSON object
22041
    @copydoc find(KeyT&&)
22042
    */
22043
    template<typename KeyT>
22044
    const_iterator find(KeyT&& key) const
22045
14.1M
    {
22046
14.1M
        auto result = cend();
22047
22048
14.1M
        if (is_object())
22049
9.57M
        {
22050
9.57M
            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22051
9.57M
        }
22052
22053
14.1M
        return result;
22054
14.1M
    }
22055
22056
    /*!
22057
    @brief returns the number of occurrences of a key in a JSON object
22058
22059
    Returns the number of elements with key @a key. If ObjectType is the
22060
    default `std::map` type, the return value will always be `0` (@a key was
22061
    not found) or `1` (@a key was found).
22062
22063
    @note This method always returns `0` when executed on a JSON type that is
22064
          not an object.
22065
22066
    @param[in] key key value of the element to count
22067
22068
    @return Number of elements with key @a key. If the JSON value is not an
22069
    object, the return value will be `0`.
22070
22071
    @complexity Logarithmic in the size of the JSON object.
22072
22073
    @liveexample{The example shows how `count()` is used.,count}
22074
22075
    @since version 1.0.0
22076
    */
22077
    template<typename KeyT>
22078
    size_type count(KeyT&& key) const
22079
    {
22080
        // return 0 for all nonobject types
22081
        return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
22082
    }
22083
22084
    /*!
22085
    @brief check the existence of an element in a JSON object
22086
22087
    Check whether an element exists in a JSON object with key equivalent to
22088
    @a key. If the element is not found or the JSON value is not an object,
22089
    false is returned.
22090
22091
    @note This method always returns false when executed on a JSON type
22092
          that is not an object.
22093
22094
    @param[in] key key value to check its existence.
22095
22096
    @return true if an element with specified @a key exists. If no such
22097
    element with such key is found or the JSON value is not an object,
22098
    false is returned.
22099
22100
    @complexity Logarithmic in the size of the JSON object.
22101
22102
    @liveexample{The following code shows an example for `contains()`.,contains}
22103
22104
    @sa see @ref find(KeyT&&) -- returns an iterator to an object element
22105
    @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
22106
22107
    @since version 3.6.0
22108
    */
22109
    template < typename KeyT, typename std::enable_if <
22110
                   !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
22111
    bool contains(KeyT && key) const
22112
    {
22113
        return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22114
    }
22115
22116
    /*!
22117
    @brief check the existence of an element in a JSON object given a JSON pointer
22118
22119
    Check whether the given JSON pointer @a ptr can be resolved in the current
22120
    JSON value.
22121
22122
    @note This method can be executed on any JSON value type.
22123
22124
    @param[in] ptr JSON pointer to check its existence.
22125
22126
    @return true if the JSON pointer can be resolved to a stored value, false
22127
    otherwise.
22128
22129
    @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
22130
22131
    @throw parse_error.106   if an array index begins with '0'
22132
    @throw parse_error.109   if an array index was not a number
22133
22134
    @complexity Logarithmic in the size of the JSON object.
22135
22136
    @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
22137
22138
    @sa see @ref contains(KeyT &&) const -- checks the existence of a key
22139
22140
    @since version 3.7.0
22141
    */
22142
    bool contains(const json_pointer& ptr) const
22143
    {
22144
        return ptr.contains(this);
22145
    }
22146
22147
    /// @}
22148
22149
22150
    ///////////////
22151
    // iterators //
22152
    ///////////////
22153
22154
    /// @name iterators
22155
    /// @{
22156
22157
    /*!
22158
    @brief returns an iterator to the first element
22159
22160
    Returns an iterator to the first element.
22161
22162
    @image html range-begin-end.svg "Illustration from cppreference.com"
22163
22164
    @return iterator to the first element
22165
22166
    @complexity Constant.
22167
22168
    @requirement This function helps `basic_json` satisfying the
22169
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22170
    requirements:
22171
    - The complexity is constant.
22172
22173
    @liveexample{The following code shows an example for `begin()`.,begin}
22174
22175
    @sa see @ref cbegin() -- returns a const iterator to the beginning
22176
    @sa see @ref end() -- returns an iterator to the end
22177
    @sa see @ref cend() -- returns a const iterator to the end
22178
22179
    @since version 1.0.0
22180
    */
22181
    iterator begin() noexcept
22182
0
    {
22183
0
        iterator result(this);
22184
0
        result.set_begin();
22185
0
        return result;
22186
0
    }
22187
22188
    /*!
22189
    @copydoc basic_json::cbegin()
22190
    */
22191
    const_iterator begin() const noexcept
22192
438k
    {
22193
438k
        return cbegin();
22194
438k
    }
22195
22196
    /*!
22197
    @brief returns a const iterator to the first element
22198
22199
    Returns a const iterator to the first element.
22200
22201
    @image html range-begin-end.svg "Illustration from cppreference.com"
22202
22203
    @return const iterator to the first element
22204
22205
    @complexity Constant.
22206
22207
    @requirement This function helps `basic_json` satisfying the
22208
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22209
    requirements:
22210
    - The complexity is constant.
22211
    - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
22212
22213
    @liveexample{The following code shows an example for `cbegin()`.,cbegin}
22214
22215
    @sa see @ref begin() -- returns an iterator to the beginning
22216
    @sa see @ref end() -- returns an iterator to the end
22217
    @sa see @ref cend() -- returns a const iterator to the end
22218
22219
    @since version 1.0.0
22220
    */
22221
    const_iterator cbegin() const noexcept
22222
438k
    {
22223
438k
        const_iterator result(this);
22224
438k
        result.set_begin();
22225
438k
        return result;
22226
438k
    }
22227
22228
    /*!
22229
    @brief returns an iterator to one past the last element
22230
22231
    Returns an iterator to one past the last element.
22232
22233
    @image html range-begin-end.svg "Illustration from cppreference.com"
22234
22235
    @return iterator one past the last element
22236
22237
    @complexity Constant.
22238
22239
    @requirement This function helps `basic_json` satisfying the
22240
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22241
    requirements:
22242
    - The complexity is constant.
22243
22244
    @liveexample{The following code shows an example for `end()`.,end}
22245
22246
    @sa see @ref cend() -- returns a const iterator to the end
22247
    @sa see @ref begin() -- returns an iterator to the beginning
22248
    @sa see @ref cbegin() -- returns a const iterator to the beginning
22249
22250
    @since version 1.0.0
22251
    */
22252
    iterator end() noexcept
22253
0
    {
22254
0
        iterator result(this);
22255
0
        result.set_end();
22256
0
        return result;
22257
0
    }
22258
22259
    /*!
22260
    @copydoc basic_json::cend()
22261
    */
22262
    const_iterator end() const noexcept
22263
15.4M
    {
22264
15.4M
        return cend();
22265
15.4M
    }
22266
22267
    /*!
22268
    @brief returns a const iterator to one past the last element
22269
22270
    Returns a const iterator to one past the last element.
22271
22272
    @image html range-begin-end.svg "Illustration from cppreference.com"
22273
22274
    @return const iterator one past the last element
22275
22276
    @complexity Constant.
22277
22278
    @requirement This function helps `basic_json` satisfying the
22279
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22280
    requirements:
22281
    - The complexity is constant.
22282
    - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
22283
22284
    @liveexample{The following code shows an example for `cend()`.,cend}
22285
22286
    @sa see @ref end() -- returns an iterator to the end
22287
    @sa see @ref begin() -- returns an iterator to the beginning
22288
    @sa see @ref cbegin() -- returns a const iterator to the beginning
22289
22290
    @since version 1.0.0
22291
    */
22292
    const_iterator cend() const noexcept
22293
29.6M
    {
22294
29.6M
        const_iterator result(this);
22295
29.6M
        result.set_end();
22296
29.6M
        return result;
22297
29.6M
    }
22298
22299
    /*!
22300
    @brief returns an iterator to the reverse-beginning
22301
22302
    Returns an iterator to the reverse-beginning; that is, the last element.
22303
22304
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22305
22306
    @complexity Constant.
22307
22308
    @requirement This function helps `basic_json` satisfying the
22309
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22310
    requirements:
22311
    - The complexity is constant.
22312
    - Has the semantics of `reverse_iterator(end())`.
22313
22314
    @liveexample{The following code shows an example for `rbegin()`.,rbegin}
22315
22316
    @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22317
    @sa see @ref rend() -- returns a reverse iterator to the end
22318
    @sa see @ref crend() -- returns a const reverse iterator to the end
22319
22320
    @since version 1.0.0
22321
    */
22322
    reverse_iterator rbegin() noexcept
22323
    {
22324
        return reverse_iterator(end());
22325
    }
22326
22327
    /*!
22328
    @copydoc basic_json::crbegin()
22329
    */
22330
    const_reverse_iterator rbegin() const noexcept
22331
    {
22332
        return crbegin();
22333
    }
22334
22335
    /*!
22336
    @brief returns an iterator to the reverse-end
22337
22338
    Returns an iterator to the reverse-end; that is, one before the first
22339
    element.
22340
22341
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22342
22343
    @complexity Constant.
22344
22345
    @requirement This function helps `basic_json` satisfying the
22346
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22347
    requirements:
22348
    - The complexity is constant.
22349
    - Has the semantics of `reverse_iterator(begin())`.
22350
22351
    @liveexample{The following code shows an example for `rend()`.,rend}
22352
22353
    @sa see @ref crend() -- returns a const reverse iterator to the end
22354
    @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22355
    @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22356
22357
    @since version 1.0.0
22358
    */
22359
    reverse_iterator rend() noexcept
22360
    {
22361
        return reverse_iterator(begin());
22362
    }
22363
22364
    /*!
22365
    @copydoc basic_json::crend()
22366
    */
22367
    const_reverse_iterator rend() const noexcept
22368
    {
22369
        return crend();
22370
    }
22371
22372
    /*!
22373
    @brief returns a const reverse iterator to the last element
22374
22375
    Returns a const iterator to the reverse-beginning; that is, the last
22376
    element.
22377
22378
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22379
22380
    @complexity Constant.
22381
22382
    @requirement This function helps `basic_json` satisfying the
22383
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22384
    requirements:
22385
    - The complexity is constant.
22386
    - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
22387
22388
    @liveexample{The following code shows an example for `crbegin()`.,crbegin}
22389
22390
    @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22391
    @sa see @ref rend() -- returns a reverse iterator to the end
22392
    @sa see @ref crend() -- returns a const reverse iterator to the end
22393
22394
    @since version 1.0.0
22395
    */
22396
    const_reverse_iterator crbegin() const noexcept
22397
    {
22398
        return const_reverse_iterator(cend());
22399
    }
22400
22401
    /*!
22402
    @brief returns a const reverse iterator to one before the first
22403
22404
    Returns a const reverse iterator to the reverse-end; that is, one before
22405
    the first element.
22406
22407
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22408
22409
    @complexity Constant.
22410
22411
    @requirement This function helps `basic_json` satisfying the
22412
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22413
    requirements:
22414
    - The complexity is constant.
22415
    - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
22416
22417
    @liveexample{The following code shows an example for `crend()`.,crend}
22418
22419
    @sa see @ref rend() -- returns a reverse iterator to the end
22420
    @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22421
    @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22422
22423
    @since version 1.0.0
22424
    */
22425
    const_reverse_iterator crend() const noexcept
22426
    {
22427
        return const_reverse_iterator(cbegin());
22428
    }
22429
22430
  public:
22431
    /*!
22432
    @brief wrapper to access iterator member functions in range-based for
22433
22434
    This function allows to access @ref iterator::key() and @ref
22435
    iterator::value() during range-based for loops. In these loops, a
22436
    reference to the JSON values is returned, so there is no access to the
22437
    underlying iterator.
22438
22439
    For loop without iterator_wrapper:
22440
22441
    @code{cpp}
22442
    for (auto it = j_object.begin(); it != j_object.end(); ++it)
22443
    {
22444
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22445
    }
22446
    @endcode
22447
22448
    Range-based for loop without iterator proxy:
22449
22450
    @code{cpp}
22451
    for (auto it : j_object)
22452
    {
22453
        // "it" is of type json::reference and has no key() member
22454
        std::cout << "value: " << it << '\n';
22455
    }
22456
    @endcode
22457
22458
    Range-based for loop with iterator proxy:
22459
22460
    @code{cpp}
22461
    for (auto it : json::iterator_wrapper(j_object))
22462
    {
22463
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22464
    }
22465
    @endcode
22466
22467
    @note When iterating over an array, `key()` will return the index of the
22468
          element as string (see example).
22469
22470
    @param[in] ref  reference to a JSON value
22471
    @return iteration proxy object wrapping @a ref with an interface to use in
22472
            range-based for loops
22473
22474
    @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
22475
22476
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22477
    changes in the JSON value.
22478
22479
    @complexity Constant.
22480
22481
    @note The name of this function is not yet final and may change in the
22482
    future.
22483
22484
    @deprecated This stream operator is deprecated and will be removed in
22485
                future 4.0.0 of the library. Please use @ref items() instead;
22486
                that is, replace `json::iterator_wrapper(j)` with `j.items()`.
22487
    */
22488
    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22489
    static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22490
    {
22491
        return ref.items();
22492
    }
22493
22494
    /*!
22495
    @copydoc iterator_wrapper(reference)
22496
    */
22497
    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22498
    static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22499
    {
22500
        return ref.items();
22501
    }
22502
22503
    /*!
22504
    @brief helper to access iterator member functions in range-based for
22505
22506
    This function allows to access @ref iterator::key() and @ref
22507
    iterator::value() during range-based for loops. In these loops, a
22508
    reference to the JSON values is returned, so there is no access to the
22509
    underlying iterator.
22510
22511
    For loop without `items()` function:
22512
22513
    @code{cpp}
22514
    for (auto it = j_object.begin(); it != j_object.end(); ++it)
22515
    {
22516
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22517
    }
22518
    @endcode
22519
22520
    Range-based for loop without `items()` function:
22521
22522
    @code{cpp}
22523
    for (auto it : j_object)
22524
    {
22525
        // "it" is of type json::reference and has no key() member
22526
        std::cout << "value: " << it << '\n';
22527
    }
22528
    @endcode
22529
22530
    Range-based for loop with `items()` function:
22531
22532
    @code{cpp}
22533
    for (auto& el : j_object.items())
22534
    {
22535
        std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
22536
    }
22537
    @endcode
22538
22539
    The `items()` function also allows to use
22540
    [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
22541
    (C++17):
22542
22543
    @code{cpp}
22544
    for (auto& [key, val] : j_object.items())
22545
    {
22546
        std::cout << "key: " << key << ", value:" << val << '\n';
22547
    }
22548
    @endcode
22549
22550
    @note When iterating over an array, `key()` will return the index of the
22551
          element as string (see example). For primitive types (e.g., numbers),
22552
          `key()` returns an empty string.
22553
22554
    @warning Using `items()` on temporary objects is dangerous. Make sure the
22555
             object's lifetime exeeds the iteration. See
22556
             <https://github.com/nlohmann/json/issues/2040> for more
22557
             information.
22558
22559
    @return iteration proxy object wrapping @a ref with an interface to use in
22560
            range-based for loops
22561
22562
    @liveexample{The following code shows how the function is used.,items}
22563
22564
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22565
    changes in the JSON value.
22566
22567
    @complexity Constant.
22568
22569
    @since version 3.1.0, structured bindings support since 3.5.0.
22570
    */
22571
    iteration_proxy<iterator> items() noexcept
22572
    {
22573
        return iteration_proxy<iterator>(*this);
22574
    }
22575
22576
    /*!
22577
    @copydoc items()
22578
    */
22579
    iteration_proxy<const_iterator> items() const noexcept
22580
0
    {
22581
0
        return iteration_proxy<const_iterator>(*this);
22582
0
    }
22583
22584
    /// @}
22585
22586
22587
    //////////////
22588
    // capacity //
22589
    //////////////
22590
22591
    /// @name capacity
22592
    /// @{
22593
22594
    /*!
22595
    @brief checks whether the container is empty.
22596
22597
    Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
22598
22599
    @return The return value depends on the different types and is
22600
            defined as follows:
22601
            Value type  | return value
22602
            ----------- | -------------
22603
            null        | `true`
22604
            boolean     | `false`
22605
            string      | `false`
22606
            number      | `false`
22607
            binary      | `false`
22608
            object      | result of function `object_t::empty()`
22609
            array       | result of function `array_t::empty()`
22610
22611
    @liveexample{The following code uses `empty()` to check if a JSON
22612
    object contains any elements.,empty}
22613
22614
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22615
    the Container concept; that is, their `empty()` functions have constant
22616
    complexity.
22617
22618
    @iterators No changes.
22619
22620
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
22621
22622
    @note This function does not return whether a string stored as JSON value
22623
    is empty - it returns whether the JSON container itself is empty which is
22624
    false in the case of a string.
22625
22626
    @requirement This function helps `basic_json` satisfying the
22627
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22628
    requirements:
22629
    - The complexity is constant.
22630
    - Has the semantics of `begin() == end()`.
22631
22632
    @sa see @ref size() -- returns the number of elements
22633
22634
    @since version 1.0.0
22635
    */
22636
    bool empty() const noexcept
22637
0
    {
22638
0
        switch (m_type)
22639
0
        {
22640
0
            case value_t::null:
22641
0
            {
22642
                // null values are empty
22643
0
                return true;
22644
0
            }
22645
22646
0
            case value_t::array:
22647
0
            {
22648
                // delegate call to array_t::empty()
22649
0
                return m_value.array->empty();
22650
0
            }
22651
22652
0
            case value_t::object:
22653
0
            {
22654
                // delegate call to object_t::empty()
22655
0
                return m_value.object->empty();
22656
0
            }
22657
22658
0
            case value_t::string:
22659
0
            case value_t::boolean:
22660
0
            case value_t::number_integer:
22661
0
            case value_t::number_unsigned:
22662
0
            case value_t::number_float:
22663
0
            case value_t::binary:
22664
0
            case value_t::discarded:
22665
0
            default:
22666
0
            {
22667
                // all other types are nonempty
22668
0
                return false;
22669
0
            }
22670
0
        }
22671
0
    }
22672
22673
    /*!
22674
    @brief returns the number of elements
22675
22676
    Returns the number of elements in a JSON value.
22677
22678
    @return The return value depends on the different types and is
22679
            defined as follows:
22680
            Value type  | return value
22681
            ----------- | -------------
22682
            null        | `0`
22683
            boolean     | `1`
22684
            string      | `1`
22685
            number      | `1`
22686
            binary      | `1`
22687
            object      | result of function object_t::size()
22688
            array       | result of function array_t::size()
22689
22690
    @liveexample{The following code calls `size()` on the different value
22691
    types.,size}
22692
22693
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22694
    the Container concept; that is, their size() functions have constant
22695
    complexity.
22696
22697
    @iterators No changes.
22698
22699
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
22700
22701
    @note This function does not return the length of a string stored as JSON
22702
    value - it returns the number of elements in the JSON value which is 1 in
22703
    the case of a string.
22704
22705
    @requirement This function helps `basic_json` satisfying the
22706
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22707
    requirements:
22708
    - The complexity is constant.
22709
    - Has the semantics of `std::distance(begin(), end())`.
22710
22711
    @sa see @ref empty() -- checks whether the container is empty
22712
    @sa see @ref max_size() -- returns the maximal number of elements
22713
22714
    @since version 1.0.0
22715
    */
22716
    size_type size() const noexcept
22717
36.8k
    {
22718
36.8k
        switch (m_type)
22719
36.8k
        {
22720
0
            case value_t::null:
22721
0
            {
22722
                // null values are empty
22723
0
                return 0;
22724
0
            }
22725
22726
36.8k
            case value_t::array:
22727
36.8k
            {
22728
                // delegate call to array_t::size()
22729
36.8k
                return m_value.array->size();
22730
0
            }
22731
22732
0
            case value_t::object:
22733
0
            {
22734
                // delegate call to object_t::size()
22735
0
                return m_value.object->size();
22736
0
            }
22737
22738
0
            case value_t::string:
22739
0
            case value_t::boolean:
22740
0
            case value_t::number_integer:
22741
0
            case value_t::number_unsigned:
22742
0
            case value_t::number_float:
22743
0
            case value_t::binary:
22744
0
            case value_t::discarded:
22745
0
            default:
22746
0
            {
22747
                // all other types have size 1
22748
0
                return 1;
22749
0
            }
22750
36.8k
        }
22751
36.8k
    }
22752
22753
    /*!
22754
    @brief returns the maximum possible number of elements
22755
22756
    Returns the maximum number of elements a JSON value is able to hold due to
22757
    system or library implementation limitations, i.e. `std::distance(begin(),
22758
    end())` for the JSON value.
22759
22760
    @return The return value depends on the different types and is
22761
            defined as follows:
22762
            Value type  | return value
22763
            ----------- | -------------
22764
            null        | `0` (same as `size()`)
22765
            boolean     | `1` (same as `size()`)
22766
            string      | `1` (same as `size()`)
22767
            number      | `1` (same as `size()`)
22768
            binary      | `1` (same as `size()`)
22769
            object      | result of function `object_t::max_size()`
22770
            array       | result of function `array_t::max_size()`
22771
22772
    @liveexample{The following code calls `max_size()` on the different value
22773
    types. Note the output is implementation specific.,max_size}
22774
22775
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22776
    the Container concept; that is, their `max_size()` functions have constant
22777
    complexity.
22778
22779
    @iterators No changes.
22780
22781
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
22782
22783
    @requirement This function helps `basic_json` satisfying the
22784
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22785
    requirements:
22786
    - The complexity is constant.
22787
    - Has the semantics of returning `b.size()` where `b` is the largest
22788
      possible JSON value.
22789
22790
    @sa see @ref size() -- returns the number of elements
22791
22792
    @since version 1.0.0
22793
    */
22794
    size_type max_size() const noexcept
22795
0
    {
22796
0
        switch (m_type)
22797
0
        {
22798
0
            case value_t::array:
22799
0
            {
22800
                // delegate call to array_t::max_size()
22801
0
                return m_value.array->max_size();
22802
0
            }
22803
22804
0
            case value_t::object:
22805
0
            {
22806
                // delegate call to object_t::max_size()
22807
0
                return m_value.object->max_size();
22808
0
            }
22809
22810
0
            case value_t::null:
22811
0
            case value_t::string:
22812
0
            case value_t::boolean:
22813
0
            case value_t::number_integer:
22814
0
            case value_t::number_unsigned:
22815
0
            case value_t::number_float:
22816
0
            case value_t::binary:
22817
0
            case value_t::discarded:
22818
0
            default:
22819
0
            {
22820
                // all other types have max_size() == size()
22821
0
                return size();
22822
0
            }
22823
0
        }
22824
0
    }
22825
22826
    /// @}
22827
22828
22829
    ///////////////
22830
    // modifiers //
22831
    ///////////////
22832
22833
    /// @name modifiers
22834
    /// @{
22835
22836
    /*!
22837
    @brief clears the contents
22838
22839
    Clears the content of a JSON value and resets it to the default value as
22840
    if @ref basic_json(value_t) would have been called with the current value
22841
    type from @ref type():
22842
22843
    Value type  | initial value
22844
    ----------- | -------------
22845
    null        | `null`
22846
    boolean     | `false`
22847
    string      | `""`
22848
    number      | `0`
22849
    binary      | An empty byte vector
22850
    object      | `{}`
22851
    array       | `[]`
22852
22853
    @post Has the same effect as calling
22854
    @code {.cpp}
22855
    *this = basic_json(type());
22856
    @endcode
22857
22858
    @liveexample{The example below shows the effect of `clear()` to different
22859
    JSON types.,clear}
22860
22861
    @complexity Linear in the size of the JSON value.
22862
22863
    @iterators All iterators, pointers and references related to this container
22864
               are invalidated.
22865
22866
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
22867
22868
    @sa see @ref basic_json(value_t) -- constructor that creates an object with the
22869
        same value than calling `clear()`
22870
22871
    @since version 1.0.0
22872
    */
22873
    void clear() noexcept
22874
    {
22875
        switch (m_type)
22876
        {
22877
            case value_t::number_integer:
22878
            {
22879
                m_value.number_integer = 0;
22880
                break;
22881
            }
22882
22883
            case value_t::number_unsigned:
22884
            {
22885
                m_value.number_unsigned = 0;
22886
                break;
22887
            }
22888
22889
            case value_t::number_float:
22890
            {
22891
                m_value.number_float = 0.0;
22892
                break;
22893
            }
22894
22895
            case value_t::boolean:
22896
            {
22897
                m_value.boolean = false;
22898
                break;
22899
            }
22900
22901
            case value_t::string:
22902
            {
22903
                m_value.string->clear();
22904
                break;
22905
            }
22906
22907
            case value_t::binary:
22908
            {
22909
                m_value.binary->clear();
22910
                break;
22911
            }
22912
22913
            case value_t::array:
22914
            {
22915
                m_value.array->clear();
22916
                break;
22917
            }
22918
22919
            case value_t::object:
22920
            {
22921
                m_value.object->clear();
22922
                break;
22923
            }
22924
22925
            case value_t::null:
22926
            case value_t::discarded:
22927
            default:
22928
                break;
22929
        }
22930
    }
22931
22932
    /*!
22933
    @brief add an object to an array
22934
22935
    Appends the given element @a val to the end of the JSON value. If the
22936
    function is called on a JSON null value, an empty array is created before
22937
    appending @a val.
22938
22939
    @param[in] val the value to add to the JSON array
22940
22941
    @throw type_error.308 when called on a type other than JSON array or
22942
    null; example: `"cannot use push_back() with number"`
22943
22944
    @complexity Amortized constant.
22945
22946
    @liveexample{The example shows how `push_back()` and `+=` can be used to
22947
    add elements to a JSON array. Note how the `null` value was silently
22948
    converted to a JSON array.,push_back}
22949
22950
    @since version 1.0.0
22951
    */
22952
    void push_back(basic_json&& val)
22953
0
    {
22954
        // push_back only works for null objects or arrays
22955
0
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22956
0
        {
22957
0
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22958
0
        }
22959
22960
        // transform null object into an array
22961
0
        if (is_null())
22962
0
        {
22963
0
            m_type = value_t::array;
22964
0
            m_value = value_t::array;
22965
0
            assert_invariant();
22966
0
        }
22967
22968
        // add element to array (move semantics)
22969
0
        const auto old_capacity = m_value.array->capacity();
22970
0
        m_value.array->push_back(std::move(val));
22971
0
        set_parent(m_value.array->back(), old_capacity);
22972
        // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22973
0
    }
22974
22975
    /*!
22976
    @brief add an object to an array
22977
    @copydoc push_back(basic_json&&)
22978
    */
22979
    reference operator+=(basic_json&& val)
22980
    {
22981
        push_back(std::move(val));
22982
        return *this;
22983
    }
22984
22985
    /*!
22986
    @brief add an object to an array
22987
    @copydoc push_back(basic_json&&)
22988
    */
22989
    void push_back(const basic_json& val)
22990
0
    {
22991
        // push_back only works for null objects or arrays
22992
0
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22993
0
        {
22994
0
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22995
0
        }
22996
22997
        // transform null object into an array
22998
0
        if (is_null())
22999
0
        {
23000
0
            m_type = value_t::array;
23001
0
            m_value = value_t::array;
23002
0
            assert_invariant();
23003
0
        }
23004
23005
        // add element to array
23006
0
        const auto old_capacity = m_value.array->capacity();
23007
0
        m_value.array->push_back(val);
23008
0
        set_parent(m_value.array->back(), old_capacity);
23009
0
    }
23010
23011
    /*!
23012
    @brief add an object to an array
23013
    @copydoc push_back(basic_json&&)
23014
    */
23015
    reference operator+=(const basic_json& val)
23016
    {
23017
        push_back(val);
23018
        return *this;
23019
    }
23020
23021
    /*!
23022
    @brief add an object to an object
23023
23024
    Inserts the given element @a val to the JSON object. If the function is
23025
    called on a JSON null value, an empty object is created before inserting
23026
    @a val.
23027
23028
    @param[in] val the value to add to the JSON object
23029
23030
    @throw type_error.308 when called on a type other than JSON object or
23031
    null; example: `"cannot use push_back() with number"`
23032
23033
    @complexity Logarithmic in the size of the container, O(log(`size()`)).
23034
23035
    @liveexample{The example shows how `push_back()` and `+=` can be used to
23036
    add elements to a JSON object. Note how the `null` value was silently
23037
    converted to a JSON object.,push_back__object_t__value}
23038
23039
    @since version 1.0.0
23040
    */
23041
    void push_back(const typename object_t::value_type& val)
23042
    {
23043
        // push_back only works for null objects or objects
23044
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23045
        {
23046
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23047
        }
23048
23049
        // transform null object into an object
23050
        if (is_null())
23051
        {
23052
            m_type = value_t::object;
23053
            m_value = value_t::object;
23054
            assert_invariant();
23055
        }
23056
23057
        // add element to object
23058
        auto res = m_value.object->insert(val);
23059
        set_parent(res.first->second);
23060
    }
23061
23062
    /*!
23063
    @brief add an object to an object
23064
    @copydoc push_back(const typename object_t::value_type&)
23065
    */
23066
    reference operator+=(const typename object_t::value_type& val)
23067
    {
23068
        push_back(val);
23069
        return *this;
23070
    }
23071
23072
    /*!
23073
    @brief add an object to an object
23074
23075
    This function allows to use `push_back` with an initializer list. In case
23076
23077
    1. the current value is an object,
23078
    2. the initializer list @a init contains only two elements, and
23079
    3. the first element of @a init is a string,
23080
23081
    @a init is converted into an object element and added using
23082
    @ref push_back(const typename object_t::value_type&). Otherwise, @a init
23083
    is converted to a JSON value and added using @ref push_back(basic_json&&).
23084
23085
    @param[in] init  an initializer list
23086
23087
    @complexity Linear in the size of the initializer list @a init.
23088
23089
    @note This function is required to resolve an ambiguous overload error,
23090
          because pairs like `{"key", "value"}` can be both interpreted as
23091
          `object_t::value_type` or `std::initializer_list<basic_json>`, see
23092
          https://github.com/nlohmann/json/issues/235 for more information.
23093
23094
    @liveexample{The example shows how initializer lists are treated as
23095
    objects when possible.,push_back__initializer_list}
23096
    */
23097
    void push_back(initializer_list_t init)
23098
    {
23099
        if (is_object() && init.size() == 2 && (*init.begin())->is_string())
23100
        {
23101
            basic_json&& key = init.begin()->moved_or_copied();
23102
            push_back(typename object_t::value_type(
23103
                          std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
23104
        }
23105
        else
23106
        {
23107
            push_back(basic_json(init));
23108
        }
23109
    }
23110
23111
    /*!
23112
    @brief add an object to an object
23113
    @copydoc push_back(initializer_list_t)
23114
    */
23115
    reference operator+=(initializer_list_t init)
23116
    {
23117
        push_back(init);
23118
        return *this;
23119
    }
23120
23121
    /*!
23122
    @brief add an object to an array
23123
23124
    Creates a JSON value from the passed parameters @a args to the end of the
23125
    JSON value. If the function is called on a JSON null value, an empty array
23126
    is created before appending the value created from @a args.
23127
23128
    @param[in] args arguments to forward to a constructor of @ref basic_json
23129
    @tparam Args compatible types to create a @ref basic_json object
23130
23131
    @return reference to the inserted element
23132
23133
    @throw type_error.311 when called on a type other than JSON array or
23134
    null; example: `"cannot use emplace_back() with number"`
23135
23136
    @complexity Amortized constant.
23137
23138
    @liveexample{The example shows how `push_back()` can be used to add
23139
    elements to a JSON array. Note how the `null` value was silently converted
23140
    to a JSON array.,emplace_back}
23141
23142
    @since version 2.0.8, returns reference since 3.7.0
23143
    */
23144
    template<class... Args>
23145
    reference emplace_back(Args&& ... args)
23146
    {
23147
        // emplace_back only works for null objects or arrays
23148
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23149
        {
23150
            JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23151
        }
23152
23153
        // transform null object into an array
23154
        if (is_null())
23155
        {
23156
            m_type = value_t::array;
23157
            m_value = value_t::array;
23158
            assert_invariant();
23159
        }
23160
23161
        // add element to array (perfect forwarding)
23162
        const auto old_capacity = m_value.array->capacity();
23163
        m_value.array->emplace_back(std::forward<Args>(args)...);
23164
        return set_parent(m_value.array->back(), old_capacity);
23165
    }
23166
23167
    /*!
23168
    @brief add an object to an object if key does not exist
23169
23170
    Inserts a new element into a JSON object constructed in-place with the
23171
    given @a args if there is no element with the key in the container. If the
23172
    function is called on a JSON null value, an empty object is created before
23173
    appending the value created from @a args.
23174
23175
    @param[in] args arguments to forward to a constructor of @ref basic_json
23176
    @tparam Args compatible types to create a @ref basic_json object
23177
23178
    @return a pair consisting of an iterator to the inserted element, or the
23179
            already-existing element if no insertion happened, and a bool
23180
            denoting whether the insertion took place.
23181
23182
    @throw type_error.311 when called on a type other than JSON object or
23183
    null; example: `"cannot use emplace() with number"`
23184
23185
    @complexity Logarithmic in the size of the container, O(log(`size()`)).
23186
23187
    @liveexample{The example shows how `emplace()` can be used to add elements
23188
    to a JSON object. Note how the `null` value was silently converted to a
23189
    JSON object. Further note how no value is added if there was already one
23190
    value stored with the same key.,emplace}
23191
23192
    @since version 2.0.8
23193
    */
23194
    template<class... Args>
23195
    std::pair<iterator, bool> emplace(Args&& ... args)
23196
    {
23197
        // emplace only works for null objects or arrays
23198
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23199
        {
23200
            JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23201
        }
23202
23203
        // transform null object into an object
23204
        if (is_null())
23205
        {
23206
            m_type = value_t::object;
23207
            m_value = value_t::object;
23208
            assert_invariant();
23209
        }
23210
23211
        // add element to array (perfect forwarding)
23212
        auto res = m_value.object->emplace(std::forward<Args>(args)...);
23213
        set_parent(res.first->second);
23214
23215
        // create result iterator and set iterator to the result of emplace
23216
        auto it = begin();
23217
        it.m_it.object_iterator = res.first;
23218
23219
        // return pair of iterator and boolean
23220
        return {it, res.second};
23221
    }
23222
23223
    /// Helper for insertion of an iterator
23224
    /// @note: This uses std::distance to support GCC 4.8,
23225
    ///        see https://github.com/nlohmann/json/pull/1257
23226
    template<typename... Args>
23227
    iterator insert_iterator(const_iterator pos, Args&& ... args)
23228
    {
23229
        iterator result(this);
23230
        JSON_ASSERT(m_value.array != nullptr);
23231
23232
        auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23233
        m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23234
        result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23235
23236
        // This could have been written as:
23237
        // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23238
        // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23239
23240
        set_parents();
23241
        return result;
23242
    }
23243
23244
    /*!
23245
    @brief inserts element
23246
23247
    Inserts element @a val before iterator @a pos.
23248
23249
    @param[in] pos iterator before which the content will be inserted; may be
23250
    the end() iterator
23251
    @param[in] val element to insert
23252
    @return iterator pointing to the inserted @a val.
23253
23254
    @throw type_error.309 if called on JSON values other than arrays;
23255
    example: `"cannot use insert() with string"`
23256
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23257
    example: `"iterator does not fit current value"`
23258
23259
    @complexity Constant plus linear in the distance between @a pos and end of
23260
    the container.
23261
23262
    @liveexample{The example shows how `insert()` is used.,insert}
23263
23264
    @since version 1.0.0
23265
    */
23266
    iterator insert(const_iterator pos, const basic_json& val)
23267
    {
23268
        // insert only works for arrays
23269
        if (JSON_HEDLEY_LIKELY(is_array()))
23270
        {
23271
            // check if iterator pos fits to this JSON value
23272
            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23273
            {
23274
                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23275
            }
23276
23277
            // insert to array and return iterator
23278
            return insert_iterator(pos, val);
23279
        }
23280
23281
        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23282
    }
23283
23284
    /*!
23285
    @brief inserts element
23286
    @copydoc insert(const_iterator, const basic_json&)
23287
    */
23288
    iterator insert(const_iterator pos, basic_json&& val)
23289
    {
23290
        return insert(pos, val);
23291
    }
23292
23293
    /*!
23294
    @brief inserts elements
23295
23296
    Inserts @a cnt copies of @a val before iterator @a pos.
23297
23298
    @param[in] pos iterator before which the content will be inserted; may be
23299
    the end() iterator
23300
    @param[in] cnt number of copies of @a val to insert
23301
    @param[in] val element to insert
23302
    @return iterator pointing to the first element inserted, or @a pos if
23303
    `cnt==0`
23304
23305
    @throw type_error.309 if called on JSON values other than arrays; example:
23306
    `"cannot use insert() with string"`
23307
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23308
    example: `"iterator does not fit current value"`
23309
23310
    @complexity Linear in @a cnt plus linear in the distance between @a pos
23311
    and end of the container.
23312
23313
    @liveexample{The example shows how `insert()` is used.,insert__count}
23314
23315
    @since version 1.0.0
23316
    */
23317
    iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
23318
    {
23319
        // insert only works for arrays
23320
        if (JSON_HEDLEY_LIKELY(is_array()))
23321
        {
23322
            // check if iterator pos fits to this JSON value
23323
            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23324
            {
23325
                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23326
            }
23327
23328
            // insert to array and return iterator
23329
            return insert_iterator(pos, cnt, val);
23330
        }
23331
23332
        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23333
    }
23334
23335
    /*!
23336
    @brief inserts elements
23337
23338
    Inserts elements from range `[first, last)` before iterator @a pos.
23339
23340
    @param[in] pos iterator before which the content will be inserted; may be
23341
    the end() iterator
23342
    @param[in] first begin of the range of elements to insert
23343
    @param[in] last end of the range of elements to insert
23344
23345
    @throw type_error.309 if called on JSON values other than arrays; example:
23346
    `"cannot use insert() with string"`
23347
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23348
    example: `"iterator does not fit current value"`
23349
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
23350
    same JSON value; example: `"iterators do not fit"`
23351
    @throw invalid_iterator.211 if @a first or @a last are iterators into
23352
    container for which insert is called; example: `"passed iterators may not
23353
    belong to container"`
23354
23355
    @return iterator pointing to the first element inserted, or @a pos if
23356
    `first==last`
23357
23358
    @complexity Linear in `std::distance(first, last)` plus linear in the
23359
    distance between @a pos and end of the container.
23360
23361
    @liveexample{The example shows how `insert()` is used.,insert__range}
23362
23363
    @since version 1.0.0
23364
    */
23365
    iterator insert(const_iterator pos, const_iterator first, const_iterator last)
23366
    {
23367
        // insert only works for arrays
23368
        if (JSON_HEDLEY_UNLIKELY(!is_array()))
23369
        {
23370
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23371
        }
23372
23373
        // check if iterator pos fits to this JSON value
23374
        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23375
        {
23376
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23377
        }
23378
23379
        // check if range iterators belong to the same JSON object
23380
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23381
        {
23382
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23383
        }
23384
23385
        if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23386
        {
23387
            JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23388
        }
23389
23390
        // insert to array and return iterator
23391
        return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23392
    }
23393
23394
    /*!
23395
    @brief inserts elements
23396
23397
    Inserts elements from initializer list @a ilist before iterator @a pos.
23398
23399
    @param[in] pos iterator before which the content will be inserted; may be
23400
    the end() iterator
23401
    @param[in] ilist initializer list to insert the values from
23402
23403
    @throw type_error.309 if called on JSON values other than arrays; example:
23404
    `"cannot use insert() with string"`
23405
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23406
    example: `"iterator does not fit current value"`
23407
23408
    @return iterator pointing to the first element inserted, or @a pos if
23409
    `ilist` is empty
23410
23411
    @complexity Linear in `ilist.size()` plus linear in the distance between
23412
    @a pos and end of the container.
23413
23414
    @liveexample{The example shows how `insert()` is used.,insert__ilist}
23415
23416
    @since version 1.0.0
23417
    */
23418
    iterator insert(const_iterator pos, initializer_list_t ilist)
23419
    {
23420
        // insert only works for arrays
23421
        if (JSON_HEDLEY_UNLIKELY(!is_array()))
23422
        {
23423
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23424
        }
23425
23426
        // check if iterator pos fits to this JSON value
23427
        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23428
        {
23429
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23430
        }
23431
23432
        // insert to array and return iterator
23433
        return insert_iterator(pos, ilist.begin(), ilist.end());
23434
    }
23435
23436
    /*!
23437
    @brief inserts elements
23438
23439
    Inserts elements from range `[first, last)`.
23440
23441
    @param[in] first begin of the range of elements to insert
23442
    @param[in] last end of the range of elements to insert
23443
23444
    @throw type_error.309 if called on JSON values other than objects; example:
23445
    `"cannot use insert() with string"`
23446
    @throw invalid_iterator.202 if iterator @a first or @a last does does not
23447
    point to an object; example: `"iterators first and last must point to
23448
    objects"`
23449
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
23450
    same JSON value; example: `"iterators do not fit"`
23451
23452
    @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
23453
    of elements to insert.
23454
23455
    @liveexample{The example shows how `insert()` is used.,insert__range_object}
23456
23457
    @since version 3.0.0
23458
    */
23459
    void insert(const_iterator first, const_iterator last)
23460
    {
23461
        // insert only works for objects
23462
        if (JSON_HEDLEY_UNLIKELY(!is_object()))
23463
        {
23464
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23465
        }
23466
23467
        // check if range iterators belong to the same JSON object
23468
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23469
        {
23470
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23471
        }
23472
23473
        // passed iterators must belong to objects
23474
        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23475
        {
23476
            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23477
        }
23478
23479
        m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23480
    }
23481
23482
    /*!
23483
    @brief updates a JSON object from another object, overwriting existing keys
23484
23485
    Inserts all values from JSON object @a j and overwrites existing keys.
23486
23487
    @param[in] j  JSON object to read values from
23488
23489
    @throw type_error.312 if called on JSON values other than objects; example:
23490
    `"cannot use update() with string"`
23491
23492
    @complexity O(N*log(size() + N)), where N is the number of elements to
23493
                insert.
23494
23495
    @liveexample{The example shows how `update()` is used.,update}
23496
23497
    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23498
23499
    @since version 3.0.0
23500
    */
23501
    void update(const_reference j)
23502
    {
23503
        // implicitly convert null value to an empty object
23504
        if (is_null())
23505
        {
23506
            m_type = value_t::object;
23507
            m_value.object = create<object_t>();
23508
            assert_invariant();
23509
        }
23510
23511
        if (JSON_HEDLEY_UNLIKELY(!is_object()))
23512
        {
23513
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23514
        }
23515
        if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
23516
        {
23517
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23518
        }
23519
23520
        for (auto it = j.cbegin(); it != j.cend(); ++it)
23521
        {
23522
            m_value.object->operator[](it.key()) = it.value();
23523
#if JSON_DIAGNOSTICS
23524
            m_value.object->operator[](it.key()).m_parent = this;
23525
#endif
23526
        }
23527
    }
23528
23529
    /*!
23530
    @brief updates a JSON object from another object, overwriting existing keys
23531
23532
    Inserts all values from from range `[first, last)` and overwrites existing
23533
    keys.
23534
23535
    @param[in] first begin of the range of elements to insert
23536
    @param[in] last end of the range of elements to insert
23537
23538
    @throw type_error.312 if called on JSON values other than objects; example:
23539
    `"cannot use update() with string"`
23540
    @throw invalid_iterator.202 if iterator @a first or @a last does does not
23541
    point to an object; example: `"iterators first and last must point to
23542
    objects"`
23543
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
23544
    same JSON value; example: `"iterators do not fit"`
23545
23546
    @complexity O(N*log(size() + N)), where N is the number of elements to
23547
                insert.
23548
23549
    @liveexample{The example shows how `update()` is used__range.,update}
23550
23551
    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23552
23553
    @since version 3.0.0
23554
    */
23555
    void update(const_iterator first, const_iterator last)
23556
    {
23557
        // implicitly convert null value to an empty object
23558
        if (is_null())
23559
        {
23560
            m_type = value_t::object;
23561
            m_value.object = create<object_t>();
23562
            assert_invariant();
23563
        }
23564
23565
        if (JSON_HEDLEY_UNLIKELY(!is_object()))
23566
        {
23567
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23568
        }
23569
23570
        // check if range iterators belong to the same JSON object
23571
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23572
        {
23573
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23574
        }
23575
23576
        // passed iterators must belong to objects
23577
        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
23578
                                 || !last.m_object->is_object()))
23579
        {
23580
            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23581
        }
23582
23583
        for (auto it = first; it != last; ++it)
23584
        {
23585
            m_value.object->operator[](it.key()) = it.value();
23586
#if JSON_DIAGNOSTICS
23587
            m_value.object->operator[](it.key()).m_parent = this;
23588
#endif
23589
        }
23590
    }
23591
23592
    /*!
23593
    @brief exchanges the values
23594
23595
    Exchanges the contents of the JSON value with those of @a other. Does not
23596
    invoke any move, copy, or swap operations on individual elements. All
23597
    iterators and references remain valid. The past-the-end iterator is
23598
    invalidated.
23599
23600
    @param[in,out] other JSON value to exchange the contents with
23601
23602
    @complexity Constant.
23603
23604
    @liveexample{The example below shows how JSON values can be swapped with
23605
    `swap()`.,swap__reference}
23606
23607
    @since version 1.0.0
23608
    */
23609
    void swap(reference other) noexcept (
23610
        std::is_nothrow_move_constructible<value_t>::value&&
23611
        std::is_nothrow_move_assignable<value_t>::value&&
23612
        std::is_nothrow_move_constructible<json_value>::value&&
23613
        std::is_nothrow_move_assignable<json_value>::value
23614
    )
23615
0
    {
23616
0
        std::swap(m_type, other.m_type);
23617
0
        std::swap(m_value, other.m_value);
23618
0
23619
0
        set_parents();
23620
0
        other.set_parents();
23621
0
        assert_invariant();
23622
0
    }
23623
23624
    /*!
23625
    @brief exchanges the values
23626
23627
    Exchanges the contents of the JSON value from @a left with those of @a right. Does not
23628
    invoke any move, copy, or swap operations on individual elements. All
23629
    iterators and references remain valid. The past-the-end iterator is
23630
    invalidated. implemented as a friend function callable via ADL.
23631
23632
    @param[in,out] left JSON value to exchange the contents with
23633
    @param[in,out] right JSON value to exchange the contents with
23634
23635
    @complexity Constant.
23636
23637
    @liveexample{The example below shows how JSON values can be swapped with
23638
    `swap()`.,swap__reference}
23639
23640
    @since version 1.0.0
23641
    */
23642
    friend void swap(reference left, reference right) noexcept (
23643
        std::is_nothrow_move_constructible<value_t>::value&&
23644
        std::is_nothrow_move_assignable<value_t>::value&&
23645
        std::is_nothrow_move_constructible<json_value>::value&&
23646
        std::is_nothrow_move_assignable<json_value>::value
23647
    )
23648
    {
23649
        left.swap(right);
23650
    }
23651
23652
    /*!
23653
    @brief exchanges the values
23654
23655
    Exchanges the contents of a JSON array with those of @a other. Does not
23656
    invoke any move, copy, or swap operations on individual elements. All
23657
    iterators and references remain valid. The past-the-end iterator is
23658
    invalidated.
23659
23660
    @param[in,out] other array to exchange the contents with
23661
23662
    @throw type_error.310 when JSON value is not an array; example: `"cannot
23663
    use swap() with string"`
23664
23665
    @complexity Constant.
23666
23667
    @liveexample{The example below shows how arrays can be swapped with
23668
    `swap()`.,swap__array_t}
23669
23670
    @since version 1.0.0
23671
    */
23672
    void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23673
    {
23674
        // swap only works for arrays
23675
        if (JSON_HEDLEY_LIKELY(is_array()))
23676
        {
23677
            std::swap(*(m_value.array), other);
23678
        }
23679
        else
23680
        {
23681
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23682
        }
23683
    }
23684
23685
    /*!
23686
    @brief exchanges the values
23687
23688
    Exchanges the contents of a JSON object with those of @a other. Does not
23689
    invoke any move, copy, or swap operations on individual elements. All
23690
    iterators and references remain valid. The past-the-end iterator is
23691
    invalidated.
23692
23693
    @param[in,out] other object to exchange the contents with
23694
23695
    @throw type_error.310 when JSON value is not an object; example:
23696
    `"cannot use swap() with string"`
23697
23698
    @complexity Constant.
23699
23700
    @liveexample{The example below shows how objects can be swapped with
23701
    `swap()`.,swap__object_t}
23702
23703
    @since version 1.0.0
23704
    */
23705
    void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23706
    {
23707
        // swap only works for objects
23708
        if (JSON_HEDLEY_LIKELY(is_object()))
23709
        {
23710
            std::swap(*(m_value.object), other);
23711
        }
23712
        else
23713
        {
23714
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23715
        }
23716
    }
23717
23718
    /*!
23719
    @brief exchanges the values
23720
23721
    Exchanges the contents of a JSON string with those of @a other. Does not
23722
    invoke any move, copy, or swap operations on individual elements. All
23723
    iterators and references remain valid. The past-the-end iterator is
23724
    invalidated.
23725
23726
    @param[in,out] other string to exchange the contents with
23727
23728
    @throw type_error.310 when JSON value is not a string; example: `"cannot
23729
    use swap() with boolean"`
23730
23731
    @complexity Constant.
23732
23733
    @liveexample{The example below shows how strings can be swapped with
23734
    `swap()`.,swap__string_t}
23735
23736
    @since version 1.0.0
23737
    */
23738
    void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23739
    {
23740
        // swap only works for strings
23741
        if (JSON_HEDLEY_LIKELY(is_string()))
23742
        {
23743
            std::swap(*(m_value.string), other);
23744
        }
23745
        else
23746
        {
23747
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23748
        }
23749
    }
23750
23751
    /*!
23752
    @brief exchanges the values
23753
23754
    Exchanges the contents of a JSON string with those of @a other. Does not
23755
    invoke any move, copy, or swap operations on individual elements. All
23756
    iterators and references remain valid. The past-the-end iterator is
23757
    invalidated.
23758
23759
    @param[in,out] other binary to exchange the contents with
23760
23761
    @throw type_error.310 when JSON value is not a string; example: `"cannot
23762
    use swap() with boolean"`
23763
23764
    @complexity Constant.
23765
23766
    @liveexample{The example below shows how strings can be swapped with
23767
    `swap()`.,swap__binary_t}
23768
23769
    @since version 3.8.0
23770
    */
23771
    void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23772
    {
23773
        // swap only works for strings
23774
        if (JSON_HEDLEY_LIKELY(is_binary()))
23775
        {
23776
            std::swap(*(m_value.binary), other);
23777
        }
23778
        else
23779
        {
23780
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23781
        }
23782
    }
23783
23784
    /// @copydoc swap(binary_t&)
23785
    void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23786
    {
23787
        // swap only works for strings
23788
        if (JSON_HEDLEY_LIKELY(is_binary()))
23789
        {
23790
            std::swap(*(m_value.binary), other);
23791
        }
23792
        else
23793
        {
23794
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23795
        }
23796
    }
23797
23798
    /// @}
23799
23800
  public:
23801
    //////////////////////////////////////////
23802
    // lexicographical comparison operators //
23803
    //////////////////////////////////////////
23804
23805
    /// @name lexicographical comparison operators
23806
    /// @{
23807
23808
    /*!
23809
    @brief comparison: equal
23810
23811
    Compares two JSON values for equality according to the following rules:
23812
    - Two JSON values are equal if (1) they are from the same type and (2)
23813
      their stored values are the same according to their respective
23814
      `operator==`.
23815
    - Integer and floating-point numbers are automatically converted before
23816
      comparison. Note that two NaN values are always treated as unequal.
23817
    - Two JSON null values are equal.
23818
23819
    @note Floating-point inside JSON values numbers are compared with
23820
    `json::number_float_t::operator==` which is `double::operator==` by
23821
    default. To compare floating-point while respecting an epsilon, an alternative
23822
    [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
23823
    could be used, for instance
23824
    @code {.cpp}
23825
    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
23826
    inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
23827
    {
23828
        return std::abs(a - b) <= epsilon;
23829
    }
23830
    @endcode
23831
    Or you can self-defined operator equal function like this:
23832
    @code {.cpp}
23833
    bool my_equal(const_reference lhs, const_reference rhs) {
23834
    const auto lhs_type lhs.type();
23835
    const auto rhs_type rhs.type();
23836
    if (lhs_type == rhs_type) {
23837
        switch(lhs_type)
23838
            // self_defined case
23839
            case value_t::number_float:
23840
                return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
23841
            // other cases remain the same with the original
23842
            ...
23843
    }
23844
    ...
23845
    }
23846
    @endcode
23847
23848
    @note NaN values never compare equal to themselves or to other NaN values.
23849
23850
    @param[in] lhs  first JSON value to consider
23851
    @param[in] rhs  second JSON value to consider
23852
    @return whether the values @a lhs and @a rhs are equal
23853
23854
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
23855
23856
    @complexity Linear.
23857
23858
    @liveexample{The example demonstrates comparing several JSON
23859
    types.,operator__equal}
23860
23861
    @since version 1.0.0
23862
    */
23863
    friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23864
    {
23865
#ifdef __GNUC__
23866
#pragma GCC diagnostic push
23867
#pragma GCC diagnostic ignored "-Wfloat-equal"
23868
#endif
23869
        const auto lhs_type = lhs.type();
23870
        const auto rhs_type = rhs.type();
23871
23872
        if (lhs_type == rhs_type)
23873
        {
23874
            switch (lhs_type)
23875
            {
23876
                case value_t::array:
23877
                    return *lhs.m_value.array == *rhs.m_value.array;
23878
23879
                case value_t::object:
23880
                    return *lhs.m_value.object == *rhs.m_value.object;
23881
23882
                case value_t::null:
23883
                    return true;
23884
23885
                case value_t::string:
23886
                    return *lhs.m_value.string == *rhs.m_value.string;
23887
23888
                case value_t::boolean:
23889
                    return lhs.m_value.boolean == rhs.m_value.boolean;
23890
23891
                case value_t::number_integer:
23892
                    return lhs.m_value.number_integer == rhs.m_value.number_integer;
23893
23894
                case value_t::number_unsigned:
23895
                    return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23896
23897
                case value_t::number_float:
23898
                    return lhs.m_value.number_float == rhs.m_value.number_float;
23899
23900
                case value_t::binary:
23901
                    return *lhs.m_value.binary == *rhs.m_value.binary;
23902
23903
                case value_t::discarded:
23904
                default:
23905
                    return false;
23906
            }
23907
        }
23908
        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23909
        {
23910
            return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23911
        }
23912
        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23913
        {
23914
            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23915
        }
23916
        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23917
        {
23918
            return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23919
        }
23920
        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23921
        {
23922
            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23923
        }
23924
        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23925
        {
23926
            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23927
        }
23928
        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23929
        {
23930
            return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23931
        }
23932
23933
        return false;
23934
#ifdef __GNUC__
23935
#pragma GCC diagnostic pop
23936
#endif
23937
    }
23938
23939
    /*!
23940
    @brief comparison: equal
23941
    @copydoc operator==(const_reference, const_reference)
23942
    */
23943
    template<typename ScalarType, typename std::enable_if<
23944
                 std::is_scalar<ScalarType>::value, int>::type = 0>
23945
    friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23946
    {
23947
        return lhs == basic_json(rhs);
23948
    }
23949
23950
    /*!
23951
    @brief comparison: equal
23952
    @copydoc operator==(const_reference, const_reference)
23953
    */
23954
    template<typename ScalarType, typename std::enable_if<
23955
                 std::is_scalar<ScalarType>::value, int>::type = 0>
23956
    friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23957
    {
23958
        return basic_json(lhs) == rhs;
23959
    }
23960
23961
    /*!
23962
    @brief comparison: not equal
23963
23964
    Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
23965
23966
    @param[in] lhs  first JSON value to consider
23967
    @param[in] rhs  second JSON value to consider
23968
    @return whether the values @a lhs and @a rhs are not equal
23969
23970
    @complexity Linear.
23971
23972
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
23973
23974
    @liveexample{The example demonstrates comparing several JSON
23975
    types.,operator__notequal}
23976
23977
    @since version 1.0.0
23978
    */
23979
    friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23980
    {
23981
        return !(lhs == rhs);
23982
    }
23983
23984
    /*!
23985
    @brief comparison: not equal
23986
    @copydoc operator!=(const_reference, const_reference)
23987
    */
23988
    template<typename ScalarType, typename std::enable_if<
23989
                 std::is_scalar<ScalarType>::value, int>::type = 0>
23990
    friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23991
    {
23992
        return lhs != basic_json(rhs);
23993
    }
23994
23995
    /*!
23996
    @brief comparison: not equal
23997
    @copydoc operator!=(const_reference, const_reference)
23998
    */
23999
    template<typename ScalarType, typename std::enable_if<
24000
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24001
    friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
24002
    {
24003
        return basic_json(lhs) != rhs;
24004
    }
24005
24006
    /*!
24007
    @brief comparison: less than
24008
24009
    Compares whether one JSON value @a lhs is less than another JSON value @a
24010
    rhs according to the following rules:
24011
    - If @a lhs and @a rhs have the same type, the values are compared using
24012
      the default `<` operator.
24013
    - Integer and floating-point numbers are automatically converted before
24014
      comparison
24015
    - In case @a lhs and @a rhs have different types, the values are ignored
24016
      and the order of the types is considered, see
24017
      @ref operator<(const value_t, const value_t).
24018
24019
    @param[in] lhs  first JSON value to consider
24020
    @param[in] rhs  second JSON value to consider
24021
    @return whether @a lhs is less than @a rhs
24022
24023
    @complexity Linear.
24024
24025
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
24026
24027
    @liveexample{The example demonstrates comparing several JSON
24028
    types.,operator__less}
24029
24030
    @since version 1.0.0
24031
    */
24032
    friend bool operator<(const_reference lhs, const_reference rhs) noexcept
24033
    {
24034
        const auto lhs_type = lhs.type();
24035
        const auto rhs_type = rhs.type();
24036
24037
        if (lhs_type == rhs_type)
24038
        {
24039
            switch (lhs_type)
24040
            {
24041
                case value_t::array:
24042
                    // note parentheses are necessary, see
24043
                    // https://github.com/nlohmann/json/issues/1530
24044
                    return (*lhs.m_value.array) < (*rhs.m_value.array);
24045
24046
                case value_t::object:
24047
                    return (*lhs.m_value.object) < (*rhs.m_value.object);
24048
24049
                case value_t::null:
24050
                    return false;
24051
24052
                case value_t::string:
24053
                    return (*lhs.m_value.string) < (*rhs.m_value.string);
24054
24055
                case value_t::boolean:
24056
                    return (lhs.m_value.boolean) < (rhs.m_value.boolean);
24057
24058
                case value_t::number_integer:
24059
                    return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
24060
24061
                case value_t::number_unsigned:
24062
                    return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
24063
24064
                case value_t::number_float:
24065
                    return (lhs.m_value.number_float) < (rhs.m_value.number_float);
24066
24067
                case value_t::binary:
24068
                    return (*lhs.m_value.binary) < (*rhs.m_value.binary);
24069
24070
                case value_t::discarded:
24071
                default:
24072
                    return false;
24073
            }
24074
        }
24075
        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
24076
        {
24077
            return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
24078
        }
24079
        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
24080
        {
24081
            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
24082
        }
24083
        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
24084
        {
24085
            return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
24086
        }
24087
        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
24088
        {
24089
            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
24090
        }
24091
        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
24092
        {
24093
            return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
24094
        }
24095
        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
24096
        {
24097
            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
24098
        }
24099
24100
        // We only reach this line if we cannot compare values. In that case,
24101
        // we compare types. Note we have to call the operator explicitly,
24102
        // because MSVC has problems otherwise.
24103
        return operator<(lhs_type, rhs_type);
24104
    }
24105
24106
    /*!
24107
    @brief comparison: less than
24108
    @copydoc operator<(const_reference, const_reference)
24109
    */
24110
    template<typename ScalarType, typename std::enable_if<
24111
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24112
    friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24113
    {
24114
        return lhs < basic_json(rhs);
24115
    }
24116
24117
    /*!
24118
    @brief comparison: less than
24119
    @copydoc operator<(const_reference, const_reference)
24120
    */
24121
    template<typename ScalarType, typename std::enable_if<
24122
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24123
    friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24124
    {
24125
        return basic_json(lhs) < rhs;
24126
    }
24127
24128
    /*!
24129
    @brief comparison: less than or equal
24130
24131
    Compares whether one JSON value @a lhs is less than or equal to another
24132
    JSON value by calculating `not (rhs < lhs)`.
24133
24134
    @param[in] lhs  first JSON value to consider
24135
    @param[in] rhs  second JSON value to consider
24136
    @return whether @a lhs is less than or equal to @a rhs
24137
24138
    @complexity Linear.
24139
24140
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
24141
24142
    @liveexample{The example demonstrates comparing several JSON
24143
    types.,operator__greater}
24144
24145
    @since version 1.0.0
24146
    */
24147
    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24148
    {
24149
        return !(rhs < lhs);
24150
    }
24151
24152
    /*!
24153
    @brief comparison: less than or equal
24154
    @copydoc operator<=(const_reference, const_reference)
24155
    */
24156
    template<typename ScalarType, typename std::enable_if<
24157
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24158
    friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24159
    {
24160
        return lhs <= basic_json(rhs);
24161
    }
24162
24163
    /*!
24164
    @brief comparison: less than or equal
24165
    @copydoc operator<=(const_reference, const_reference)
24166
    */
24167
    template<typename ScalarType, typename std::enable_if<
24168
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24169
    friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24170
    {
24171
        return basic_json(lhs) <= rhs;
24172
    }
24173
24174
    /*!
24175
    @brief comparison: greater than
24176
24177
    Compares whether one JSON value @a lhs is greater than another
24178
    JSON value by calculating `not (lhs <= rhs)`.
24179
24180
    @param[in] lhs  first JSON value to consider
24181
    @param[in] rhs  second JSON value to consider
24182
    @return whether @a lhs is greater than to @a rhs
24183
24184
    @complexity Linear.
24185
24186
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
24187
24188
    @liveexample{The example demonstrates comparing several JSON
24189
    types.,operator__lessequal}
24190
24191
    @since version 1.0.0
24192
    */
24193
    friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24194
    {
24195
        return !(lhs <= rhs);
24196
    }
24197
24198
    /*!
24199
    @brief comparison: greater than
24200
    @copydoc operator>(const_reference, const_reference)
24201
    */
24202
    template<typename ScalarType, typename std::enable_if<
24203
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24204
    friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24205
    {
24206
        return lhs > basic_json(rhs);
24207
    }
24208
24209
    /*!
24210
    @brief comparison: greater than
24211
    @copydoc operator>(const_reference, const_reference)
24212
    */
24213
    template<typename ScalarType, typename std::enable_if<
24214
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24215
    friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24216
    {
24217
        return basic_json(lhs) > rhs;
24218
    }
24219
24220
    /*!
24221
    @brief comparison: greater than or equal
24222
24223
    Compares whether one JSON value @a lhs is greater than or equal to another
24224
    JSON value by calculating `not (lhs < rhs)`.
24225
24226
    @param[in] lhs  first JSON value to consider
24227
    @param[in] rhs  second JSON value to consider
24228
    @return whether @a lhs is greater than or equal to @a rhs
24229
24230
    @complexity Linear.
24231
24232
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
24233
24234
    @liveexample{The example demonstrates comparing several JSON
24235
    types.,operator__greaterequal}
24236
24237
    @since version 1.0.0
24238
    */
24239
    friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24240
    {
24241
        return !(lhs < rhs);
24242
    }
24243
24244
    /*!
24245
    @brief comparison: greater than or equal
24246
    @copydoc operator>=(const_reference, const_reference)
24247
    */
24248
    template<typename ScalarType, typename std::enable_if<
24249
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24250
    friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24251
    {
24252
        return lhs >= basic_json(rhs);
24253
    }
24254
24255
    /*!
24256
    @brief comparison: greater than or equal
24257
    @copydoc operator>=(const_reference, const_reference)
24258
    */
24259
    template<typename ScalarType, typename std::enable_if<
24260
                 std::is_scalar<ScalarType>::value, int>::type = 0>
24261
    friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24262
    {
24263
        return basic_json(lhs) >= rhs;
24264
    }
24265
24266
    /// @}
24267
24268
    ///////////////////
24269
    // serialization //
24270
    ///////////////////
24271
24272
    /// @name serialization
24273
    /// @{
24274
#ifndef JSON_NO_IO
24275
    /*!
24276
    @brief serialize to stream
24277
24278
    Serialize the given JSON value @a j to the output stream @a o. The JSON
24279
    value will be serialized using the @ref dump member function.
24280
24281
    - The indentation of the output can be controlled with the member variable
24282
      `width` of the output stream @a o. For instance, using the manipulator
24283
      `std::setw(4)` on @a o sets the indentation level to `4` and the
24284
      serialization result is the same as calling `dump(4)`.
24285
24286
    - The indentation character can be controlled with the member variable
24287
      `fill` of the output stream @a o. For instance, the manipulator
24288
      `std::setfill('\\t')` sets indentation to use a tab character rather than
24289
      the default space character.
24290
24291
    @param[in,out] o  stream to serialize to
24292
    @param[in] j  JSON value to serialize
24293
24294
    @return the stream @a o
24295
24296
    @throw type_error.316 if a string stored inside the JSON value is not
24297
                          UTF-8 encoded
24298
24299
    @complexity Linear.
24300
24301
    @liveexample{The example below shows the serialization with different
24302
    parameters to `width` to adjust the indentation level.,operator_serialize}
24303
24304
    @since version 1.0.0; indentation character added in version 3.0.0
24305
    */
24306
    friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24307
    {
24308
        // read width member and use it as indentation parameter if nonzero
24309
        const bool pretty_print = o.width() > 0;
24310
        const auto indentation = pretty_print ? o.width() : 0;
24311
24312
        // reset width to 0 for subsequent calls to this stream
24313
        o.width(0);
24314
24315
        // do the actual serialization
24316
        serializer s(detail::output_adapter<char>(o), o.fill());
24317
        s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24318
        return o;
24319
    }
24320
24321
    /*!
24322
    @brief serialize to stream
24323
    @deprecated This stream operator is deprecated and will be removed in
24324
                future 4.0.0 of the library. Please use
24325
                @ref operator<<(std::ostream&, const basic_json&)
24326
                instead; that is, replace calls like `j >> o;` with `o << j;`.
24327
    @since version 1.0.0; deprecated since version 3.0.0
24328
    */
24329
    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24330
    friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24331
    {
24332
        return o << j;
24333
    }
24334
#endif  // JSON_NO_IO
24335
    /// @}
24336
24337
24338
    /////////////////////
24339
    // deserialization //
24340
    /////////////////////
24341
24342
    /// @name deserialization
24343
    /// @{
24344
24345
    /*!
24346
    @brief deserialize from a compatible input
24347
24348
    @tparam InputType A compatible input, for instance
24349
    - an std::istream object
24350
    - a FILE pointer
24351
    - a C-style array of characters
24352
    - a pointer to a null-terminated string of single byte characters
24353
    - an object obj for which begin(obj) and end(obj) produces a valid pair of
24354
      iterators.
24355
24356
    @param[in] i  input to read from
24357
    @param[in] cb  a parser callback function of type @ref parser_callback_t
24358
    which is used to control the deserialization by filtering unwanted values
24359
    (optional)
24360
    @param[in] allow_exceptions  whether to throw exceptions in case of a
24361
    parse error (optional, true by default)
24362
    @param[in] ignore_comments  whether comments should be ignored and treated
24363
    like whitespace (true) or yield a parse error (true); (optional, false by
24364
    default)
24365
24366
    @return deserialized JSON value; in case of a parse error and
24367
            @a allow_exceptions set to `false`, the return value will be
24368
            value_t::discarded.
24369
24370
    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24371
    of input; expected string literal""`
24372
    @throw parse_error.102 if to_unicode fails or surrogate error
24373
    @throw parse_error.103 if to_unicode fails
24374
24375
    @complexity Linear in the length of the input. The parser is a predictive
24376
    LL(1) parser. The complexity can be higher if the parser callback function
24377
    @a cb or reading from the input @a i has a super-linear complexity.
24378
24379
    @note A UTF-8 byte order mark is silently ignored.
24380
24381
    @liveexample{The example below demonstrates the `parse()` function reading
24382
    from an array.,parse__array__parser_callback_t}
24383
24384
    @liveexample{The example below demonstrates the `parse()` function with
24385
    and without callback function.,parse__string__parser_callback_t}
24386
24387
    @liveexample{The example below demonstrates the `parse()` function with
24388
    and without callback function.,parse__istream__parser_callback_t}
24389
24390
    @liveexample{The example below demonstrates the `parse()` function reading
24391
    from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
24392
24393
    @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
24394
    ignore comments.
24395
    */
24396
    template<typename InputType>
24397
    JSON_HEDLEY_WARN_UNUSED_RESULT
24398
    static basic_json parse(InputType&& i,
24399
                            const parser_callback_t cb = nullptr,
24400
                            const bool allow_exceptions = true,
24401
                            const bool ignore_comments = false)
24402
    {
24403
        basic_json result;
24404
        parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24405
        return result;
24406
    }
24407
24408
    /*!
24409
    @brief deserialize from a pair of character iterators
24410
24411
    The value_type of the iterator must be a integral type with size of 1, 2 or
24412
    4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
24413
24414
    @param[in] first iterator to start of character range
24415
    @param[in] last  iterator to end of character range
24416
    @param[in] cb  a parser callback function of type @ref parser_callback_t
24417
    which is used to control the deserialization by filtering unwanted values
24418
    (optional)
24419
    @param[in] allow_exceptions  whether to throw exceptions in case of a
24420
    parse error (optional, true by default)
24421
    @param[in] ignore_comments  whether comments should be ignored and treated
24422
    like whitespace (true) or yield a parse error (true); (optional, false by
24423
    default)
24424
24425
    @return deserialized JSON value; in case of a parse error and
24426
            @a allow_exceptions set to `false`, the return value will be
24427
            value_t::discarded.
24428
24429
    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24430
    of input; expected string literal""`
24431
    @throw parse_error.102 if to_unicode fails or surrogate error
24432
    @throw parse_error.103 if to_unicode fails
24433
    */
24434
    template<typename IteratorType>
24435
    JSON_HEDLEY_WARN_UNUSED_RESULT
24436
    static basic_json parse(IteratorType first,
24437
                            IteratorType last,
24438
                            const parser_callback_t cb = nullptr,
24439
                            const bool allow_exceptions = true,
24440
                            const bool ignore_comments = false)
24441
1.82k
    {
24442
1.82k
        basic_json result;
24443
1.82k
        parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24444
1.82k
        return result;
24445
1.82k
    }
24446
24447
    JSON_HEDLEY_WARN_UNUSED_RESULT
24448
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24449
    static basic_json parse(detail::span_input_adapter&& i,
24450
                            const parser_callback_t cb = nullptr,
24451
                            const bool allow_exceptions = true,
24452
                            const bool ignore_comments = false)
24453
    {
24454
        basic_json result;
24455
        parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24456
        return result;
24457
    }
24458
24459
    /*!
24460
    @brief check if the input is valid JSON
24461
24462
    Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
24463
    function, this function neither throws an exception in case of invalid JSON
24464
    input (i.e., a parse error) nor creates diagnostic information.
24465
24466
    @tparam InputType A compatible input, for instance
24467
    - an std::istream object
24468
    - a FILE pointer
24469
    - a C-style array of characters
24470
    - a pointer to a null-terminated string of single byte characters
24471
    - an object obj for which begin(obj) and end(obj) produces a valid pair of
24472
      iterators.
24473
24474
    @param[in] i input to read from
24475
    @param[in] ignore_comments  whether comments should be ignored and treated
24476
    like whitespace (true) or yield a parse error (true); (optional, false by
24477
    default)
24478
24479
    @return Whether the input read from @a i is valid JSON.
24480
24481
    @complexity Linear in the length of the input. The parser is a predictive
24482
    LL(1) parser.
24483
24484
    @note A UTF-8 byte order mark is silently ignored.
24485
24486
    @liveexample{The example below demonstrates the `accept()` function reading
24487
    from a string.,accept__string}
24488
    */
24489
    template<typename InputType>
24490
    static bool accept(InputType&& i,
24491
                       const bool ignore_comments = false)
24492
    {
24493
        return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24494
    }
24495
24496
    template<typename IteratorType>
24497
    static bool accept(IteratorType first, IteratorType last,
24498
                       const bool ignore_comments = false)
24499
    {
24500
        return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24501
    }
24502
24503
    JSON_HEDLEY_WARN_UNUSED_RESULT
24504
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24505
    static bool accept(detail::span_input_adapter&& i,
24506
                       const bool ignore_comments = false)
24507
    {
24508
        return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24509
    }
24510
24511
    /*!
24512
    @brief generate SAX events
24513
24514
    The SAX event lister must follow the interface of @ref json_sax.
24515
24516
    This function reads from a compatible input. Examples are:
24517
    - an std::istream object
24518
    - a FILE pointer
24519
    - a C-style array of characters
24520
    - a pointer to a null-terminated string of single byte characters
24521
    - an object obj for which begin(obj) and end(obj) produces a valid pair of
24522
      iterators.
24523
24524
    @param[in] i  input to read from
24525
    @param[in,out] sax  SAX event listener
24526
    @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
24527
    @param[in] strict  whether the input has to be consumed completely
24528
    @param[in] ignore_comments  whether comments should be ignored and treated
24529
    like whitespace (true) or yield a parse error (true); (optional, false by
24530
    default); only applies to the JSON file format.
24531
24532
    @return return value of the last processed SAX event
24533
24534
    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24535
    of input; expected string literal""`
24536
    @throw parse_error.102 if to_unicode fails or surrogate error
24537
    @throw parse_error.103 if to_unicode fails
24538
24539
    @complexity Linear in the length of the input. The parser is a predictive
24540
    LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
24541
    a super-linear complexity.
24542
24543
    @note A UTF-8 byte order mark is silently ignored.
24544
24545
    @liveexample{The example below demonstrates the `sax_parse()` function
24546
    reading from string and processing the events with a user-defined SAX
24547
    event consumer.,sax_parse}
24548
24549
    @since version 3.2.0
24550
    */
24551
    template <typename InputType, typename SAX>
24552
    JSON_HEDLEY_NON_NULL(2)
24553
    static bool sax_parse(InputType&& i, SAX* sax,
24554
                          input_format_t format = input_format_t::json,
24555
                          const bool strict = true,
24556
                          const bool ignore_comments = false)
24557
    {
24558
        auto ia = detail::input_adapter(std::forward<InputType>(i));
24559
        return format == input_format_t::json
24560
               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24561
               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24562
    }
24563
24564
    template<class IteratorType, class SAX>
24565
    JSON_HEDLEY_NON_NULL(3)
24566
    static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24567
                          input_format_t format = input_format_t::json,
24568
                          const bool strict = true,
24569
                          const bool ignore_comments = false)
24570
    {
24571
        auto ia = detail::input_adapter(std::move(first), std::move(last));
24572
        return format == input_format_t::json
24573
               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24574
               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24575
    }
24576
24577
    template <typename SAX>
24578
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24579
    JSON_HEDLEY_NON_NULL(2)
24580
    static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24581
                          input_format_t format = input_format_t::json,
24582
                          const bool strict = true,
24583
                          const bool ignore_comments = false)
24584
    {
24585
        auto ia = i.get();
24586
        return format == input_format_t::json
24587
               // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24588
               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24589
               // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24590
               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24591
    }
24592
#ifndef JSON_NO_IO
24593
    /*!
24594
    @brief deserialize from stream
24595
    @deprecated This stream operator is deprecated and will be removed in
24596
                version 4.0.0 of the library. Please use
24597
                @ref operator>>(std::istream&, basic_json&)
24598
                instead; that is, replace calls like `j << i;` with `i >> j;`.
24599
    @since version 1.0.0; deprecated since version 3.0.0
24600
    */
24601
    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24602
    friend std::istream& operator<<(basic_json& j, std::istream& i)
24603
    {
24604
        return operator>>(i, j);
24605
    }
24606
24607
    /*!
24608
    @brief deserialize from stream
24609
24610
    Deserializes an input stream to a JSON value.
24611
24612
    @param[in,out] i  input stream to read a serialized JSON value from
24613
    @param[in,out] j  JSON value to write the deserialized input to
24614
24615
    @throw parse_error.101 in case of an unexpected token
24616
    @throw parse_error.102 if to_unicode fails or surrogate error
24617
    @throw parse_error.103 if to_unicode fails
24618
24619
    @complexity Linear in the length of the input. The parser is a predictive
24620
    LL(1) parser.
24621
24622
    @note A UTF-8 byte order mark is silently ignored.
24623
24624
    @liveexample{The example below shows how a JSON value is constructed by
24625
    reading a serialization from a stream.,operator_deserialize}
24626
24627
    @sa parse(std::istream&, const parser_callback_t) for a variant with a
24628
    parser callback function to filter values while parsing
24629
24630
    @since version 1.0.0
24631
    */
24632
    friend std::istream& operator>>(std::istream& i, basic_json& j)
24633
    {
24634
        parser(detail::input_adapter(i)).parse(false, j);
24635
        return i;
24636
    }
24637
#endif  // JSON_NO_IO
24638
    /// @}
24639
24640
    ///////////////////////////
24641
    // convenience functions //
24642
    ///////////////////////////
24643
24644
    /*!
24645
    @brief return the type as string
24646
24647
    Returns the type name as string to be used in error messages - usually to
24648
    indicate that a function was called on a wrong JSON type.
24649
24650
    @return a string representation of a the @a m_type member:
24651
            Value type  | return value
24652
            ----------- | -------------
24653
            null        | `"null"`
24654
            boolean     | `"boolean"`
24655
            string      | `"string"`
24656
            number      | `"number"` (for all number types)
24657
            object      | `"object"`
24658
            array       | `"array"`
24659
            binary      | `"binary"`
24660
            discarded   | `"discarded"`
24661
24662
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
24663
24664
    @complexity Constant.
24665
24666
    @liveexample{The following code exemplifies `type_name()` for all JSON
24667
    types.,type_name}
24668
24669
    @sa see @ref type() -- return the type of the JSON value
24670
    @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
24671
24672
    @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
24673
    since 3.0.0
24674
    */
24675
    JSON_HEDLEY_RETURNS_NON_NULL
24676
    const char* type_name() const noexcept
24677
0
    {
24678
0
        {
24679
0
            switch (m_type)
24680
0
            {
24681
0
                case value_t::null:
24682
0
                    return "null";
24683
0
                case value_t::object:
24684
0
                    return "object";
24685
0
                case value_t::array:
24686
0
                    return "array";
24687
0
                case value_t::string:
24688
0
                    return "string";
24689
0
                case value_t::boolean:
24690
0
                    return "boolean";
24691
0
                case value_t::binary:
24692
0
                    return "binary";
24693
0
                case value_t::discarded:
24694
0
                    return "discarded";
24695
0
                case value_t::number_integer:
24696
0
                case value_t::number_unsigned:
24697
0
                case value_t::number_float:
24698
0
                default:
24699
0
                    return "number";
24700
0
            }
24701
0
        }
24702
0
    }
24703
24704
24705
  JSON_PRIVATE_UNLESS_TESTED:
24706
    //////////////////////
24707
    // member variables //
24708
    //////////////////////
24709
24710
    /// the type of the current element
24711
    value_t m_type = value_t::null;
24712
24713
    /// the value of the current element
24714
    json_value m_value = {};
24715
24716
#if JSON_DIAGNOSTICS
24717
    /// a pointer to a parent value (for debugging purposes)
24718
    basic_json* m_parent = nullptr;
24719
#endif
24720
24721
    //////////////////////////////////////////
24722
    // binary serialization/deserialization //
24723
    //////////////////////////////////////////
24724
24725
    /// @name binary serialization/deserialization support
24726
    /// @{
24727
24728
  public:
24729
    /*!
24730
    @brief create a CBOR serialization of a given JSON value
24731
24732
    Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
24733
    Binary Object Representation) serialization format. CBOR is a binary
24734
    serialization format which aims to be more compact than JSON itself, yet
24735
    more efficient to parse.
24736
24737
    The library uses the following mapping from JSON values types to
24738
    CBOR types according to the CBOR specification (RFC 7049):
24739
24740
    JSON value type | value/range                                | CBOR type                          | first byte
24741
    --------------- | ------------------------------------------ | ---------------------------------- | ---------------
24742
    null            | `null`                                     | Null                               | 0xF6
24743
    boolean         | `true`                                     | True                               | 0xF5
24744
    boolean         | `false`                                    | False                              | 0xF4
24745
    number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
24746
    number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
24747
    number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
24748
    number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
24749
    number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
24750
    number_integer  | 0..23                                      | Integer                            | 0x00..0x17
24751
    number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
24752
    number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
24753
    number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
24754
    number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
24755
    number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
24756
    number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
24757
    number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
24758
    number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
24759
    number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
24760
    number_float    | *any value representable by a float*       | Single-Precision Float             | 0xFA
24761
    number_float    | *any value NOT representable by a float*   | Double-Precision Float             | 0xFB
24762
    string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
24763
    string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
24764
    string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
24765
    string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
24766
    string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
24767
    array           | *size*: 0..23                              | array                              | 0x80..0x97
24768
    array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
24769
    array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
24770
    array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
24771
    array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
24772
    object          | *size*: 0..23                              | map                                | 0xA0..0xB7
24773
    object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
24774
    object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
24775
    object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
24776
    object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
24777
    binary          | *size*: 0..23                              | byte string                        | 0x40..0x57
24778
    binary          | *size*: 23..255                            | byte string (1 byte follow)        | 0x58
24779
    binary          | *size*: 256..65535                         | byte string (2 bytes follow)       | 0x59
24780
    binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)       | 0x5A
24781
    binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)       | 0x5B
24782
24783
    Binary values with subtype are mapped to tagged values (0xD8..0xDB)
24784
    depending on the subtype, followed by a byte string, see "binary" cells
24785
    in the table above.
24786
24787
    @note The mapping is **complete** in the sense that any JSON value type
24788
          can be converted to a CBOR value.
24789
24790
    @note If NaN or Infinity are stored inside a JSON number, they are
24791
          serialized properly. This behavior differs from the @ref dump()
24792
          function which serializes NaN or Infinity to `null`.
24793
24794
    @note The following CBOR types are not used in the conversion:
24795
          - UTF-8 strings terminated by "break" (0x7F)
24796
          - arrays terminated by "break" (0x9F)
24797
          - maps terminated by "break" (0xBF)
24798
          - byte strings terminated by "break" (0x5F)
24799
          - date/time (0xC0..0xC1)
24800
          - bignum (0xC2..0xC3)
24801
          - decimal fraction (0xC4)
24802
          - bigfloat (0xC5)
24803
          - expected conversions (0xD5..0xD7)
24804
          - simple values (0xE0..0xF3, 0xF8)
24805
          - undefined (0xF7)
24806
          - half-precision floats (0xF9)
24807
          - break (0xFF)
24808
24809
    @param[in] j  JSON value to serialize
24810
    @return CBOR serialization as byte vector
24811
24812
    @complexity Linear in the size of the JSON value @a j.
24813
24814
    @liveexample{The example shows the serialization of a JSON value to a byte
24815
    vector in CBOR format.,to_cbor}
24816
24817
    @sa http://cbor.io
24818
    @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
24819
        analogous deserialization
24820
    @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24821
    @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24822
             related UBJSON format
24823
24824
    @since version 2.0.9; compact representation of floating-point numbers
24825
           since version 3.8.0
24826
    */
24827
    static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24828
    {
24829
        std::vector<std::uint8_t> result;
24830
        to_cbor(j, result);
24831
        return result;
24832
    }
24833
24834
    static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24835
    {
24836
        binary_writer<std::uint8_t>(o).write_cbor(j);
24837
    }
24838
24839
    static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24840
    {
24841
        binary_writer<char>(o).write_cbor(j);
24842
    }
24843
24844
    /*!
24845
    @brief create a MessagePack serialization of a given JSON value
24846
24847
    Serializes a given JSON value @a j to a byte vector using the MessagePack
24848
    serialization format. MessagePack is a binary serialization format which
24849
    aims to be more compact than JSON itself, yet more efficient to parse.
24850
24851
    The library uses the following mapping from JSON values types to
24852
    MessagePack types according to the MessagePack specification:
24853
24854
    JSON value type | value/range                       | MessagePack type | first byte
24855
    --------------- | --------------------------------- | ---------------- | ----------
24856
    null            | `null`                            | nil              | 0xC0
24857
    boolean         | `true`                            | true             | 0xC3
24858
    boolean         | `false`                           | false            | 0xC2
24859
    number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
24860
    number_integer  | -2147483648..-32769               | int32            | 0xD2
24861
    number_integer  | -32768..-129                      | int16            | 0xD1
24862
    number_integer  | -128..-33                         | int8             | 0xD0
24863
    number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
24864
    number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
24865
    number_integer  | 128..255                          | uint 8           | 0xCC
24866
    number_integer  | 256..65535                        | uint 16          | 0xCD
24867
    number_integer  | 65536..4294967295                 | uint 32          | 0xCE
24868
    number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
24869
    number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
24870
    number_unsigned | 128..255                          | uint 8           | 0xCC
24871
    number_unsigned | 256..65535                        | uint 16          | 0xCD
24872
    number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
24873
    number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
24874
    number_float    | *any value representable by a float*     | float 32 | 0xCA
24875
    number_float    | *any value NOT representable by a float* | float 64 | 0xCB
24876
    string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
24877
    string          | *length*: 32..255                 | str 8            | 0xD9
24878
    string          | *length*: 256..65535              | str 16           | 0xDA
24879
    string          | *length*: 65536..4294967295       | str 32           | 0xDB
24880
    array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
24881
    array           | *size*: 16..65535                 | array 16         | 0xDC
24882
    array           | *size*: 65536..4294967295         | array 32         | 0xDD
24883
    object          | *size*: 0..15                     | fix map          | 0x80..0x8F
24884
    object          | *size*: 16..65535                 | map 16           | 0xDE
24885
    object          | *size*: 65536..4294967295         | map 32           | 0xDF
24886
    binary          | *size*: 0..255                    | bin 8            | 0xC4
24887
    binary          | *size*: 256..65535                | bin 16           | 0xC5
24888
    binary          | *size*: 65536..4294967295         | bin 32           | 0xC6
24889
24890
    @note The mapping is **complete** in the sense that any JSON value type
24891
          can be converted to a MessagePack value.
24892
24893
    @note The following values can **not** be converted to a MessagePack value:
24894
          - strings with more than 4294967295 bytes
24895
          - byte strings with more than 4294967295 bytes
24896
          - arrays with more than 4294967295 elements
24897
          - objects with more than 4294967295 elements
24898
24899
    @note Any MessagePack output created @ref to_msgpack can be successfully
24900
          parsed by @ref from_msgpack.
24901
24902
    @note If NaN or Infinity are stored inside a JSON number, they are
24903
          serialized properly. This behavior differs from the @ref dump()
24904
          function which serializes NaN or Infinity to `null`.
24905
24906
    @param[in] j  JSON value to serialize
24907
    @return MessagePack serialization as byte vector
24908
24909
    @complexity Linear in the size of the JSON value @a j.
24910
24911
    @liveexample{The example shows the serialization of a JSON value to a byte
24912
    vector in MessagePack format.,to_msgpack}
24913
24914
    @sa http://msgpack.org
24915
    @sa see @ref from_msgpack for the analogous deserialization
24916
    @sa see @ref to_cbor(const basic_json& for the related CBOR format
24917
    @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24918
             related UBJSON format
24919
24920
    @since version 2.0.9
24921
    */
24922
    static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24923
    {
24924
        std::vector<std::uint8_t> result;
24925
        to_msgpack(j, result);
24926
        return result;
24927
    }
24928
24929
    static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24930
    {
24931
        binary_writer<std::uint8_t>(o).write_msgpack(j);
24932
    }
24933
24934
    static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24935
    {
24936
        binary_writer<char>(o).write_msgpack(j);
24937
    }
24938
24939
    /*!
24940
    @brief create a UBJSON serialization of a given JSON value
24941
24942
    Serializes a given JSON value @a j to a byte vector using the UBJSON
24943
    (Universal Binary JSON) serialization format. UBJSON aims to be more compact
24944
    than JSON itself, yet more efficient to parse.
24945
24946
    The library uses the following mapping from JSON values types to
24947
    UBJSON types according to the UBJSON specification:
24948
24949
    JSON value type | value/range                       | UBJSON type | marker
24950
    --------------- | --------------------------------- | ----------- | ------
24951
    null            | `null`                            | null        | `Z`
24952
    boolean         | `true`                            | true        | `T`
24953
    boolean         | `false`                           | false       | `F`
24954
    number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
24955
    number_integer  | -2147483648..-32769               | int32       | `l`
24956
    number_integer  | -32768..-129                      | int16       | `I`
24957
    number_integer  | -128..127                         | int8        | `i`
24958
    number_integer  | 128..255                          | uint8       | `U`
24959
    number_integer  | 256..32767                        | int16       | `I`
24960
    number_integer  | 32768..2147483647                 | int32       | `l`
24961
    number_integer  | 2147483648..9223372036854775807   | int64       | `L`
24962
    number_unsigned | 0..127                            | int8        | `i`
24963
    number_unsigned | 128..255                          | uint8       | `U`
24964
    number_unsigned | 256..32767                        | int16       | `I`
24965
    number_unsigned | 32768..2147483647                 | int32       | `l`
24966
    number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
24967
    number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`
24968
    number_float    | *any value*                       | float64     | `D`
24969
    string          | *with shortest length indicator*  | string      | `S`
24970
    array           | *see notes on optimized format*   | array       | `[`
24971
    object          | *see notes on optimized format*   | map         | `{`
24972
24973
    @note The mapping is **complete** in the sense that any JSON value type
24974
          can be converted to a UBJSON value.
24975
24976
    @note The following values can **not** be converted to a UBJSON value:
24977
          - strings with more than 9223372036854775807 bytes (theoretical)
24978
24979
    @note The following markers are not used in the conversion:
24980
          - `Z`: no-op values are not created.
24981
          - `C`: single-byte strings are serialized with `S` markers.
24982
24983
    @note Any UBJSON output created @ref to_ubjson can be successfully parsed
24984
          by @ref from_ubjson.
24985
24986
    @note If NaN or Infinity are stored inside a JSON number, they are
24987
          serialized properly. This behavior differs from the @ref dump()
24988
          function which serializes NaN or Infinity to `null`.
24989
24990
    @note The optimized formats for containers are supported: Parameter
24991
          @a use_size adds size information to the beginning of a container and
24992
          removes the closing marker. Parameter @a use_type further checks
24993
          whether all elements of a container have the same type and adds the
24994
          type marker to the beginning of the container. The @a use_type
24995
          parameter must only be used together with @a use_size = true. Note
24996
          that @a use_size = true alone may result in larger representations -
24997
          the benefit of this parameter is that the receiving side is
24998
          immediately informed on the number of elements of the container.
24999
25000
    @note If the JSON data contains the binary type, the value stored is a list
25001
          of integers, as suggested by the UBJSON documentation.  In particular,
25002
          this means that serialization and the deserialization of a JSON
25003
          containing binary values into UBJSON and back will result in a
25004
          different JSON object.
25005
25006
    @param[in] j  JSON value to serialize
25007
    @param[in] use_size  whether to add size annotations to container types
25008
    @param[in] use_type  whether to add type annotations to container types
25009
                         (must be combined with @a use_size = true)
25010
    @return UBJSON serialization as byte vector
25011
25012
    @complexity Linear in the size of the JSON value @a j.
25013
25014
    @liveexample{The example shows the serialization of a JSON value to a byte
25015
    vector in UBJSON format.,to_ubjson}
25016
25017
    @sa http://ubjson.org
25018
    @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25019
        analogous deserialization
25020
    @sa see @ref to_cbor(const basic_json& for the related CBOR format
25021
    @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
25022
25023
    @since version 3.1.0
25024
    */
25025
    static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
25026
            const bool use_size = false,
25027
            const bool use_type = false)
25028
    {
25029
        std::vector<std::uint8_t> result;
25030
        to_ubjson(j, result, use_size, use_type);
25031
        return result;
25032
    }
25033
25034
    static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
25035
                          const bool use_size = false, const bool use_type = false)
25036
    {
25037
        binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
25038
    }
25039
25040
    static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
25041
                          const bool use_size = false, const bool use_type = false)
25042
    {
25043
        binary_writer<char>(o).write_ubjson(j, use_size, use_type);
25044
    }
25045
25046
25047
    /*!
25048
    @brief Serializes the given JSON object `j` to BSON and returns a vector
25049
           containing the corresponding BSON-representation.
25050
25051
    BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
25052
    stored as a single entity (a so-called document).
25053
25054
    The library uses the following mapping from JSON values types to BSON types:
25055
25056
    JSON value type | value/range                       | BSON type   | marker
25057
    --------------- | --------------------------------- | ----------- | ------
25058
    null            | `null`                            | null        | 0x0A
25059
    boolean         | `true`, `false`                   | boolean     | 0x08
25060
    number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
25061
    number_integer  | -2147483648..2147483647           | int32       | 0x10
25062
    number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
25063
    number_unsigned | 0..2147483647                     | int32       | 0x10
25064
    number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
25065
    number_unsigned | 9223372036854775808..18446744073709551615| --   | --
25066
    number_float    | *any value*                       | double      | 0x01
25067
    string          | *any value*                       | string      | 0x02
25068
    array           | *any value*                       | document    | 0x04
25069
    object          | *any value*                       | document    | 0x03
25070
    binary          | *any value*                       | binary      | 0x05
25071
25072
    @warning The mapping is **incomplete**, since only JSON-objects (and things
25073
    contained therein) can be serialized to BSON.
25074
    Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
25075
    and the keys may not contain U+0000, since they are serialized a
25076
    zero-terminated c-strings.
25077
25078
    @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
25079
    @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
25080
    @throw type_error.317    if `!j.is_object()`
25081
25082
    @pre The input `j` is required to be an object: `j.is_object() == true`.
25083
25084
    @note Any BSON output created via @ref to_bson can be successfully parsed
25085
          by @ref from_bson.
25086
25087
    @param[in] j  JSON value to serialize
25088
    @return BSON serialization as byte vector
25089
25090
    @complexity Linear in the size of the JSON value @a j.
25091
25092
    @liveexample{The example shows the serialization of a JSON value to a byte
25093
    vector in BSON format.,to_bson}
25094
25095
    @sa http://bsonspec.org/spec.html
25096
    @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the
25097
        analogous deserialization
25098
    @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
25099
             related UBJSON format
25100
    @sa see @ref to_cbor(const basic_json&) for the related CBOR format
25101
    @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
25102
    */
25103
    static std::vector<std::uint8_t> to_bson(const basic_json& j)
25104
    {
25105
        std::vector<std::uint8_t> result;
25106
        to_bson(j, result);
25107
        return result;
25108
    }
25109
25110
    /*!
25111
    @brief Serializes the given JSON object `j` to BSON and forwards the
25112
           corresponding BSON-representation to the given output_adapter `o`.
25113
    @param j The JSON object to convert to BSON.
25114
    @param o The output adapter that receives the binary BSON representation.
25115
    @pre The input `j` shall be an object: `j.is_object() == true`
25116
    @sa see @ref to_bson(const basic_json&)
25117
    */
25118
    static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
25119
    {
25120
        binary_writer<std::uint8_t>(o).write_bson(j);
25121
    }
25122
25123
    /*!
25124
    @copydoc to_bson(const basic_json&, detail::output_adapter<std::uint8_t>)
25125
    */
25126
    static void to_bson(const basic_json& j, detail::output_adapter<char> o)
25127
    {
25128
        binary_writer<char>(o).write_bson(j);
25129
    }
25130
25131
25132
    /*!
25133
    @brief create a JSON value from an input in CBOR format
25134
25135
    Deserializes a given input @a i to a JSON value using the CBOR (Concise
25136
    Binary Object Representation) serialization format.
25137
25138
    The library maps CBOR types to JSON value types as follows:
25139
25140
    CBOR type              | JSON value type | first byte
25141
    ---------------------- | --------------- | ----------
25142
    Integer                | number_unsigned | 0x00..0x17
25143
    Unsigned integer       | number_unsigned | 0x18
25144
    Unsigned integer       | number_unsigned | 0x19
25145
    Unsigned integer       | number_unsigned | 0x1A
25146
    Unsigned integer       | number_unsigned | 0x1B
25147
    Negative integer       | number_integer  | 0x20..0x37
25148
    Negative integer       | number_integer  | 0x38
25149
    Negative integer       | number_integer  | 0x39
25150
    Negative integer       | number_integer  | 0x3A
25151
    Negative integer       | number_integer  | 0x3B
25152
    Byte string            | binary          | 0x40..0x57
25153
    Byte string            | binary          | 0x58
25154
    Byte string            | binary          | 0x59
25155
    Byte string            | binary          | 0x5A
25156
    Byte string            | binary          | 0x5B
25157
    UTF-8 string           | string          | 0x60..0x77
25158
    UTF-8 string           | string          | 0x78
25159
    UTF-8 string           | string          | 0x79
25160
    UTF-8 string           | string          | 0x7A
25161
    UTF-8 string           | string          | 0x7B
25162
    UTF-8 string           | string          | 0x7F
25163
    array                  | array           | 0x80..0x97
25164
    array                  | array           | 0x98
25165
    array                  | array           | 0x99
25166
    array                  | array           | 0x9A
25167
    array                  | array           | 0x9B
25168
    array                  | array           | 0x9F
25169
    map                    | object          | 0xA0..0xB7
25170
    map                    | object          | 0xB8
25171
    map                    | object          | 0xB9
25172
    map                    | object          | 0xBA
25173
    map                    | object          | 0xBB
25174
    map                    | object          | 0xBF
25175
    False                  | `false`         | 0xF4
25176
    True                   | `true`          | 0xF5
25177
    Null                   | `null`          | 0xF6
25178
    Half-Precision Float   | number_float    | 0xF9
25179
    Single-Precision Float | number_float    | 0xFA
25180
    Double-Precision Float | number_float    | 0xFB
25181
25182
    @warning The mapping is **incomplete** in the sense that not all CBOR
25183
             types can be converted to a JSON value. The following CBOR types
25184
             are not supported and will yield parse errors (parse_error.112):
25185
             - date/time (0xC0..0xC1)
25186
             - bignum (0xC2..0xC3)
25187
             - decimal fraction (0xC4)
25188
             - bigfloat (0xC5)
25189
             - expected conversions (0xD5..0xD7)
25190
             - simple values (0xE0..0xF3, 0xF8)
25191
             - undefined (0xF7)
25192
25193
    @warning CBOR allows map keys of any type, whereas JSON only allows
25194
             strings as keys in object values. Therefore, CBOR maps with keys
25195
             other than UTF-8 strings are rejected (parse_error.113).
25196
25197
    @note Any CBOR output created @ref to_cbor can be successfully parsed by
25198
          @ref from_cbor.
25199
25200
    @param[in] i  an input in CBOR format convertible to an input adapter
25201
    @param[in] strict  whether to expect the input to be consumed until EOF
25202
                       (true by default)
25203
    @param[in] allow_exceptions  whether to throw exceptions in case of a
25204
    parse error (optional, true by default)
25205
    @param[in] tag_handler how to treat CBOR tags (optional, error by default)
25206
25207
    @return deserialized JSON value; in case of a parse error and
25208
            @a allow_exceptions set to `false`, the return value will be
25209
            value_t::discarded.
25210
25211
    @throw parse_error.110 if the given input ends prematurely or the end of
25212
    file was not reached when @a strict was set to true
25213
    @throw parse_error.112 if unsupported features from CBOR were
25214
    used in the given input @a v or if the input is not valid CBOR
25215
    @throw parse_error.113 if a string was expected as map key, but not found
25216
25217
    @complexity Linear in the size of the input @a i.
25218
25219
    @liveexample{The example shows the deserialization of a byte vector in CBOR
25220
    format to a JSON value.,from_cbor}
25221
25222
    @sa http://cbor.io
25223
    @sa see @ref to_cbor(const basic_json&) for the analogous serialization
25224
    @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the
25225
        related MessagePack format
25226
    @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25227
        related UBJSON format
25228
25229
    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25230
           consume input adapters, removed start_index parameter, and added
25231
           @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25232
           since 3.2.0; added @a tag_handler parameter since 3.9.0.
25233
    */
25234
    template<typename InputType>
25235
    JSON_HEDLEY_WARN_UNUSED_RESULT
25236
    static basic_json from_cbor(InputType&& i,
25237
                                const bool strict = true,
25238
                                const bool allow_exceptions = true,
25239
                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25240
    {
25241
        basic_json result;
25242
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25243
        auto ia = detail::input_adapter(std::forward<InputType>(i));
25244
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25245
        return res ? result : basic_json(value_t::discarded);
25246
    }
25247
25248
    /*!
25249
    @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t)
25250
    */
25251
    template<typename IteratorType>
25252
    JSON_HEDLEY_WARN_UNUSED_RESULT
25253
    static basic_json from_cbor(IteratorType first, IteratorType last,
25254
                                const bool strict = true,
25255
                                const bool allow_exceptions = true,
25256
                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25257
    {
25258
        basic_json result;
25259
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25260
        auto ia = detail::input_adapter(std::move(first), std::move(last));
25261
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25262
        return res ? result : basic_json(value_t::discarded);
25263
    }
25264
25265
    template<typename T>
25266
    JSON_HEDLEY_WARN_UNUSED_RESULT
25267
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25268
    static basic_json from_cbor(const T* ptr, std::size_t len,
25269
                                const bool strict = true,
25270
                                const bool allow_exceptions = true,
25271
                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25272
    {
25273
        return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25274
    }
25275
25276
25277
    JSON_HEDLEY_WARN_UNUSED_RESULT
25278
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25279
    static basic_json from_cbor(detail::span_input_adapter&& i,
25280
                                const bool strict = true,
25281
                                const bool allow_exceptions = true,
25282
                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25283
    {
25284
        basic_json result;
25285
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25286
        auto ia = i.get();
25287
        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25288
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25289
        return res ? result : basic_json(value_t::discarded);
25290
    }
25291
25292
    /*!
25293
    @brief create a JSON value from an input in MessagePack format
25294
25295
    Deserializes a given input @a i to a JSON value using the MessagePack
25296
    serialization format.
25297
25298
    The library maps MessagePack types to JSON value types as follows:
25299
25300
    MessagePack type | JSON value type | first byte
25301
    ---------------- | --------------- | ----------
25302
    positive fixint  | number_unsigned | 0x00..0x7F
25303
    fixmap           | object          | 0x80..0x8F
25304
    fixarray         | array           | 0x90..0x9F
25305
    fixstr           | string          | 0xA0..0xBF
25306
    nil              | `null`          | 0xC0
25307
    false            | `false`         | 0xC2
25308
    true             | `true`          | 0xC3
25309
    float 32         | number_float    | 0xCA
25310
    float 64         | number_float    | 0xCB
25311
    uint 8           | number_unsigned | 0xCC
25312
    uint 16          | number_unsigned | 0xCD
25313
    uint 32          | number_unsigned | 0xCE
25314
    uint 64          | number_unsigned | 0xCF
25315
    int 8            | number_integer  | 0xD0
25316
    int 16           | number_integer  | 0xD1
25317
    int 32           | number_integer  | 0xD2
25318
    int 64           | number_integer  | 0xD3
25319
    str 8            | string          | 0xD9
25320
    str 16           | string          | 0xDA
25321
    str 32           | string          | 0xDB
25322
    array 16         | array           | 0xDC
25323
    array 32         | array           | 0xDD
25324
    map 16           | object          | 0xDE
25325
    map 32           | object          | 0xDF
25326
    bin 8            | binary          | 0xC4
25327
    bin 16           | binary          | 0xC5
25328
    bin 32           | binary          | 0xC6
25329
    ext 8            | binary          | 0xC7
25330
    ext 16           | binary          | 0xC8
25331
    ext 32           | binary          | 0xC9
25332
    fixext 1         | binary          | 0xD4
25333
    fixext 2         | binary          | 0xD5
25334
    fixext 4         | binary          | 0xD6
25335
    fixext 8         | binary          | 0xD7
25336
    fixext 16        | binary          | 0xD8
25337
    negative fixint  | number_integer  | 0xE0-0xFF
25338
25339
    @note Any MessagePack output created @ref to_msgpack can be successfully
25340
          parsed by @ref from_msgpack.
25341
25342
    @param[in] i  an input in MessagePack format convertible to an input
25343
                  adapter
25344
    @param[in] strict  whether to expect the input to be consumed until EOF
25345
                       (true by default)
25346
    @param[in] allow_exceptions  whether to throw exceptions in case of a
25347
    parse error (optional, true by default)
25348
25349
    @return deserialized JSON value; in case of a parse error and
25350
            @a allow_exceptions set to `false`, the return value will be
25351
            value_t::discarded.
25352
25353
    @throw parse_error.110 if the given input ends prematurely or the end of
25354
    file was not reached when @a strict was set to true
25355
    @throw parse_error.112 if unsupported features from MessagePack were
25356
    used in the given input @a i or if the input is not valid MessagePack
25357
    @throw parse_error.113 if a string was expected as map key, but not found
25358
25359
    @complexity Linear in the size of the input @a i.
25360
25361
    @liveexample{The example shows the deserialization of a byte vector in
25362
    MessagePack format to a JSON value.,from_msgpack}
25363
25364
    @sa http://msgpack.org
25365
    @sa see @ref to_msgpack(const basic_json&) for the analogous serialization
25366
    @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25367
        related CBOR format
25368
    @sa see @ref from_ubjson(InputType&&, const bool, const bool) for
25369
        the related UBJSON format
25370
    @sa see @ref from_bson(InputType&&, const bool, const bool) for
25371
        the related BSON format
25372
25373
    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25374
           consume input adapters, removed start_index parameter, and added
25375
           @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25376
           since 3.2.0
25377
    */
25378
    template<typename InputType>
25379
    JSON_HEDLEY_WARN_UNUSED_RESULT
25380
    static basic_json from_msgpack(InputType&& i,
25381
                                   const bool strict = true,
25382
                                   const bool allow_exceptions = true)
25383
    {
25384
        basic_json result;
25385
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25386
        auto ia = detail::input_adapter(std::forward<InputType>(i));
25387
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25388
        return res ? result : basic_json(value_t::discarded);
25389
    }
25390
25391
    /*!
25392
    @copydoc from_msgpack(InputType&&, const bool, const bool)
25393
    */
25394
    template<typename IteratorType>
25395
    JSON_HEDLEY_WARN_UNUSED_RESULT
25396
    static basic_json from_msgpack(IteratorType first, IteratorType last,
25397
                                   const bool strict = true,
25398
                                   const bool allow_exceptions = true)
25399
    {
25400
        basic_json result;
25401
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25402
        auto ia = detail::input_adapter(std::move(first), std::move(last));
25403
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25404
        return res ? result : basic_json(value_t::discarded);
25405
    }
25406
25407
25408
    template<typename T>
25409
    JSON_HEDLEY_WARN_UNUSED_RESULT
25410
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25411
    static basic_json from_msgpack(const T* ptr, std::size_t len,
25412
                                   const bool strict = true,
25413
                                   const bool allow_exceptions = true)
25414
    {
25415
        return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25416
    }
25417
25418
    JSON_HEDLEY_WARN_UNUSED_RESULT
25419
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25420
    static basic_json from_msgpack(detail::span_input_adapter&& i,
25421
                                   const bool strict = true,
25422
                                   const bool allow_exceptions = true)
25423
    {
25424
        basic_json result;
25425
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25426
        auto ia = i.get();
25427
        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25428
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25429
        return res ? result : basic_json(value_t::discarded);
25430
    }
25431
25432
25433
    /*!
25434
    @brief create a JSON value from an input in UBJSON format
25435
25436
    Deserializes a given input @a i to a JSON value using the UBJSON (Universal
25437
    Binary JSON) serialization format.
25438
25439
    The library maps UBJSON types to JSON value types as follows:
25440
25441
    UBJSON type | JSON value type                         | marker
25442
    ----------- | --------------------------------------- | ------
25443
    no-op       | *no value, next value is read*          | `N`
25444
    null        | `null`                                  | `Z`
25445
    false       | `false`                                 | `F`
25446
    true        | `true`                                  | `T`
25447
    float32     | number_float                            | `d`
25448
    float64     | number_float                            | `D`
25449
    uint8       | number_unsigned                         | `U`
25450
    int8        | number_integer                          | `i`
25451
    int16       | number_integer                          | `I`
25452
    int32       | number_integer                          | `l`
25453
    int64       | number_integer                          | `L`
25454
    high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
25455
    string      | string                                  | `S`
25456
    char        | string                                  | `C`
25457
    array       | array (optimized values are supported)  | `[`
25458
    object      | object (optimized values are supported) | `{`
25459
25460
    @note The mapping is **complete** in the sense that any UBJSON value can
25461
          be converted to a JSON value.
25462
25463
    @param[in] i  an input in UBJSON format convertible to an input adapter
25464
    @param[in] strict  whether to expect the input to be consumed until EOF
25465
                       (true by default)
25466
    @param[in] allow_exceptions  whether to throw exceptions in case of a
25467
    parse error (optional, true by default)
25468
25469
    @return deserialized JSON value; in case of a parse error and
25470
            @a allow_exceptions set to `false`, the return value will be
25471
            value_t::discarded.
25472
25473
    @throw parse_error.110 if the given input ends prematurely or the end of
25474
    file was not reached when @a strict was set to true
25475
    @throw parse_error.112 if a parse error occurs
25476
    @throw parse_error.113 if a string could not be parsed successfully
25477
25478
    @complexity Linear in the size of the input @a i.
25479
25480
    @liveexample{The example shows the deserialization of a byte vector in
25481
    UBJSON format to a JSON value.,from_ubjson}
25482
25483
    @sa http://ubjson.org
25484
    @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
25485
             analogous serialization
25486
    @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25487
        related CBOR format
25488
    @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25489
        the related MessagePack format
25490
    @sa see @ref from_bson(InputType&&, const bool, const bool) for
25491
        the related BSON format
25492
25493
    @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
25494
    */
25495
    template<typename InputType>
25496
    JSON_HEDLEY_WARN_UNUSED_RESULT
25497
    static basic_json from_ubjson(InputType&& i,
25498
                                  const bool strict = true,
25499
                                  const bool allow_exceptions = true)
25500
    {
25501
        basic_json result;
25502
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25503
        auto ia = detail::input_adapter(std::forward<InputType>(i));
25504
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25505
        return res ? result : basic_json(value_t::discarded);
25506
    }
25507
25508
    /*!
25509
    @copydoc from_ubjson(InputType&&, const bool, const bool)
25510
    */
25511
    template<typename IteratorType>
25512
    JSON_HEDLEY_WARN_UNUSED_RESULT
25513
    static basic_json from_ubjson(IteratorType first, IteratorType last,
25514
                                  const bool strict = true,
25515
                                  const bool allow_exceptions = true)
25516
    {
25517
        basic_json result;
25518
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25519
        auto ia = detail::input_adapter(std::move(first), std::move(last));
25520
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25521
        return res ? result : basic_json(value_t::discarded);
25522
    }
25523
25524
    template<typename T>
25525
    JSON_HEDLEY_WARN_UNUSED_RESULT
25526
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25527
    static basic_json from_ubjson(const T* ptr, std::size_t len,
25528
                                  const bool strict = true,
25529
                                  const bool allow_exceptions = true)
25530
    {
25531
        return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25532
    }
25533
25534
    JSON_HEDLEY_WARN_UNUSED_RESULT
25535
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25536
    static basic_json from_ubjson(detail::span_input_adapter&& i,
25537
                                  const bool strict = true,
25538
                                  const bool allow_exceptions = true)
25539
    {
25540
        basic_json result;
25541
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25542
        auto ia = i.get();
25543
        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25544
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25545
        return res ? result : basic_json(value_t::discarded);
25546
    }
25547
25548
25549
    /*!
25550
    @brief Create a JSON value from an input in BSON format
25551
25552
    Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
25553
    serialization format.
25554
25555
    The library maps BSON record types to JSON value types as follows:
25556
25557
    BSON type       | BSON marker byte | JSON value type
25558
    --------------- | ---------------- | ---------------------------
25559
    double          | 0x01             | number_float
25560
    string          | 0x02             | string
25561
    document        | 0x03             | object
25562
    array           | 0x04             | array
25563
    binary          | 0x05             | binary
25564
    undefined       | 0x06             | still unsupported
25565
    ObjectId        | 0x07             | still unsupported
25566
    boolean         | 0x08             | boolean
25567
    UTC Date-Time   | 0x09             | still unsupported
25568
    null            | 0x0A             | null
25569
    Regular Expr.   | 0x0B             | still unsupported
25570
    DB Pointer      | 0x0C             | still unsupported
25571
    JavaScript Code | 0x0D             | still unsupported
25572
    Symbol          | 0x0E             | still unsupported
25573
    JavaScript Code | 0x0F             | still unsupported
25574
    int32           | 0x10             | number_integer
25575
    Timestamp       | 0x11             | still unsupported
25576
    128-bit decimal float | 0x13       | still unsupported
25577
    Max Key         | 0x7F             | still unsupported
25578
    Min Key         | 0xFF             | still unsupported
25579
25580
    @warning The mapping is **incomplete**. The unsupported mappings
25581
             are indicated in the table above.
25582
25583
    @param[in] i  an input in BSON format convertible to an input adapter
25584
    @param[in] strict  whether to expect the input to be consumed until EOF
25585
                       (true by default)
25586
    @param[in] allow_exceptions  whether to throw exceptions in case of a
25587
    parse error (optional, true by default)
25588
25589
    @return deserialized JSON value; in case of a parse error and
25590
            @a allow_exceptions set to `false`, the return value will be
25591
            value_t::discarded.
25592
25593
    @throw parse_error.114 if an unsupported BSON record type is encountered
25594
25595
    @complexity Linear in the size of the input @a i.
25596
25597
    @liveexample{The example shows the deserialization of a byte vector in
25598
    BSON format to a JSON value.,from_bson}
25599
25600
    @sa http://bsonspec.org/spec.html
25601
    @sa see @ref to_bson(const basic_json&) for the analogous serialization
25602
    @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25603
        related CBOR format
25604
    @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25605
        the related MessagePack format
25606
    @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25607
        related UBJSON format
25608
    */
25609
    template<typename InputType>
25610
    JSON_HEDLEY_WARN_UNUSED_RESULT
25611
    static basic_json from_bson(InputType&& i,
25612
                                const bool strict = true,
25613
                                const bool allow_exceptions = true)
25614
    {
25615
        basic_json result;
25616
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25617
        auto ia = detail::input_adapter(std::forward<InputType>(i));
25618
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25619
        return res ? result : basic_json(value_t::discarded);
25620
    }
25621
25622
    /*!
25623
    @copydoc from_bson(InputType&&, const bool, const bool)
25624
    */
25625
    template<typename IteratorType>
25626
    JSON_HEDLEY_WARN_UNUSED_RESULT
25627
    static basic_json from_bson(IteratorType first, IteratorType last,
25628
                                const bool strict = true,
25629
                                const bool allow_exceptions = true)
25630
    {
25631
        basic_json result;
25632
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25633
        auto ia = detail::input_adapter(std::move(first), std::move(last));
25634
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25635
        return res ? result : basic_json(value_t::discarded);
25636
    }
25637
25638
    template<typename T>
25639
    JSON_HEDLEY_WARN_UNUSED_RESULT
25640
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25641
    static basic_json from_bson(const T* ptr, std::size_t len,
25642
                                const bool strict = true,
25643
                                const bool allow_exceptions = true)
25644
    {
25645
        return from_bson(ptr, ptr + len, strict, allow_exceptions);
25646
    }
25647
25648
    JSON_HEDLEY_WARN_UNUSED_RESULT
25649
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25650
    static basic_json from_bson(detail::span_input_adapter&& i,
25651
                                const bool strict = true,
25652
                                const bool allow_exceptions = true)
25653
    {
25654
        basic_json result;
25655
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25656
        auto ia = i.get();
25657
        // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25658
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25659
        return res ? result : basic_json(value_t::discarded);
25660
    }
25661
    /// @}
25662
25663
    //////////////////////////
25664
    // JSON Pointer support //
25665
    //////////////////////////
25666
25667
    /// @name JSON Pointer functions
25668
    /// @{
25669
25670
    /*!
25671
    @brief access specified element via JSON Pointer
25672
25673
    Uses a JSON pointer to retrieve a reference to the respective JSON value.
25674
    No bound checking is performed. Similar to @ref operator[](const typename
25675
    object_t::key_type&), `null` values are created in arrays and objects if
25676
    necessary.
25677
25678
    In particular:
25679
    - If the JSON pointer points to an object key that does not exist, it
25680
      is created an filled with a `null` value before a reference to it
25681
      is returned.
25682
    - If the JSON pointer points to an array index that does not exist, it
25683
      is created an filled with a `null` value before a reference to it
25684
      is returned. All indices between the current maximum and the given
25685
      index are also filled with `null`.
25686
    - The special value `-` is treated as a synonym for the index past the
25687
      end.
25688
25689
    @param[in] ptr  a JSON pointer
25690
25691
    @return reference to the element pointed to by @a ptr
25692
25693
    @complexity Constant.
25694
25695
    @throw parse_error.106   if an array index begins with '0'
25696
    @throw parse_error.109   if an array index was not a number
25697
    @throw out_of_range.404  if the JSON pointer can not be resolved
25698
25699
    @liveexample{The behavior is shown in the example.,operatorjson_pointer}
25700
25701
    @since version 2.0.0
25702
    */
25703
    reference operator[](const json_pointer& ptr)
25704
    {
25705
        return ptr.get_unchecked(this);
25706
    }
25707
25708
    /*!
25709
    @brief access specified element via JSON Pointer
25710
25711
    Uses a JSON pointer to retrieve a reference to the respective JSON value.
25712
    No bound checking is performed. The function does not change the JSON
25713
    value; no `null` values are created. In particular, the special value
25714
    `-` yields an exception.
25715
25716
    @param[in] ptr  JSON pointer to the desired element
25717
25718
    @return const reference to the element pointed to by @a ptr
25719
25720
    @complexity Constant.
25721
25722
    @throw parse_error.106   if an array index begins with '0'
25723
    @throw parse_error.109   if an array index was not a number
25724
    @throw out_of_range.402  if the array index '-' is used
25725
    @throw out_of_range.404  if the JSON pointer can not be resolved
25726
25727
    @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
25728
25729
    @since version 2.0.0
25730
    */
25731
    const_reference operator[](const json_pointer& ptr) const
25732
    {
25733
        return ptr.get_unchecked(this);
25734
    }
25735
25736
    /*!
25737
    @brief access specified element via JSON Pointer
25738
25739
    Returns a reference to the element at with specified JSON pointer @a ptr,
25740
    with bounds checking.
25741
25742
    @param[in] ptr  JSON pointer to the desired element
25743
25744
    @return reference to the element pointed to by @a ptr
25745
25746
    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25747
    begins with '0'. See example below.
25748
25749
    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25750
    is not a number. See example below.
25751
25752
    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25753
    is out of range. See example below.
25754
25755
    @throw out_of_range.402 if the array index '-' is used in the passed JSON
25756
    pointer @a ptr. As `at` provides checked access (and no elements are
25757
    implicitly inserted), the index '-' is always invalid. See example below.
25758
25759
    @throw out_of_range.403 if the JSON pointer describes a key of an object
25760
    which cannot be found. See example below.
25761
25762
    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25763
    See example below.
25764
25765
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25766
    changes in the JSON value.
25767
25768
    @complexity Constant.
25769
25770
    @since version 2.0.0
25771
25772
    @liveexample{The behavior is shown in the example.,at_json_pointer}
25773
    */
25774
    reference at(const json_pointer& ptr)
25775
    {
25776
        return ptr.get_checked(this);
25777
    }
25778
25779
    /*!
25780
    @brief access specified element via JSON Pointer
25781
25782
    Returns a const reference to the element at with specified JSON pointer @a
25783
    ptr, with bounds checking.
25784
25785
    @param[in] ptr  JSON pointer to the desired element
25786
25787
    @return reference to the element pointed to by @a ptr
25788
25789
    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25790
    begins with '0'. See example below.
25791
25792
    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25793
    is not a number. See example below.
25794
25795
    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25796
    is out of range. See example below.
25797
25798
    @throw out_of_range.402 if the array index '-' is used in the passed JSON
25799
    pointer @a ptr. As `at` provides checked access (and no elements are
25800
    implicitly inserted), the index '-' is always invalid. See example below.
25801
25802
    @throw out_of_range.403 if the JSON pointer describes a key of an object
25803
    which cannot be found. See example below.
25804
25805
    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25806
    See example below.
25807
25808
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25809
    changes in the JSON value.
25810
25811
    @complexity Constant.
25812
25813
    @since version 2.0.0
25814
25815
    @liveexample{The behavior is shown in the example.,at_json_pointer_const}
25816
    */
25817
    const_reference at(const json_pointer& ptr) const
25818
    {
25819
        return ptr.get_checked(this);
25820
    }
25821
25822
    /*!
25823
    @brief return flattened JSON value
25824
25825
    The function creates a JSON object whose keys are JSON pointers (see [RFC
25826
    6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
25827
    primitive. The original JSON value can be restored using the @ref
25828
    unflatten() function.
25829
25830
    @return an object that maps JSON pointers to primitive values
25831
25832
    @note Empty objects and arrays are flattened to `null` and will not be
25833
          reconstructed correctly by the @ref unflatten() function.
25834
25835
    @complexity Linear in the size the JSON value.
25836
25837
    @liveexample{The following code shows how a JSON object is flattened to an
25838
    object whose keys consist of JSON pointers.,flatten}
25839
25840
    @sa see @ref unflatten() for the reverse function
25841
25842
    @since version 2.0.0
25843
    */
25844
    basic_json flatten() const
25845
    {
25846
        basic_json result(value_t::object);
25847
        json_pointer::flatten("", *this, result);
25848
        return result;
25849
    }
25850
25851
    /*!
25852
    @brief unflatten a previously flattened JSON value
25853
25854
    The function restores the arbitrary nesting of a JSON value that has been
25855
    flattened before using the @ref flatten() function. The JSON value must
25856
    meet certain constraints:
25857
    1. The value must be an object.
25858
    2. The keys must be JSON pointers (see
25859
       [RFC 6901](https://tools.ietf.org/html/rfc6901))
25860
    3. The mapped values must be primitive JSON types.
25861
25862
    @return the original JSON from a flattened version
25863
25864
    @note Empty objects and arrays are flattened by @ref flatten() to `null`
25865
          values and can not unflattened to their original type. Apart from
25866
          this example, for a JSON value `j`, the following is always true:
25867
          `j == j.flatten().unflatten()`.
25868
25869
    @complexity Linear in the size the JSON value.
25870
25871
    @throw type_error.314  if value is not an object
25872
    @throw type_error.315  if object values are not primitive
25873
25874
    @liveexample{The following code shows how a flattened JSON object is
25875
    unflattened into the original nested JSON object.,unflatten}
25876
25877
    @sa see @ref flatten() for the reverse function
25878
25879
    @since version 2.0.0
25880
    */
25881
    basic_json unflatten() const
25882
    {
25883
        return json_pointer::unflatten(*this);
25884
    }
25885
25886
    /// @}
25887
25888
    //////////////////////////
25889
    // JSON Patch functions //
25890
    //////////////////////////
25891
25892
    /// @name JSON Patch functions
25893
    /// @{
25894
25895
    /*!
25896
    @brief applies a JSON patch
25897
25898
    [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
25899
    expressing a sequence of operations to apply to a JSON) document. With
25900
    this function, a JSON Patch is applied to the current JSON value by
25901
    executing all operations from the patch.
25902
25903
    @param[in] json_patch  JSON patch document
25904
    @return patched document
25905
25906
    @note The application of a patch is atomic: Either all operations succeed
25907
          and the patched document is returned or an exception is thrown. In
25908
          any case, the original value is not changed: the patch is applied
25909
          to a copy of the value.
25910
25911
    @throw parse_error.104 if the JSON patch does not consist of an array of
25912
    objects
25913
25914
    @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
25915
    attributes are missing); example: `"operation add must have member path"`
25916
25917
    @throw out_of_range.401 if an array index is out of range.
25918
25919
    @throw out_of_range.403 if a JSON pointer inside the patch could not be
25920
    resolved successfully in the current JSON value; example: `"key baz not
25921
    found"`
25922
25923
    @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
25924
    "move")
25925
25926
    @throw other_error.501 if "test" operation was unsuccessful
25927
25928
    @complexity Linear in the size of the JSON value and the length of the
25929
    JSON patch. As usually only a fraction of the JSON value is affected by
25930
    the patch, the complexity can usually be neglected.
25931
25932
    @liveexample{The following code shows how a JSON patch is applied to a
25933
    value.,patch}
25934
25935
    @sa see @ref diff -- create a JSON patch by comparing two JSON values
25936
25937
    @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
25938
    @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
25939
25940
    @since version 2.0.0
25941
    */
25942
    basic_json patch(const basic_json& json_patch) const
25943
    {
25944
        // make a working copy to apply the patch to
25945
        basic_json result = *this;
25946
25947
        // the valid JSON Patch operations
25948
        enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25949
25950
        const auto get_op = [](const std::string & op)
25951
        {
25952
            if (op == "add")
25953
            {
25954
                return patch_operations::add;
25955
            }
25956
            if (op == "remove")
25957
            {
25958
                return patch_operations::remove;
25959
            }
25960
            if (op == "replace")
25961
            {
25962
                return patch_operations::replace;
25963
            }
25964
            if (op == "move")
25965
            {
25966
                return patch_operations::move;
25967
            }
25968
            if (op == "copy")
25969
            {
25970
                return patch_operations::copy;
25971
            }
25972
            if (op == "test")
25973
            {
25974
                return patch_operations::test;
25975
            }
25976
25977
            return patch_operations::invalid;
25978
        };
25979
25980
        // wrapper for "add" operation; add value at ptr
25981
        const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25982
        {
25983
            // adding to the root of the target document means replacing it
25984
            if (ptr.empty())
25985
            {
25986
                result = val;
25987
                return;
25988
            }
25989
25990
            // make sure the top element of the pointer exists
25991
            json_pointer top_pointer = ptr.top();
25992
            if (top_pointer != ptr)
25993
            {
25994
                result.at(top_pointer);
25995
            }
25996
25997
            // get reference to parent of JSON pointer ptr
25998
            const auto last_path = ptr.back();
25999
            ptr.pop_back();
26000
            basic_json& parent = result[ptr];
26001
26002
            switch (parent.m_type)
26003
            {
26004
                case value_t::null:
26005
                case value_t::object:
26006
                {
26007
                    // use operator[] to add value
26008
                    parent[last_path] = val;
26009
                    break;
26010
                }
26011
26012
                case value_t::array:
26013
                {
26014
                    if (last_path == "-")
26015
                    {
26016
                        // special case: append to back
26017
                        parent.push_back(val);
26018
                    }
26019
                    else
26020
                    {
26021
                        const auto idx = json_pointer::array_index(last_path);
26022
                        if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
26023
                        {
26024
                            // avoid undefined behavior
26025
                            JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
26026
                        }
26027
26028
                        // default case: insert add offset
26029
                        parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
26030
                    }
26031
                    break;
26032
                }
26033
26034
                // if there exists a parent it cannot be primitive
26035
                case value_t::string: // LCOV_EXCL_LINE
26036
                case value_t::boolean: // LCOV_EXCL_LINE
26037
                case value_t::number_integer: // LCOV_EXCL_LINE
26038
                case value_t::number_unsigned: // LCOV_EXCL_LINE
26039
                case value_t::number_float: // LCOV_EXCL_LINE
26040
                case value_t::binary: // LCOV_EXCL_LINE
26041
                case value_t::discarded: // LCOV_EXCL_LINE
26042
                default:            // LCOV_EXCL_LINE
26043
                    JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
26044
            }
26045
        };
26046
26047
        // wrapper for "remove" operation; remove value at ptr
26048
        const auto operation_remove = [this, &result](json_pointer & ptr)
26049
        {
26050
            // get reference to parent of JSON pointer ptr
26051
            const auto last_path = ptr.back();
26052
            ptr.pop_back();
26053
            basic_json& parent = result.at(ptr);
26054
26055
            // remove child
26056
            if (parent.is_object())
26057
            {
26058
                // perform range check
26059
                auto it = parent.find(last_path);
26060
                if (JSON_HEDLEY_LIKELY(it != parent.end()))
26061
                {
26062
                    parent.erase(it);
26063
                }
26064
                else
26065
                {
26066
                    JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
26067
                }
26068
            }
26069
            else if (parent.is_array())
26070
            {
26071
                // note erase performs range check
26072
                parent.erase(json_pointer::array_index(last_path));
26073
            }
26074
        };
26075
26076
        // type check: top level value must be an array
26077
        if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
26078
        {
26079
            JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
26080
        }
26081
26082
        // iterate and apply the operations
26083
        for (const auto& val : json_patch)
26084
        {
26085
            // wrapper to get a value for an operation
26086
            const auto get_value = [&val](const std::string & op,
26087
                                          const std::string & member,
26088
                                          bool string_type) -> basic_json &
26089
            {
26090
                // find value
26091
                auto it = val.m_value.object->find(member);
26092
26093
                // context-sensitive error message
26094
                const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
26095
26096
                // check if desired value is present
26097
                if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
26098
                {
26099
                    // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26100
                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
26101
                }
26102
26103
                // check if result is of type string
26104
                if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
26105
                {
26106
                    // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26107
                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
26108
                }
26109
26110
                // no error: return value
26111
                return it->second;
26112
            };
26113
26114
            // type check: every element of the array must be an object
26115
            if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26116
            {
26117
                JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26118
            }
26119
26120
            // collect mandatory members
26121
            const auto op = get_value("op", "op", true).template get<std::string>();
26122
            const auto path = get_value(op, "path", true).template get<std::string>();
26123
            json_pointer ptr(path);
26124
26125
            switch (get_op(op))
26126
            {
26127
                case patch_operations::add:
26128
                {
26129
                    operation_add(ptr, get_value("add", "value", false));
26130
                    break;
26131
                }
26132
26133
                case patch_operations::remove:
26134
                {
26135
                    operation_remove(ptr);
26136
                    break;
26137
                }
26138
26139
                case patch_operations::replace:
26140
                {
26141
                    // the "path" location must exist - use at()
26142
                    result.at(ptr) = get_value("replace", "value", false);
26143
                    break;
26144
                }
26145
26146
                case patch_operations::move:
26147
                {
26148
                    const auto from_path = get_value("move", "from", true).template get<std::string>();
26149
                    json_pointer from_ptr(from_path);
26150
26151
                    // the "from" location must exist - use at()
26152
                    basic_json v = result.at(from_ptr);
26153
26154
                    // The move operation is functionally identical to a
26155
                    // "remove" operation on the "from" location, followed
26156
                    // immediately by an "add" operation at the target
26157
                    // location with the value that was just removed.
26158
                    operation_remove(from_ptr);
26159
                    operation_add(ptr, v);
26160
                    break;
26161
                }
26162
26163
                case patch_operations::copy:
26164
                {
26165
                    const auto from_path = get_value("copy", "from", true).template get<std::string>();
26166
                    const json_pointer from_ptr(from_path);
26167
26168
                    // the "from" location must exist - use at()
26169
                    basic_json v = result.at(from_ptr);
26170
26171
                    // The copy is functionally identical to an "add"
26172
                    // operation at the target location using the value
26173
                    // specified in the "from" member.
26174
                    operation_add(ptr, v);
26175
                    break;
26176
                }
26177
26178
                case patch_operations::test:
26179
                {
26180
                    bool success = false;
26181
                    JSON_TRY
26182
                    {
26183
                        // check if "value" matches the one at "path"
26184
                        // the "path" location must exist - use at()
26185
                        success = (result.at(ptr) == get_value("test", "value", false));
26186
                    }
26187
                    JSON_INTERNAL_CATCH (out_of_range&)
26188
                    {
26189
                        // ignore out of range errors: success remains false
26190
                    }
26191
26192
                    // throw an exception if test fails
26193
                    if (JSON_HEDLEY_UNLIKELY(!success))
26194
                    {
26195
                        JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26196
                    }
26197
26198
                    break;
26199
                }
26200
26201
                case patch_operations::invalid:
26202
                default:
26203
                {
26204
                    // op must be "add", "remove", "replace", "move", "copy", or
26205
                    // "test"
26206
                    JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26207
                }
26208
            }
26209
        }
26210
26211
        return result;
26212
    }
26213
26214
    /*!
26215
    @brief creates a diff as a JSON patch
26216
26217
    Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
26218
    be changed into the value @a target by calling @ref patch function.
26219
26220
    @invariant For two JSON values @a source and @a target, the following code
26221
    yields always `true`:
26222
    @code {.cpp}
26223
    source.patch(diff(source, target)) == target;
26224
    @endcode
26225
26226
    @note Currently, only `remove`, `add`, and `replace` operations are
26227
          generated.
26228
26229
    @param[in] source  JSON value to compare from
26230
    @param[in] target  JSON value to compare against
26231
    @param[in] path    helper value to create JSON pointers
26232
26233
    @return a JSON patch to convert the @a source to @a target
26234
26235
    @complexity Linear in the lengths of @a source and @a target.
26236
26237
    @liveexample{The following code shows how a JSON patch is created as a
26238
    diff for two JSON values.,diff}
26239
26240
    @sa see @ref patch -- apply a JSON patch
26241
    @sa see @ref merge_patch -- apply a JSON Merge Patch
26242
26243
    @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
26244
26245
    @since version 2.0.0
26246
    */
26247
    JSON_HEDLEY_WARN_UNUSED_RESULT
26248
    static basic_json diff(const basic_json& source, const basic_json& target,
26249
                           const std::string& path = "")
26250
    {
26251
        // the patch
26252
        basic_json result(value_t::array);
26253
26254
        // if the values are the same, return empty patch
26255
        if (source == target)
26256
        {
26257
            return result;
26258
        }
26259
26260
        if (source.type() != target.type())
26261
        {
26262
            // different types: replace value
26263
            result.push_back(
26264
            {
26265
                {"op", "replace"}, {"path", path}, {"value", target}
26266
            });
26267
            return result;
26268
        }
26269
26270
        switch (source.type())
26271
        {
26272
            case value_t::array:
26273
            {
26274
                // first pass: traverse common elements
26275
                std::size_t i = 0;
26276
                while (i < source.size() && i < target.size())
26277
                {
26278
                    // recursive call to compare array values at index i
26279
                    auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26280
                    result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26281
                    ++i;
26282
                }
26283
26284
                // i now reached the end of at least one array
26285
                // in a second pass, traverse the remaining elements
26286
26287
                // remove my remaining elements
26288
                const auto end_index = static_cast<difference_type>(result.size());
26289
                while (i < source.size())
26290
                {
26291
                    // add operations in reverse order to avoid invalid
26292
                    // indices
26293
                    result.insert(result.begin() + end_index, object(
26294
                    {
26295
                        {"op", "remove"},
26296
                        {"path", path + "/" + std::to_string(i)}
26297
                    }));
26298
                    ++i;
26299
                }
26300
26301
                // add other remaining elements
26302
                while (i < target.size())
26303
                {
26304
                    result.push_back(
26305
                    {
26306
                        {"op", "add"},
26307
                        {"path", path + "/-"},
26308
                        {"value", target[i]}
26309
                    });
26310
                    ++i;
26311
                }
26312
26313
                break;
26314
            }
26315
26316
            case value_t::object:
26317
            {
26318
                // first pass: traverse this object's elements
26319
                for (auto it = source.cbegin(); it != source.cend(); ++it)
26320
                {
26321
                    // escape the key name to be used in a JSON patch
26322
                    const auto path_key = path + "/" + detail::escape(it.key());
26323
26324
                    if (target.find(it.key()) != target.end())
26325
                    {
26326
                        // recursive call to compare object values at key it
26327
                        auto temp_diff = diff(it.value(), target[it.key()], path_key);
26328
                        result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26329
                    }
26330
                    else
26331
                    {
26332
                        // found a key that is not in o -> remove it
26333
                        result.push_back(object(
26334
                        {
26335
                            {"op", "remove"}, {"path", path_key}
26336
                        }));
26337
                    }
26338
                }
26339
26340
                // second pass: traverse other object's elements
26341
                for (auto it = target.cbegin(); it != target.cend(); ++it)
26342
                {
26343
                    if (source.find(it.key()) == source.end())
26344
                    {
26345
                        // found a key that is not in this -> add it
26346
                        const auto path_key = path + "/" + detail::escape(it.key());
26347
                        result.push_back(
26348
                        {
26349
                            {"op", "add"}, {"path", path_key},
26350
                            {"value", it.value()}
26351
                        });
26352
                    }
26353
                }
26354
26355
                break;
26356
            }
26357
26358
            case value_t::null:
26359
            case value_t::string:
26360
            case value_t::boolean:
26361
            case value_t::number_integer:
26362
            case value_t::number_unsigned:
26363
            case value_t::number_float:
26364
            case value_t::binary:
26365
            case value_t::discarded:
26366
            default:
26367
            {
26368
                // both primitive type: replace value
26369
                result.push_back(
26370
                {
26371
                    {"op", "replace"}, {"path", path}, {"value", target}
26372
                });
26373
                break;
26374
            }
26375
        }
26376
26377
        return result;
26378
    }
26379
26380
    /// @}
26381
26382
    ////////////////////////////////
26383
    // JSON Merge Patch functions //
26384
    ////////////////////////////////
26385
26386
    /// @name JSON Merge Patch functions
26387
    /// @{
26388
26389
    /*!
26390
    @brief applies a JSON Merge Patch
26391
26392
    The merge patch format is primarily intended for use with the HTTP PATCH
26393
    method as a means of describing a set of modifications to a target
26394
    resource's content. This function applies a merge patch to the current
26395
    JSON value.
26396
26397
    The function implements the following algorithm from Section 2 of
26398
    [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
26399
26400
    ```
26401
    define MergePatch(Target, Patch):
26402
      if Patch is an Object:
26403
        if Target is not an Object:
26404
          Target = {} // Ignore the contents and set it to an empty Object
26405
        for each Name/Value pair in Patch:
26406
          if Value is null:
26407
            if Name exists in Target:
26408
              remove the Name/Value pair from Target
26409
          else:
26410
            Target[Name] = MergePatch(Target[Name], Value)
26411
        return Target
26412
      else:
26413
        return Patch
26414
    ```
26415
26416
    Thereby, `Target` is the current object; that is, the patch is applied to
26417
    the current value.
26418
26419
    @param[in] apply_patch  the patch to apply
26420
26421
    @complexity Linear in the lengths of @a patch.
26422
26423
    @liveexample{The following code shows how a JSON Merge Patch is applied to
26424
    a JSON document.,merge_patch}
26425
26426
    @sa see @ref patch -- apply a JSON patch
26427
    @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
26428
26429
    @since version 3.0.0
26430
    */
26431
    void merge_patch(const basic_json& apply_patch)
26432
    {
26433
        if (apply_patch.is_object())
26434
        {
26435
            if (!is_object())
26436
            {
26437
                *this = object();
26438
            }
26439
            for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26440
            {
26441
                if (it.value().is_null())
26442
                {
26443
                    erase(it.key());
26444
                }
26445
                else
26446
                {
26447
                    operator[](it.key()).merge_patch(it.value());
26448
                }
26449
            }
26450
        }
26451
        else
26452
        {
26453
            *this = apply_patch;
26454
        }
26455
    }
26456
26457
    /// @}
26458
};
26459
26460
/*!
26461
@brief user-defined to_string function for JSON values
26462
26463
This function implements a user-defined to_string  for JSON objects.
26464
26465
@param[in] j  a JSON object
26466
@return a std::string object
26467
*/
26468
26469
NLOHMANN_BASIC_JSON_TPL_DECLARATION
26470
std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
26471
{
26472
    return j.dump();
26473
}
26474
} // namespace nlohmann
26475
26476
///////////////////////
26477
// nonmember support //
26478
///////////////////////
26479
26480
// specialization of std::swap, and std::hash
26481
namespace std
26482
{
26483
26484
/// hash value for JSON objects
26485
template<>
26486
struct hash<nlohmann::json>
26487
{
26488
    /*!
26489
    @brief return a hash value for a JSON object
26490
26491
    @since version 1.0.0
26492
    */
26493
    std::size_t operator()(const nlohmann::json& j) const
26494
0
    {
26495
0
        return nlohmann::detail::hash(j);
26496
0
    }
26497
};
26498
26499
/// specialization for std::less<value_t>
26500
/// @note: do not remove the space after '<',
26501
///        see https://github.com/nlohmann/json/pull/679
26502
template<>
26503
struct less<::nlohmann::detail::value_t>
26504
{
26505
    /*!
26506
    @brief compare two value_t enum values
26507
    @since version 3.0.0
26508
    */
26509
    bool operator()(nlohmann::detail::value_t lhs,
26510
                    nlohmann::detail::value_t rhs) const noexcept
26511
0
    {
26512
0
        return nlohmann::detail::operator<(lhs, rhs);
26513
0
    }
26514
};
26515
26516
// C++20 prohibit function specialization in the std namespace.
26517
#ifndef JSON_HAS_CPP_20
26518
26519
/*!
26520
@brief exchanges the values of two JSON objects
26521
26522
@since version 1.0.0
26523
*/
26524
template<>
26525
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26526
    is_nothrow_move_constructible<nlohmann::json>::value&&  // NOLINT(misc-redundant-expression)
26527
    is_nothrow_move_assignable<nlohmann::json>::value
26528
                              )
26529
0
{
26530
0
    j1.swap(j2);
26531
0
}
26532
26533
#endif
26534
26535
} // namespace std
26536
26537
/*!
26538
@brief user-defined string literal for JSON values
26539
26540
This operator implements a user-defined string literal for JSON objects. It
26541
can be used by adding `"_json"` to a string literal and returns a JSON object
26542
if no parse error occurred.
26543
26544
@param[in] s  a string representation of a JSON object
26545
@param[in] n  the length of string @a s
26546
@return a JSON object
26547
26548
@since version 1.0.0
26549
*/
26550
JSON_HEDLEY_NON_NULL(1)
26551
inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26552
0
{
26553
0
    return nlohmann::json::parse(s, s + n);
26554
0
}
26555
26556
/*!
26557
@brief user-defined string literal for JSON pointer
26558
26559
This operator implements a user-defined string literal for JSON Pointers. It
26560
can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
26561
object if no parse error occurred.
26562
26563
@param[in] s  a string representation of a JSON Pointer
26564
@param[in] n  the length of string @a s
26565
@return a JSON pointer object
26566
26567
@since version 2.0.0
26568
*/
26569
JSON_HEDLEY_NON_NULL(1)
26570
inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26571
0
{
26572
0
    return nlohmann::json::json_pointer(std::string(s, n));
26573
0
}
26574
26575
// #include <nlohmann/detail/macro_unscope.hpp>
26576
26577
26578
// restore clang diagnostic settings
26579
#if defined(__clang__)
26580
    #pragma clang diagnostic pop
26581
#endif
26582
26583
// clean up
26584
#undef JSON_ASSERT
26585
#undef JSON_INTERNAL_CATCH
26586
#undef JSON_CATCH
26587
#undef JSON_THROW
26588
#undef JSON_TRY
26589
#undef JSON_PRIVATE_UNLESS_TESTED
26590
#undef JSON_HAS_CPP_11
26591
#undef JSON_HAS_CPP_14
26592
#undef JSON_HAS_CPP_17
26593
#undef JSON_HAS_CPP_20
26594
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26595
#undef NLOHMANN_BASIC_JSON_TPL
26596
#undef JSON_EXPLICIT
26597
#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
26598
26599
// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26600
26601
26602
#undef JSON_HEDLEY_ALWAYS_INLINE
26603
#undef JSON_HEDLEY_ARM_VERSION
26604
#undef JSON_HEDLEY_ARM_VERSION_CHECK
26605
#undef JSON_HEDLEY_ARRAY_PARAM
26606
#undef JSON_HEDLEY_ASSUME
26607
#undef JSON_HEDLEY_BEGIN_C_DECLS
26608
#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26609
#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26610
#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26611
#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26612
#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26613
#undef JSON_HEDLEY_CLANG_HAS_FEATURE
26614
#undef JSON_HEDLEY_CLANG_HAS_WARNING
26615
#undef JSON_HEDLEY_COMPCERT_VERSION
26616
#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26617
#undef JSON_HEDLEY_CONCAT
26618
#undef JSON_HEDLEY_CONCAT3
26619
#undef JSON_HEDLEY_CONCAT3_EX
26620
#undef JSON_HEDLEY_CONCAT_EX
26621
#undef JSON_HEDLEY_CONST
26622
#undef JSON_HEDLEY_CONSTEXPR
26623
#undef JSON_HEDLEY_CONST_CAST
26624
#undef JSON_HEDLEY_CPP_CAST
26625
#undef JSON_HEDLEY_CRAY_VERSION
26626
#undef JSON_HEDLEY_CRAY_VERSION_CHECK
26627
#undef JSON_HEDLEY_C_DECL
26628
#undef JSON_HEDLEY_DEPRECATED
26629
#undef JSON_HEDLEY_DEPRECATED_FOR
26630
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26631
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26632
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26633
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26634
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26635
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26636
#undef JSON_HEDLEY_DIAGNOSTIC_POP
26637
#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26638
#undef JSON_HEDLEY_DMC_VERSION
26639
#undef JSON_HEDLEY_DMC_VERSION_CHECK
26640
#undef JSON_HEDLEY_EMPTY_BASES
26641
#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26642
#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26643
#undef JSON_HEDLEY_END_C_DECLS
26644
#undef JSON_HEDLEY_FLAGS
26645
#undef JSON_HEDLEY_FLAGS_CAST
26646
#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26647
#undef JSON_HEDLEY_GCC_HAS_BUILTIN
26648
#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26649
#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26650
#undef JSON_HEDLEY_GCC_HAS_EXTENSION
26651
#undef JSON_HEDLEY_GCC_HAS_FEATURE
26652
#undef JSON_HEDLEY_GCC_HAS_WARNING
26653
#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26654
#undef JSON_HEDLEY_GCC_VERSION
26655
#undef JSON_HEDLEY_GCC_VERSION_CHECK
26656
#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26657
#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26658
#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26659
#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26660
#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26661
#undef JSON_HEDLEY_GNUC_HAS_FEATURE
26662
#undef JSON_HEDLEY_GNUC_HAS_WARNING
26663
#undef JSON_HEDLEY_GNUC_VERSION
26664
#undef JSON_HEDLEY_GNUC_VERSION_CHECK
26665
#undef JSON_HEDLEY_HAS_ATTRIBUTE
26666
#undef JSON_HEDLEY_HAS_BUILTIN
26667
#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26668
#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26669
#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26670
#undef JSON_HEDLEY_HAS_EXTENSION
26671
#undef JSON_HEDLEY_HAS_FEATURE
26672
#undef JSON_HEDLEY_HAS_WARNING
26673
#undef JSON_HEDLEY_IAR_VERSION
26674
#undef JSON_HEDLEY_IAR_VERSION_CHECK
26675
#undef JSON_HEDLEY_IBM_VERSION
26676
#undef JSON_HEDLEY_IBM_VERSION_CHECK
26677
#undef JSON_HEDLEY_IMPORT
26678
#undef JSON_HEDLEY_INLINE
26679
#undef JSON_HEDLEY_INTEL_CL_VERSION
26680
#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26681
#undef JSON_HEDLEY_INTEL_VERSION
26682
#undef JSON_HEDLEY_INTEL_VERSION_CHECK
26683
#undef JSON_HEDLEY_IS_CONSTANT
26684
#undef JSON_HEDLEY_IS_CONSTEXPR_
26685
#undef JSON_HEDLEY_LIKELY
26686
#undef JSON_HEDLEY_MALLOC
26687
#undef JSON_HEDLEY_MCST_LCC_VERSION
26688
#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26689
#undef JSON_HEDLEY_MESSAGE
26690
#undef JSON_HEDLEY_MSVC_VERSION
26691
#undef JSON_HEDLEY_MSVC_VERSION_CHECK
26692
#undef JSON_HEDLEY_NEVER_INLINE
26693
#undef JSON_HEDLEY_NON_NULL
26694
#undef JSON_HEDLEY_NO_ESCAPE
26695
#undef JSON_HEDLEY_NO_RETURN
26696
#undef JSON_HEDLEY_NO_THROW
26697
#undef JSON_HEDLEY_NULL
26698
#undef JSON_HEDLEY_PELLES_VERSION
26699
#undef JSON_HEDLEY_PELLES_VERSION_CHECK
26700
#undef JSON_HEDLEY_PGI_VERSION
26701
#undef JSON_HEDLEY_PGI_VERSION_CHECK
26702
#undef JSON_HEDLEY_PREDICT
26703
#undef JSON_HEDLEY_PRINTF_FORMAT
26704
#undef JSON_HEDLEY_PRIVATE
26705
#undef JSON_HEDLEY_PUBLIC
26706
#undef JSON_HEDLEY_PURE
26707
#undef JSON_HEDLEY_REINTERPRET_CAST
26708
#undef JSON_HEDLEY_REQUIRE
26709
#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26710
#undef JSON_HEDLEY_REQUIRE_MSG
26711
#undef JSON_HEDLEY_RESTRICT
26712
#undef JSON_HEDLEY_RETURNS_NON_NULL
26713
#undef JSON_HEDLEY_SENTINEL
26714
#undef JSON_HEDLEY_STATIC_ASSERT
26715
#undef JSON_HEDLEY_STATIC_CAST
26716
#undef JSON_HEDLEY_STRINGIFY
26717
#undef JSON_HEDLEY_STRINGIFY_EX
26718
#undef JSON_HEDLEY_SUNPRO_VERSION
26719
#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26720
#undef JSON_HEDLEY_TINYC_VERSION
26721
#undef JSON_HEDLEY_TINYC_VERSION_CHECK
26722
#undef JSON_HEDLEY_TI_ARMCL_VERSION
26723
#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26724
#undef JSON_HEDLEY_TI_CL2000_VERSION
26725
#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26726
#undef JSON_HEDLEY_TI_CL430_VERSION
26727
#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26728
#undef JSON_HEDLEY_TI_CL6X_VERSION
26729
#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26730
#undef JSON_HEDLEY_TI_CL7X_VERSION
26731
#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26732
#undef JSON_HEDLEY_TI_CLPRU_VERSION
26733
#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26734
#undef JSON_HEDLEY_TI_VERSION
26735
#undef JSON_HEDLEY_TI_VERSION_CHECK
26736
#undef JSON_HEDLEY_UNAVAILABLE
26737
#undef JSON_HEDLEY_UNLIKELY
26738
#undef JSON_HEDLEY_UNPREDICTABLE
26739
#undef JSON_HEDLEY_UNREACHABLE
26740
#undef JSON_HEDLEY_UNREACHABLE_RETURN
26741
#undef JSON_HEDLEY_VERSION
26742
#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26743
#undef JSON_HEDLEY_VERSION_DECODE_MINOR
26744
#undef JSON_HEDLEY_VERSION_DECODE_REVISION
26745
#undef JSON_HEDLEY_VERSION_ENCODE
26746
#undef JSON_HEDLEY_WARNING
26747
#undef JSON_HEDLEY_WARN_UNUSED_RESULT
26748
#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26749
#undef JSON_HEDLEY_FALL_THROUGH
26750
26751
26752
26753
#endif  // INCLUDE_NLOHMANN_JSON_HPP_