Coverage Report

Created: 2022-08-24 06:18

/src/Fast-DDS/thirdparty/nlohmann-json/nlohmann/json.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
    __ _____ _____ _____
3
 __|  |   __|     |   | |  JSON for Modern C++
4
|  |  |__   |  |  | | | |  version 3.9.1
5
|_____|_____|_____|_|___|  https://github.com/nlohmann/json
6
7
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8
SPDX-License-Identifier: MIT
9
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11
Permission is hereby  granted, free of charge, to any  person obtaining a copy
12
of this software and associated  documentation files (the "Software"), to deal
13
in the Software  without restriction, including without  limitation the rights
14
to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15
copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16
furnished to do so, subject to the following conditions:
17
18
The above copyright notice and this permission notice shall be included in all
19
copies or substantial portions of the Software.
20
21
THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22
IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23
FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24
AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25
LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27
SOFTWARE.
28
*/
29
30
#ifndef INCLUDE_NLOHMANN_JSON_HPP_
31
#define INCLUDE_NLOHMANN_JSON_HPP_
32
33
#define NLOHMANN_JSON_VERSION_MAJOR 3
34
#define NLOHMANN_JSON_VERSION_MINOR 9
35
#define NLOHMANN_JSON_VERSION_PATCH 1
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
#include <iosfwd> // istream, ostream
42
#include <iterator> // random_access_iterator_tag
43
#include <memory> // unique_ptr
44
#include <numeric> // accumulate
45
#include <string> // string, stoi, to_string
46
#include <utility> // declval, forward, move, pair, swap
47
#include <vector> // vector
48
49
// #include <nlohmann/adl_serializer.hpp>
50
51
52
#include <utility>
53
54
// #include <nlohmann/detail/conversions/from_json.hpp>
55
56
57
#include <algorithm> // transform
58
#include <array> // array
59
#include <forward_list> // forward_list
60
#include <iterator> // inserter, front_inserter, end
61
#include <map> // map
62
#include <string> // string
63
#include <tuple> // tuple, make_tuple
64
#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
65
#include <unordered_map> // unordered_map
66
#include <utility> // pair, declval
67
#include <valarray> // valarray
68
69
// #include <nlohmann/detail/exceptions.hpp>
70
71
72
#include <exception> // exception
73
#include <stdexcept> // runtime_error
74
#include <string> // to_string
75
76
// #include <nlohmann/detail/input/position_t.hpp>
77
78
79
#include <cstddef> // size_t
80
81
namespace nlohmann
82
{
83
namespace detail
84
{
85
/// struct to capture the start position of the current token
86
struct position_t
87
{
88
    /// the total number of characters read
89
    std::size_t chars_read_total = 0;
90
    /// the number of characters read in the current line
91
    std::size_t chars_read_current_line = 0;
92
    /// the number of lines read
93
    std::size_t lines_read = 0;
94
95
    /// conversion to size_t to preserve SAX interface
96
    constexpr operator size_t() const
97
0
    {
98
0
        return chars_read_total;
99
0
    }
100
};
101
102
} // namespace detail
103
} // namespace nlohmann
104
105
// #include <nlohmann/detail/macro_scope.hpp>
106
107
108
#include <utility> // pair
109
// #include <nlohmann/thirdparty/hedley/hedley.hpp>
110
/* Hedley - https://nemequ.github.io/hedley
111
 * Created by Evan Nemerson <evan@nemerson.com>
112
 *
113
 * To the extent possible under law, the author(s) have dedicated all
114
 * copyright and related and neighboring rights to this software to
115
 * the public domain worldwide. This software is distributed without
116
 * any warranty.
117
 *
118
 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
119
 * SPDX-License-Identifier: CC0-1.0
120
 */
121
122
#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 14)
123
#if defined(JSON_HEDLEY_VERSION)
124
    #undef JSON_HEDLEY_VERSION
125
#endif
126
#define JSON_HEDLEY_VERSION 14
127
128
#if defined(JSON_HEDLEY_STRINGIFY_EX)
129
    #undef JSON_HEDLEY_STRINGIFY_EX
130
#endif
131
#define JSON_HEDLEY_STRINGIFY_EX(x) #x
132
133
#if defined(JSON_HEDLEY_STRINGIFY)
134
    #undef JSON_HEDLEY_STRINGIFY
135
#endif
136
#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
137
138
#if defined(JSON_HEDLEY_CONCAT_EX)
139
    #undef JSON_HEDLEY_CONCAT_EX
140
#endif
141
#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
142
143
#if defined(JSON_HEDLEY_CONCAT)
144
    #undef JSON_HEDLEY_CONCAT
145
#endif
146
#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
147
148
#if defined(JSON_HEDLEY_CONCAT3_EX)
149
    #undef JSON_HEDLEY_CONCAT3_EX
150
#endif
151
#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
152
153
#if defined(JSON_HEDLEY_CONCAT3)
154
    #undef JSON_HEDLEY_CONCAT3
155
#endif
156
#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
157
158
#if defined(JSON_HEDLEY_VERSION_ENCODE)
159
    #undef JSON_HEDLEY_VERSION_ENCODE
160
#endif
161
#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
162
163
#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
164
    #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
165
#endif
166
#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
167
168
#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
169
    #undef JSON_HEDLEY_VERSION_DECODE_MINOR
170
#endif
171
#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
172
173
#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
174
    #undef JSON_HEDLEY_VERSION_DECODE_REVISION
175
#endif
176
#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
177
178
#if defined(JSON_HEDLEY_GNUC_VERSION)
179
    #undef JSON_HEDLEY_GNUC_VERSION
180
#endif
181
#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
182
    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
183
#elif defined(__GNUC__)
184
    #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
185
#endif
186
187
#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
188
    #undef JSON_HEDLEY_GNUC_VERSION_CHECK
189
#endif
190
#if defined(JSON_HEDLEY_GNUC_VERSION)
191
    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
192
#else
193
    #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
194
#endif
195
196
#if defined(JSON_HEDLEY_MSVC_VERSION)
197
    #undef JSON_HEDLEY_MSVC_VERSION
198
#endif
199
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
200
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
201
#elif defined(_MSC_FULL_VER) && !defined(__ICL)
202
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
203
#elif defined(_MSC_VER) && !defined(__ICL)
204
    #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
205
#endif
206
207
#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
208
    #undef JSON_HEDLEY_MSVC_VERSION_CHECK
209
#endif
210
#if !defined(JSON_HEDLEY_MSVC_VERSION)
211
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
212
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
213
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
214
#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
215
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
216
#else
217
    #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
218
#endif
219
220
#if defined(JSON_HEDLEY_INTEL_VERSION)
221
    #undef JSON_HEDLEY_INTEL_VERSION
222
#endif
223
#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
224
    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
225
#elif defined(__INTEL_COMPILER) && !defined(__ICL)
226
    #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
227
#endif
228
229
#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
230
    #undef JSON_HEDLEY_INTEL_VERSION_CHECK
231
#endif
232
#if defined(JSON_HEDLEY_INTEL_VERSION)
233
    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
234
#else
235
    #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
236
#endif
237
238
#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
239
    #undef JSON_HEDLEY_INTEL_CL_VERSION
240
#endif
241
#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
242
    #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
243
#endif
244
245
#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
246
    #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
247
#endif
248
#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
249
    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
250
#else
251
    #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
252
#endif
253
254
#if defined(JSON_HEDLEY_PGI_VERSION)
255
    #undef JSON_HEDLEY_PGI_VERSION
256
#endif
257
#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
258
    #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
259
#endif
260
261
#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
262
    #undef JSON_HEDLEY_PGI_VERSION_CHECK
263
#endif
264
#if defined(JSON_HEDLEY_PGI_VERSION)
265
    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
266
#else
267
    #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
268
#endif
269
270
#if defined(JSON_HEDLEY_SUNPRO_VERSION)
271
    #undef JSON_HEDLEY_SUNPRO_VERSION
272
#endif
273
#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
274
    #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)
275
#elif defined(__SUNPRO_C)
276
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
277
#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
278
    #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)
279
#elif defined(__SUNPRO_CC)
280
    #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
281
#endif
282
283
#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
284
    #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
285
#endif
286
#if defined(JSON_HEDLEY_SUNPRO_VERSION)
287
    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
288
#else
289
    #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
290
#endif
291
292
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
293
    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
294
#endif
295
#if defined(__EMSCRIPTEN__)
296
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
297
#endif
298
299
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
300
    #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
301
#endif
302
#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
303
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
304
#else
305
    #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
306
#endif
307
308
#if defined(JSON_HEDLEY_ARM_VERSION)
309
    #undef JSON_HEDLEY_ARM_VERSION
310
#endif
311
#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
312
    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
313
#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
314
    #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
315
#endif
316
317
#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
318
    #undef JSON_HEDLEY_ARM_VERSION_CHECK
319
#endif
320
#if defined(JSON_HEDLEY_ARM_VERSION)
321
    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
322
#else
323
    #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
324
#endif
325
326
#if defined(JSON_HEDLEY_IBM_VERSION)
327
    #undef JSON_HEDLEY_IBM_VERSION
328
#endif
329
#if defined(__ibmxl__)
330
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
331
#elif defined(__xlC__) && defined(__xlC_ver__)
332
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
333
#elif defined(__xlC__)
334
    #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
335
#endif
336
337
#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
338
    #undef JSON_HEDLEY_IBM_VERSION_CHECK
339
#endif
340
#if defined(JSON_HEDLEY_IBM_VERSION)
341
    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
342
#else
343
    #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
344
#endif
345
346
#if defined(JSON_HEDLEY_TI_VERSION)
347
    #undef JSON_HEDLEY_TI_VERSION
348
#endif
349
#if \
350
    defined(__TI_COMPILER_VERSION__) && \
351
    ( \
352
      defined(__TMS470__) || defined(__TI_ARM__) || \
353
      defined(__MSP430__) || \
354
      defined(__TMS320C2000__) \
355
    )
356
#if (__TI_COMPILER_VERSION__ >= 16000000)
357
    #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
358
#endif
359
#endif
360
361
#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
362
    #undef JSON_HEDLEY_TI_VERSION_CHECK
363
#endif
364
#if defined(JSON_HEDLEY_TI_VERSION)
365
    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
366
#else
367
    #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
368
#endif
369
370
#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
371
    #undef JSON_HEDLEY_TI_CL2000_VERSION
372
#endif
373
#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
374
    #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
375
#endif
376
377
#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
378
    #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
379
#endif
380
#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
381
    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
382
#else
383
    #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
384
#endif
385
386
#if defined(JSON_HEDLEY_TI_CL430_VERSION)
387
    #undef JSON_HEDLEY_TI_CL430_VERSION
388
#endif
389
#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
390
    #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
391
#endif
392
393
#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
394
    #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
395
#endif
396
#if defined(JSON_HEDLEY_TI_CL430_VERSION)
397
    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
398
#else
399
    #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
400
#endif
401
402
#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
403
    #undef JSON_HEDLEY_TI_ARMCL_VERSION
404
#endif
405
#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
406
    #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
407
#endif
408
409
#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
410
    #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
411
#endif
412
#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
413
    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
414
#else
415
    #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
416
#endif
417
418
#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
419
    #undef JSON_HEDLEY_TI_CL6X_VERSION
420
#endif
421
#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
422
    #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
423
#endif
424
425
#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
426
    #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
427
#endif
428
#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
429
    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430
#else
431
    #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
432
#endif
433
434
#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
435
    #undef JSON_HEDLEY_TI_CL7X_VERSION
436
#endif
437
#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
438
    #define JSON_HEDLEY_TI_CL7X_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_CL7X_VERSION_CHECK)
442
    #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
443
#endif
444
#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
445
    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446
#else
447
    #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
448
#endif
449
450
#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
451
    #undef JSON_HEDLEY_TI_CLPRU_VERSION
452
#endif
453
#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
454
    #define JSON_HEDLEY_TI_CLPRU_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_CLPRU_VERSION_CHECK)
458
    #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
459
#endif
460
#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
461
    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462
#else
463
    #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
464
#endif
465
466
#if defined(JSON_HEDLEY_CRAY_VERSION)
467
    #undef JSON_HEDLEY_CRAY_VERSION
468
#endif
469
#if defined(_CRAYC)
470
    #if defined(_RELEASE_PATCHLEVEL)
471
        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
472
    #else
473
        #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
474
    #endif
475
#endif
476
477
#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
478
    #undef JSON_HEDLEY_CRAY_VERSION_CHECK
479
#endif
480
#if defined(JSON_HEDLEY_CRAY_VERSION)
481
    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
482
#else
483
    #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
484
#endif
485
486
#if defined(JSON_HEDLEY_IAR_VERSION)
487
    #undef JSON_HEDLEY_IAR_VERSION
488
#endif
489
#if defined(__IAR_SYSTEMS_ICC__)
490
    #if __VER__ > 1000
491
        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
492
    #else
493
        #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
494
    #endif
495
#endif
496
497
#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
498
    #undef JSON_HEDLEY_IAR_VERSION_CHECK
499
#endif
500
#if defined(JSON_HEDLEY_IAR_VERSION)
501
    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
502
#else
503
    #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
504
#endif
505
506
#if defined(JSON_HEDLEY_TINYC_VERSION)
507
    #undef JSON_HEDLEY_TINYC_VERSION
508
#endif
509
#if defined(__TINYC__)
510
    #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
511
#endif
512
513
#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
514
    #undef JSON_HEDLEY_TINYC_VERSION_CHECK
515
#endif
516
#if defined(JSON_HEDLEY_TINYC_VERSION)
517
    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
518
#else
519
    #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
520
#endif
521
522
#if defined(JSON_HEDLEY_DMC_VERSION)
523
    #undef JSON_HEDLEY_DMC_VERSION
524
#endif
525
#if defined(__DMC__)
526
    #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
527
#endif
528
529
#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
530
    #undef JSON_HEDLEY_DMC_VERSION_CHECK
531
#endif
532
#if defined(JSON_HEDLEY_DMC_VERSION)
533
    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534
#else
535
    #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
536
#endif
537
538
#if defined(JSON_HEDLEY_COMPCERT_VERSION)
539
    #undef JSON_HEDLEY_COMPCERT_VERSION
540
#endif
541
#if defined(__COMPCERT_VERSION__)
542
    #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
543
#endif
544
545
#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
546
    #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
547
#endif
548
#if defined(JSON_HEDLEY_COMPCERT_VERSION)
549
    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
550
#else
551
    #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
552
#endif
553
554
#if defined(JSON_HEDLEY_PELLES_VERSION)
555
    #undef JSON_HEDLEY_PELLES_VERSION
556
#endif
557
#if defined(__POCC__)
558
    #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
559
#endif
560
561
#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
562
    #undef JSON_HEDLEY_PELLES_VERSION_CHECK
563
#endif
564
#if defined(JSON_HEDLEY_PELLES_VERSION)
565
    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
566
#else
567
    #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
568
#endif
569
570
#if defined(JSON_HEDLEY_GCC_VERSION)
571
    #undef JSON_HEDLEY_GCC_VERSION
572
#endif
573
#if \
574
    defined(JSON_HEDLEY_GNUC_VERSION) && \
575
    !defined(__clang__) && \
576
    !defined(JSON_HEDLEY_INTEL_VERSION) && \
577
    !defined(JSON_HEDLEY_PGI_VERSION) && \
578
    !defined(JSON_HEDLEY_ARM_VERSION) && \
579
    !defined(JSON_HEDLEY_TI_VERSION) && \
580
    !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
581
    !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
582
    !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
583
    !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
584
    !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
585
    !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
586
    !defined(__COMPCERT__)
587
    #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
588
#endif
589
590
#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
591
    #undef JSON_HEDLEY_GCC_VERSION_CHECK
592
#endif
593
#if defined(JSON_HEDLEY_GCC_VERSION)
594
    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
595
#else
596
    #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
597
#endif
598
599
#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
600
    #undef JSON_HEDLEY_HAS_ATTRIBUTE
601
#endif
602
#if defined(__has_attribute)
603
    #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
604
#else
605
    #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
606
#endif
607
608
#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
609
    #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
610
#endif
611
#if defined(__has_attribute)
612
    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
613
#else
614
    #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
615
#endif
616
617
#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
618
    #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
619
#endif
620
#if defined(__has_attribute)
621
    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
622
#else
623
    #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
624
#endif
625
626
#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
627
    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
628
#endif
629
#if \
630
    defined(__has_cpp_attribute) && \
631
    defined(__cplusplus) && \
632
    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
633
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
634
#else
635
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
636
#endif
637
638
#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
639
    #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
640
#endif
641
#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
642
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
643
#elif \
644
    !defined(JSON_HEDLEY_PGI_VERSION) && \
645
    !defined(JSON_HEDLEY_IAR_VERSION) && \
646
    (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
647
    (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
648
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
649
#else
650
    #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
651
#endif
652
653
#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
654
    #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
655
#endif
656
#if defined(__has_cpp_attribute) && defined(__cplusplus)
657
    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
658
#else
659
    #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
660
#endif
661
662
#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
663
    #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
664
#endif
665
#if defined(__has_cpp_attribute) && defined(__cplusplus)
666
    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
667
#else
668
    #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
669
#endif
670
671
#if defined(JSON_HEDLEY_HAS_BUILTIN)
672
    #undef JSON_HEDLEY_HAS_BUILTIN
673
#endif
674
#if defined(__has_builtin)
675
    #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
676
#else
677
    #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
678
#endif
679
680
#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
681
    #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
682
#endif
683
#if defined(__has_builtin)
684
    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
685
#else
686
    #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
687
#endif
688
689
#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
690
    #undef JSON_HEDLEY_GCC_HAS_BUILTIN
691
#endif
692
#if defined(__has_builtin)
693
    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
694
#else
695
    #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
696
#endif
697
698
#if defined(JSON_HEDLEY_HAS_FEATURE)
699
    #undef JSON_HEDLEY_HAS_FEATURE
700
#endif
701
#if defined(__has_feature)
702
    #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
703
#else
704
    #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
705
#endif
706
707
#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
708
    #undef JSON_HEDLEY_GNUC_HAS_FEATURE
709
#endif
710
#if defined(__has_feature)
711
    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
712
#else
713
    #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
714
#endif
715
716
#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
717
    #undef JSON_HEDLEY_GCC_HAS_FEATURE
718
#endif
719
#if defined(__has_feature)
720
    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
721
#else
722
    #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
723
#endif
724
725
#if defined(JSON_HEDLEY_HAS_EXTENSION)
726
    #undef JSON_HEDLEY_HAS_EXTENSION
727
#endif
728
#if defined(__has_extension)
729
    #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
730
#else
731
    #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
732
#endif
733
734
#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
735
    #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
736
#endif
737
#if defined(__has_extension)
738
    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
739
#else
740
    #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
741
#endif
742
743
#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
744
    #undef JSON_HEDLEY_GCC_HAS_EXTENSION
745
#endif
746
#if defined(__has_extension)
747
    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
748
#else
749
    #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
750
#endif
751
752
#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
753
    #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
754
#endif
755
#if defined(__has_declspec_attribute)
756
    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
757
#else
758
    #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
759
#endif
760
761
#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
762
    #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
763
#endif
764
#if defined(__has_declspec_attribute)
765
    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
766
#else
767
    #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
768
#endif
769
770
#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
771
    #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
772
#endif
773
#if defined(__has_declspec_attribute)
774
    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
775
#else
776
    #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
777
#endif
778
779
#if defined(JSON_HEDLEY_HAS_WARNING)
780
    #undef JSON_HEDLEY_HAS_WARNING
781
#endif
782
#if defined(__has_warning)
783
    #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
784
#else
785
    #define JSON_HEDLEY_HAS_WARNING(warning) (0)
786
#endif
787
788
#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
789
    #undef JSON_HEDLEY_GNUC_HAS_WARNING
790
#endif
791
#if defined(__has_warning)
792
    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
793
#else
794
    #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
795
#endif
796
797
#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
798
    #undef JSON_HEDLEY_GCC_HAS_WARNING
799
#endif
800
#if defined(__has_warning)
801
    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
802
#else
803
    #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
804
#endif
805
806
#if \
807
    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
808
    defined(__clang__) || \
809
    JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
810
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
811
    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
812
    JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
813
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
814
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
815
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
816
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
817
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
818
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
819
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
820
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
821
    JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
822
    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
823
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
824
    (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
825
    #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
826
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
827
    #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
828
#else
829
    #define JSON_HEDLEY_PRAGMA(value)
830
#endif
831
832
#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
833
    #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
834
#endif
835
#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
836
    #undef JSON_HEDLEY_DIAGNOSTIC_POP
837
#endif
838
#if defined(__clang__)
839
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
840
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
841
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
842
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
843
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
844
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
845
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
846
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
847
#elif \
848
    JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
849
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
850
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
851
    #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
852
#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
853
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
854
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
855
#elif \
856
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
857
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
858
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
859
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
860
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
861
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
862
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
863
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
864
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
865
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
866
    #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
867
#else
868
    #define JSON_HEDLEY_DIAGNOSTIC_PUSH
869
    #define JSON_HEDLEY_DIAGNOSTIC_POP
870
#endif
871
872
/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
873
   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
874
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
875
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
876
#endif
877
#if defined(__cplusplus)
878
#  if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
879
#    if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
880
#      if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
881
#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
882
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
883
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
884
    _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
885
    _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
886
    xpr \
887
    JSON_HEDLEY_DIAGNOSTIC_POP
888
#      else
889
#        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
890
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
891
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
892
    _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
893
    xpr \
894
    JSON_HEDLEY_DIAGNOSTIC_POP
895
#      endif
896
#    else
897
#      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
898
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
899
    _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
900
    xpr \
901
    JSON_HEDLEY_DIAGNOSTIC_POP
902
#    endif
903
#  endif
904
#endif
905
#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
906
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
907
#endif
908
909
#if defined(JSON_HEDLEY_CONST_CAST)
910
    #undef JSON_HEDLEY_CONST_CAST
911
#endif
912
#if defined(__cplusplus)
913
#  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
914
#elif \
915
  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
916
  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
917
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
918
#  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
919
        JSON_HEDLEY_DIAGNOSTIC_PUSH \
920
        JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
921
        ((T) (expr)); \
922
        JSON_HEDLEY_DIAGNOSTIC_POP \
923
    }))
924
#else
925
#  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
926
#endif
927
928
#if defined(JSON_HEDLEY_REINTERPRET_CAST)
929
    #undef JSON_HEDLEY_REINTERPRET_CAST
930
#endif
931
#if defined(__cplusplus)
932
    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
933
#else
934
    #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
935
#endif
936
937
#if defined(JSON_HEDLEY_STATIC_CAST)
938
    #undef JSON_HEDLEY_STATIC_CAST
939
#endif
940
#if defined(__cplusplus)
941
    #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
942
#else
943
    #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
944
#endif
945
946
#if defined(JSON_HEDLEY_CPP_CAST)
947
    #undef JSON_HEDLEY_CPP_CAST
948
#endif
949
#if defined(__cplusplus)
950
#  if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
951
#    define JSON_HEDLEY_CPP_CAST(T, expr) \
952
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
953
    _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
954
    ((T) (expr)) \
955
    JSON_HEDLEY_DIAGNOSTIC_POP
956
#  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
957
#    define JSON_HEDLEY_CPP_CAST(T, expr) \
958
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
959
    _Pragma("diag_suppress=Pe137") \
960
    JSON_HEDLEY_DIAGNOSTIC_POP
961
#  else
962
#    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
963
#  endif
964
#else
965
#  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
966
#endif
967
968
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
969
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
970
#endif
971
#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
972
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
973
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
974
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
975
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
976
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
977
#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
978
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
979
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
980
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
981
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
982
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
983
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
984
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
985
#elif \
986
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
987
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
988
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
989
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
990
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
991
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
992
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
993
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
994
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
995
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
996
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
997
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
998
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
999
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1000
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1001
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1002
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1003
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1004
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1005
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1006
#else
1007
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1008
#endif
1009
1010
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1011
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1012
#endif
1013
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1014
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1015
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1016
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1017
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1018
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1019
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1020
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1021
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1022
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1023
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1024
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1025
#elif \
1026
    JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1027
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1028
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1029
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1030
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1031
#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1032
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1033
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1034
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1035
#else
1036
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1037
#endif
1038
1039
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1040
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1041
#endif
1042
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1043
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1044
#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1045
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1046
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1047
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1048
#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1049
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1050
#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1051
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1052
#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1053
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1054
#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1055
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1056
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1057
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1058
#elif \
1059
    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1060
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1061
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1062
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1063
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1064
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1065
#else
1066
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1067
#endif
1068
1069
#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1070
    #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1071
#endif
1072
#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1073
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1074
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1075
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1076
#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1077
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1078
#else
1079
    #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1080
#endif
1081
1082
#if defined(JSON_HEDLEY_DEPRECATED)
1083
    #undef JSON_HEDLEY_DEPRECATED
1084
#endif
1085
#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1086
    #undef JSON_HEDLEY_DEPRECATED_FOR
1087
#endif
1088
#if \
1089
    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1090
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1091
    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1092
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1093
#elif \
1094
    JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1095
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1096
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1097
    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1098
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1099
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1100
    JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1101
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1102
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1103
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1104
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1105
    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1106
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1107
#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1108
    #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1109
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1110
#elif \
1111
    JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1112
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1113
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1114
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1115
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1116
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1117
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1118
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1119
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1120
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1121
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1122
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1123
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1124
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1125
    #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1126
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1127
#elif \
1128
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1129
    JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1130
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1131
    #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1132
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1133
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1134
    #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1135
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1136
#else
1137
    #define JSON_HEDLEY_DEPRECATED(since)
1138
    #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1139
#endif
1140
1141
#if defined(JSON_HEDLEY_UNAVAILABLE)
1142
    #undef JSON_HEDLEY_UNAVAILABLE
1143
#endif
1144
#if \
1145
    JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1146
    JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1147
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1148
    #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1149
#else
1150
    #define JSON_HEDLEY_UNAVAILABLE(available_since)
1151
#endif
1152
1153
#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1154
    #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1155
#endif
1156
#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1157
    #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1158
#endif
1159
#if \
1160
    JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1161
    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1162
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1163
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1164
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1165
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1166
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1167
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1168
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1169
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1170
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1171
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1172
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1173
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1174
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1175
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1176
    #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1177
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1178
#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1179
    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1180
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1181
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1182
    #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1183
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1184
#elif defined(_Check_return_) /* SAL */
1185
    #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1186
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1187
#else
1188
    #define JSON_HEDLEY_WARN_UNUSED_RESULT
1189
    #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1190
#endif
1191
1192
#if defined(JSON_HEDLEY_SENTINEL)
1193
    #undef JSON_HEDLEY_SENTINEL
1194
#endif
1195
#if \
1196
    JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1197
    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1198
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1199
    JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1200
    #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1201
#else
1202
    #define JSON_HEDLEY_SENTINEL(position)
1203
#endif
1204
1205
#if defined(JSON_HEDLEY_NO_RETURN)
1206
    #undef JSON_HEDLEY_NO_RETURN
1207
#endif
1208
#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1209
    #define JSON_HEDLEY_NO_RETURN __noreturn
1210
#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1211
    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1212
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1213
    #define JSON_HEDLEY_NO_RETURN _Noreturn
1214
#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1215
    #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1216
#elif \
1217
    JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1218
    JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1219
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1220
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1221
    JSON_HEDLEY_IBM_VERSION_CHECK(10,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
    #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1234
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1235
    #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1236
#elif \
1237
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1238
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1239
    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1240
#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1241
    #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1242
#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1243
    #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1244
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1245
    #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1246
#else
1247
    #define JSON_HEDLEY_NO_RETURN
1248
#endif
1249
1250
#if defined(JSON_HEDLEY_NO_ESCAPE)
1251
    #undef JSON_HEDLEY_NO_ESCAPE
1252
#endif
1253
#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1254
    #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1255
#else
1256
    #define JSON_HEDLEY_NO_ESCAPE
1257
#endif
1258
1259
#if defined(JSON_HEDLEY_UNREACHABLE)
1260
    #undef JSON_HEDLEY_UNREACHABLE
1261
#endif
1262
#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1263
    #undef JSON_HEDLEY_UNREACHABLE_RETURN
1264
#endif
1265
#if defined(JSON_HEDLEY_ASSUME)
1266
    #undef JSON_HEDLEY_ASSUME
1267
#endif
1268
#if \
1269
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1270
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1271
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1272
    #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1273
#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1274
    #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1275
#elif \
1276
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1277
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1278
    #if defined(__cplusplus)
1279
        #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1280
    #else
1281
        #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1282
    #endif
1283
#endif
1284
#if \
1285
    (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1286
    JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1287
    JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1288
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1289
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1290
    #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1291
#elif defined(JSON_HEDLEY_ASSUME)
1292
    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1293
#endif
1294
#if !defined(JSON_HEDLEY_ASSUME)
1295
    #if defined(JSON_HEDLEY_UNREACHABLE)
1296
        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1297
    #else
1298
        #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1299
    #endif
1300
#endif
1301
#if defined(JSON_HEDLEY_UNREACHABLE)
1302
    #if  \
1303
        JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1304
        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1305
        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1306
    #else
1307
        #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1308
    #endif
1309
#else
1310
    #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1311
#endif
1312
#if !defined(JSON_HEDLEY_UNREACHABLE)
1313
    #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1314
#endif
1315
1316
JSON_HEDLEY_DIAGNOSTIC_PUSH
1317
#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1318
    #pragma clang diagnostic ignored "-Wpedantic"
1319
#endif
1320
#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1321
    #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1322
#endif
1323
#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1324
    #if defined(__clang__)
1325
        #pragma clang diagnostic ignored "-Wvariadic-macros"
1326
    #elif defined(JSON_HEDLEY_GCC_VERSION)
1327
        #pragma GCC diagnostic ignored "-Wvariadic-macros"
1328
    #endif
1329
#endif
1330
#if defined(JSON_HEDLEY_NON_NULL)
1331
    #undef JSON_HEDLEY_NON_NULL
1332
#endif
1333
#if \
1334
    JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1335
    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1336
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1337
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1338
    #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1339
#else
1340
    #define JSON_HEDLEY_NON_NULL(...)
1341
#endif
1342
JSON_HEDLEY_DIAGNOSTIC_POP
1343
1344
#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1345
    #undef JSON_HEDLEY_PRINTF_FORMAT
1346
#endif
1347
#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1348
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1349
#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1350
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1351
#elif \
1352
    JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1353
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1354
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1355
    JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1356
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1357
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1358
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1359
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1360
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1361
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1362
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1363
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1364
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1365
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1366
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1367
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1368
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1369
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1370
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1371
#else
1372
    #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1373
#endif
1374
1375
#if defined(JSON_HEDLEY_CONSTEXPR)
1376
    #undef JSON_HEDLEY_CONSTEXPR
1377
#endif
1378
#if defined(__cplusplus)
1379
    #if __cplusplus >= 201103L
1380
        #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1381
    #endif
1382
#endif
1383
#if !defined(JSON_HEDLEY_CONSTEXPR)
1384
    #define JSON_HEDLEY_CONSTEXPR
1385
#endif
1386
1387
#if defined(JSON_HEDLEY_PREDICT)
1388
    #undef JSON_HEDLEY_PREDICT
1389
#endif
1390
#if defined(JSON_HEDLEY_LIKELY)
1391
    #undef JSON_HEDLEY_LIKELY
1392
#endif
1393
#if defined(JSON_HEDLEY_UNLIKELY)
1394
    #undef JSON_HEDLEY_UNLIKELY
1395
#endif
1396
#if defined(JSON_HEDLEY_UNPREDICTABLE)
1397
    #undef JSON_HEDLEY_UNPREDICTABLE
1398
#endif
1399
#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1400
    #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1401
#endif
1402
#if \
1403
  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1404
  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1405
#  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))
1406
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))
1407
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))
1408
0
#  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )
1409
0
#  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )
1410
#elif \
1411
  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1412
  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1413
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1414
  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1415
  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1416
  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1417
  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1418
  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1419
  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1420
  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1421
  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1422
  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1423
  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1424
  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1425
  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1426
#  define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1427
    (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1428
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1429
    (__extension__ ({ \
1430
        double hedley_probability_ = (probability); \
1431
        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1432
    }))
1433
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1434
    (__extension__ ({ \
1435
        double hedley_probability_ = (probability); \
1436
        ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1437
    }))
1438
#  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)
1439
#  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1440
#else
1441
#  define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1442
#  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1443
#  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1444
#  define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1445
#  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1446
#endif
1447
#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1448
    #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1449
#endif
1450
1451
#if defined(JSON_HEDLEY_MALLOC)
1452
    #undef JSON_HEDLEY_MALLOC
1453
#endif
1454
#if \
1455
    JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1456
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1457
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1458
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1459
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1460
    JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1461
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1462
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1463
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1464
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1465
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1466
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1467
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1468
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1469
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1470
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1471
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1472
    #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1473
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1474
    #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1475
#elif \
1476
    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1477
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1478
    #define JSON_HEDLEY_MALLOC __declspec(restrict)
1479
#else
1480
    #define JSON_HEDLEY_MALLOC
1481
#endif
1482
1483
#if defined(JSON_HEDLEY_PURE)
1484
    #undef JSON_HEDLEY_PURE
1485
#endif
1486
#if \
1487
  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1488
  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1489
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1490
  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1491
  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1492
  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1493
  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1494
  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1495
  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1496
  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1497
  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1498
  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1499
  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1500
  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1501
  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1502
  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1503
  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1504
  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1505
#  define JSON_HEDLEY_PURE __attribute__((__pure__))
1506
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1507
#  define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1508
#elif defined(__cplusplus) && \
1509
    ( \
1510
      JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1511
      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1512
      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1513
    )
1514
#  define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1515
#else
1516
#  define JSON_HEDLEY_PURE
1517
#endif
1518
1519
#if defined(JSON_HEDLEY_CONST)
1520
    #undef JSON_HEDLEY_CONST
1521
#endif
1522
#if \
1523
    JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1524
    JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1525
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1526
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1527
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1528
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1529
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1530
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1531
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1532
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1533
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1534
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1535
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1536
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1537
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1538
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1539
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1540
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1541
    #define JSON_HEDLEY_CONST __attribute__((__const__))
1542
#elif \
1543
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1544
    #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1545
#else
1546
    #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1547
#endif
1548
1549
#if defined(JSON_HEDLEY_RESTRICT)
1550
    #undef JSON_HEDLEY_RESTRICT
1551
#endif
1552
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1553
    #define JSON_HEDLEY_RESTRICT restrict
1554
#elif \
1555
    JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1556
    JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1557
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1558
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1559
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1560
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1561
    JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1562
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1563
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1564
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1565
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1566
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1567
    JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1568
    defined(__clang__)
1569
    #define JSON_HEDLEY_RESTRICT __restrict
1570
#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1571
    #define JSON_HEDLEY_RESTRICT _Restrict
1572
#else
1573
    #define JSON_HEDLEY_RESTRICT
1574
#endif
1575
1576
#if defined(JSON_HEDLEY_INLINE)
1577
    #undef JSON_HEDLEY_INLINE
1578
#endif
1579
#if \
1580
    (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1581
    (defined(__cplusplus) && (__cplusplus >= 199711L))
1582
    #define JSON_HEDLEY_INLINE inline
1583
#elif \
1584
    defined(JSON_HEDLEY_GCC_VERSION) || \
1585
    JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1586
    #define JSON_HEDLEY_INLINE __inline__
1587
#elif \
1588
    JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1589
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1590
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1591
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1592
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1593
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1594
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1595
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1596
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1597
    #define JSON_HEDLEY_INLINE __inline
1598
#else
1599
    #define JSON_HEDLEY_INLINE
1600
#endif
1601
1602
#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1603
    #undef JSON_HEDLEY_ALWAYS_INLINE
1604
#endif
1605
#if \
1606
  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1607
  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1608
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1609
  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1610
  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1611
  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1612
  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1613
  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1614
  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1615
  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1616
  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1617
  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1618
  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1619
  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1620
  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1621
  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1622
  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1623
#  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1624
#elif \
1625
  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1626
  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1627
#  define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1628
#elif defined(__cplusplus) && \
1629
    ( \
1630
      JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1631
      JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1632
      JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1633
      JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1634
      JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1635
      JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1636
    )
1637
#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1638
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1639
#  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1640
#else
1641
#  define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1642
#endif
1643
1644
#if defined(JSON_HEDLEY_NEVER_INLINE)
1645
    #undef JSON_HEDLEY_NEVER_INLINE
1646
#endif
1647
#if \
1648
    JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1649
    JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1650
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1651
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1652
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1653
    JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1654
    JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1655
    (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656
    JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1657
    (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658
    JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1659
    (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660
    JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1661
    (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1662
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1663
    JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1664
    JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1665
    #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1666
#elif \
1667
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1668
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1669
    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1670
#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1671
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1672
#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1673
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1674
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1675
    #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1676
#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1677
    #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1678
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1679
    #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1680
#else
1681
    #define JSON_HEDLEY_NEVER_INLINE
1682
#endif
1683
1684
#if defined(JSON_HEDLEY_PRIVATE)
1685
    #undef JSON_HEDLEY_PRIVATE
1686
#endif
1687
#if defined(JSON_HEDLEY_PUBLIC)
1688
    #undef JSON_HEDLEY_PUBLIC
1689
#endif
1690
#if defined(JSON_HEDLEY_IMPORT)
1691
    #undef JSON_HEDLEY_IMPORT
1692
#endif
1693
#if defined(_WIN32) || defined(__CYGWIN__)
1694
#  define JSON_HEDLEY_PRIVATE
1695
#  define JSON_HEDLEY_PUBLIC   __declspec(dllexport)
1696
#  define JSON_HEDLEY_IMPORT   __declspec(dllimport)
1697
#else
1698
#  if \
1699
    JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1700
    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1701
    JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1702
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1703
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1704
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1705
    ( \
1706
      defined(__TI_EABI__) && \
1707
      ( \
1708
        (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1709
        JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1710
      ) \
1711
    )
1712
#    define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1713
#    define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__("default")))
1714
#  else
1715
#    define JSON_HEDLEY_PRIVATE
1716
#    define JSON_HEDLEY_PUBLIC
1717
#  endif
1718
#  define JSON_HEDLEY_IMPORT    extern
1719
#endif
1720
1721
#if defined(JSON_HEDLEY_NO_THROW)
1722
    #undef JSON_HEDLEY_NO_THROW
1723
#endif
1724
#if \
1725
    JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1726
    JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1727
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1728
    #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1729
#elif \
1730
    JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1731
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1732
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1733
    #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1734
#else
1735
    #define JSON_HEDLEY_NO_THROW
1736
#endif
1737
1738
#if defined(JSON_HEDLEY_FALL_THROUGH)
1739
    #undef JSON_HEDLEY_FALL_THROUGH
1740
#endif
1741
#if \
1742
    JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1743
    JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1744
    #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1745
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1746
    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1747
#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1748
    #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1749
#elif defined(__fallthrough) /* SAL */
1750
    #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1751
#else
1752
    #define JSON_HEDLEY_FALL_THROUGH
1753
#endif
1754
1755
#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1756
    #undef JSON_HEDLEY_RETURNS_NON_NULL
1757
#endif
1758
#if \
1759
    JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1760
    JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1761
    #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1762
#elif defined(_Ret_notnull_) /* SAL */
1763
    #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1764
#else
1765
    #define JSON_HEDLEY_RETURNS_NON_NULL
1766
#endif
1767
1768
#if defined(JSON_HEDLEY_ARRAY_PARAM)
1769
    #undef JSON_HEDLEY_ARRAY_PARAM
1770
#endif
1771
#if \
1772
    defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1773
    !defined(__STDC_NO_VLA__) && \
1774
    !defined(__cplusplus) && \
1775
    !defined(JSON_HEDLEY_PGI_VERSION) && \
1776
    !defined(JSON_HEDLEY_TINYC_VERSION)
1777
    #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1778
#else
1779
    #define JSON_HEDLEY_ARRAY_PARAM(name)
1780
#endif
1781
1782
#if defined(JSON_HEDLEY_IS_CONSTANT)
1783
    #undef JSON_HEDLEY_IS_CONSTANT
1784
#endif
1785
#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1786
    #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1787
#endif
1788
/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1789
   HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
1790
#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1791
    #undef JSON_HEDLEY_IS_CONSTEXPR_
1792
#endif
1793
#if \
1794
    JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1795
    JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1796
    JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1797
    JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1798
    JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1799
    JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1800
    JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1801
    (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1802
    JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1803
    #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1804
#endif
1805
#if !defined(__cplusplus)
1806
#  if \
1807
       JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1808
       JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1809
       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1810
       JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1811
       JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1812
       JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1813
       JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1814
#if defined(__INTPTR_TYPE__)
1815
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1816
#else
1817
    #include <stdint.h>
1818
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1819
#endif
1820
#  elif \
1821
       ( \
1822
          defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1823
          !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1824
          !defined(JSON_HEDLEY_PGI_VERSION) && \
1825
          !defined(JSON_HEDLEY_IAR_VERSION)) || \
1826
       JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1827
       JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1828
       JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1829
       JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1830
       JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1831
#if defined(__INTPTR_TYPE__)
1832
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1833
#else
1834
    #include <stdint.h>
1835
    #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1836
#endif
1837
#  elif \
1838
       defined(JSON_HEDLEY_GCC_VERSION) || \
1839
       defined(JSON_HEDLEY_INTEL_VERSION) || \
1840
       defined(JSON_HEDLEY_TINYC_VERSION) || \
1841
       defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1842
       JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1843
       defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1844
       defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1845
       defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1846
       defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1847
       defined(__clang__)
1848
#    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1849
        sizeof(void) != \
1850
        sizeof(*( \
1851
                  1 ? \
1852
                  ((void*) ((expr) * 0L) ) : \
1853
((struct { char v[sizeof(void) * 2]; } *) 1) \
1854
                ) \
1855
              ) \
1856
                                            )
1857
#  endif
1858
#endif
1859
#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1860
    #if !defined(JSON_HEDLEY_IS_CONSTANT)
1861
        #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1862
    #endif
1863
    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1864
#else
1865
    #if !defined(JSON_HEDLEY_IS_CONSTANT)
1866
        #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1867
    #endif
1868
    #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1869
#endif
1870
1871
#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1872
    #undef JSON_HEDLEY_BEGIN_C_DECLS
1873
#endif
1874
#if defined(JSON_HEDLEY_END_C_DECLS)
1875
    #undef JSON_HEDLEY_END_C_DECLS
1876
#endif
1877
#if defined(JSON_HEDLEY_C_DECL)
1878
    #undef JSON_HEDLEY_C_DECL
1879
#endif
1880
#if defined(__cplusplus)
1881
    #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1882
    #define JSON_HEDLEY_END_C_DECLS }
1883
    #define JSON_HEDLEY_C_DECL extern "C"
1884
#else
1885
    #define JSON_HEDLEY_BEGIN_C_DECLS
1886
    #define JSON_HEDLEY_END_C_DECLS
1887
    #define JSON_HEDLEY_C_DECL
1888
#endif
1889
1890
#if defined(JSON_HEDLEY_STATIC_ASSERT)
1891
    #undef JSON_HEDLEY_STATIC_ASSERT
1892
#endif
1893
#if \
1894
  !defined(__cplusplus) && ( \
1895
      (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1896
      (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1897
      JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1898
      JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1899
      defined(_Static_assert) \
1900
    )
1901
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1902
#elif \
1903
  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1904
  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
1905
  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1906
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1907
#else
1908
#  define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1909
#endif
1910
1911
#if defined(JSON_HEDLEY_NULL)
1912
    #undef JSON_HEDLEY_NULL
1913
#endif
1914
#if defined(__cplusplus)
1915
    #if __cplusplus >= 201103L
1916
        #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1917
    #elif defined(NULL)
1918
        #define JSON_HEDLEY_NULL NULL
1919
    #else
1920
        #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1921
    #endif
1922
#elif defined(NULL)
1923
    #define JSON_HEDLEY_NULL NULL
1924
#else
1925
    #define JSON_HEDLEY_NULL ((void*) 0)
1926
#endif
1927
1928
#if defined(JSON_HEDLEY_MESSAGE)
1929
    #undef JSON_HEDLEY_MESSAGE
1930
#endif
1931
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1932
#  define JSON_HEDLEY_MESSAGE(msg) \
1933
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
1934
    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1935
    JSON_HEDLEY_PRAGMA(message msg) \
1936
    JSON_HEDLEY_DIAGNOSTIC_POP
1937
#elif \
1938
  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1939
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1940
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1941
#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1942
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1943
#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1944
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1945
#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1946
#  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1947
#else
1948
#  define JSON_HEDLEY_MESSAGE(msg)
1949
#endif
1950
1951
#if defined(JSON_HEDLEY_WARNING)
1952
    #undef JSON_HEDLEY_WARNING
1953
#endif
1954
#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1955
#  define JSON_HEDLEY_WARNING(msg) \
1956
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
1957
    JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1958
    JSON_HEDLEY_PRAGMA(clang warning msg) \
1959
    JSON_HEDLEY_DIAGNOSTIC_POP
1960
#elif \
1961
  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1962
  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1963
  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1964
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1965
#elif \
1966
  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1967
  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1968
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1969
#else
1970
#  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1971
#endif
1972
1973
#if defined(JSON_HEDLEY_REQUIRE)
1974
    #undef JSON_HEDLEY_REQUIRE
1975
#endif
1976
#if defined(JSON_HEDLEY_REQUIRE_MSG)
1977
    #undef JSON_HEDLEY_REQUIRE_MSG
1978
#endif
1979
#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1980
#  if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1981
#    define JSON_HEDLEY_REQUIRE(expr) \
1982
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
1983
    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1984
    __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1985
    JSON_HEDLEY_DIAGNOSTIC_POP
1986
#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1987
    JSON_HEDLEY_DIAGNOSTIC_PUSH \
1988
    _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1989
    __attribute__((diagnose_if(!(expr), msg, "error"))) \
1990
    JSON_HEDLEY_DIAGNOSTIC_POP
1991
#  else
1992
#    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1993
#    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1994
#  endif
1995
#else
1996
#  define JSON_HEDLEY_REQUIRE(expr)
1997
#  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1998
#endif
1999
2000
#if defined(JSON_HEDLEY_FLAGS)
2001
    #undef JSON_HEDLEY_FLAGS
2002
#endif
2003
#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
2004
    #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2005
#else
2006
    #define JSON_HEDLEY_FLAGS
2007
#endif
2008
2009
#if defined(JSON_HEDLEY_FLAGS_CAST)
2010
    #undef JSON_HEDLEY_FLAGS_CAST
2011
#endif
2012
#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2013
#  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2014
        JSON_HEDLEY_DIAGNOSTIC_PUSH \
2015
        _Pragma("warning(disable:188)") \
2016
        ((T) (expr)); \
2017
        JSON_HEDLEY_DIAGNOSTIC_POP \
2018
    }))
2019
#else
2020
#  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2021
#endif
2022
2023
#if defined(JSON_HEDLEY_EMPTY_BASES)
2024
    #undef JSON_HEDLEY_EMPTY_BASES
2025
#endif
2026
#if \
2027
    (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2028
    JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2029
    #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2030
#else
2031
    #define JSON_HEDLEY_EMPTY_BASES
2032
#endif
2033
2034
/* Remaining macros are deprecated. */
2035
2036
#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2037
    #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2038
#endif
2039
#if defined(__clang__)
2040
    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2041
#else
2042
    #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2043
#endif
2044
2045
#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2046
    #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2047
#endif
2048
#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2049
2050
#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2051
    #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2052
#endif
2053
#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2054
2055
#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2056
    #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2057
#endif
2058
#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2059
2060
#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2061
    #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2062
#endif
2063
#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2064
2065
#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2066
    #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2067
#endif
2068
#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2069
2070
#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2071
    #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2072
#endif
2073
#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2074
2075
#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2076
    #undef JSON_HEDLEY_CLANG_HAS_WARNING
2077
#endif
2078
#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2079
2080
#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2081
2082
2083
// This file contains all internal macro definitions
2084
// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2085
2086
// exclude unsupported compilers
2087
#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2088
    #if defined(__clang__)
2089
        #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2090
            #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2091
        #endif
2092
    #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2093
        #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2094
            #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2095
        #endif
2096
    #endif
2097
#endif
2098
2099
// C++ language standard detection
2100
#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2101
    #define JSON_HAS_CPP_20
2102
    #define JSON_HAS_CPP_17
2103
    #define JSON_HAS_CPP_14
2104
#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2105
    #define JSON_HAS_CPP_17
2106
    #define JSON_HAS_CPP_14
2107
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2108
    #define JSON_HAS_CPP_14
2109
#endif
2110
2111
// disable float-equal warnings on GCC/clang
2112
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2113
    #pragma GCC diagnostic push
2114
    #pragma GCC diagnostic ignored "-Wfloat-equal"
2115
#endif
2116
2117
// disable documentation warnings on clang
2118
#if defined(__clang__)
2119
    #pragma GCC diagnostic push
2120
    #pragma GCC diagnostic ignored "-Wdocumentation"
2121
#endif
2122
2123
// allow to disable exceptions
2124
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2125
0
    #define JSON_THROW(exception) throw exception
2126
0
    #define JSON_TRY try
2127
    #define JSON_CATCH(exception) catch(exception)
2128
    #define JSON_INTERNAL_CATCH(exception) catch(exception)
2129
#else
2130
    #include <cstdlib>
2131
    #define JSON_THROW(exception) std::abort()
2132
    #define JSON_TRY if(true)
2133
    #define JSON_CATCH(exception) if(false)
2134
    #define JSON_INTERNAL_CATCH(exception) if(false)
2135
#endif
2136
2137
// override exception macros
2138
#if defined(JSON_THROW_USER)
2139
    #undef JSON_THROW
2140
    #define JSON_THROW JSON_THROW_USER
2141
#endif
2142
#if defined(JSON_TRY_USER)
2143
    #undef JSON_TRY
2144
    #define JSON_TRY JSON_TRY_USER
2145
#endif
2146
#if defined(JSON_CATCH_USER)
2147
    #undef JSON_CATCH
2148
    #define JSON_CATCH JSON_CATCH_USER
2149
    #undef JSON_INTERNAL_CATCH
2150
    #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2151
#endif
2152
#if defined(JSON_INTERNAL_CATCH_USER)
2153
    #undef JSON_INTERNAL_CATCH
2154
    #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2155
#endif
2156
2157
// allow to override assert
2158
#if !defined(JSON_ASSERT)
2159
    #include <cassert> // assert
2160
0
    #define JSON_ASSERT(x) assert(x)
2161
#endif
2162
2163
// allow to access some private functions (needed by the test suite)
2164
#if defined(JSON_TESTS_PRIVATE)
2165
    #define JSON_PRIVATE_UNLESS_TESTED public
2166
#else
2167
    #define JSON_PRIVATE_UNLESS_TESTED private
2168
#endif
2169
2170
/*!
2171
@brief macro to briefly define a mapping between an enum and JSON
2172
@def NLOHMANN_JSON_SERIALIZE_ENUM
2173
@since version 3.4.0
2174
*/
2175
#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \
2176
    template<typename BasicJsonType>                                                            \
2177
    inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
2178
    {                                                                                           \
2179
        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2180
        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2181
        auto it = std::find_if(std::begin(m), std::end(m),                                      \
2182
                               [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
2183
        {                                                                                       \
2184
            return ej_pair.first == e;                                                          \
2185
        });                                                                                     \
2186
        j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
2187
    }                                                                                           \
2188
    template<typename BasicJsonType>                                                            \
2189
    inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
2190
    {                                                                                           \
2191
        static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2192
        static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2193
        auto it = std::find_if(std::begin(m), std::end(m),                                      \
2194
                               [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2195
        {                                                                                       \
2196
            return ej_pair.second == j;                                                         \
2197
        });                                                                                     \
2198
        e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
2199
    }
2200
2201
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2202
// may be removed in the future once the class is split.
2203
2204
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
2205
    template<template<typename, typename, typename...> class ObjectType,   \
2206
             template<typename, typename...> class ArrayType,              \
2207
             class StringType, class BooleanType, class NumberIntegerType, \
2208
             class NumberUnsignedType, class NumberFloatType,              \
2209
             template<typename> class AllocatorType,                       \
2210
             template<typename, typename = void> class JSONSerializer,     \
2211
             class BinaryType>
2212
2213
#define NLOHMANN_BASIC_JSON_TPL                                            \
2214
    basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
2215
    NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
2216
    AllocatorType, JSONSerializer, BinaryType>
2217
2218
// Macros to simplify conversion from/to types
2219
2220
#define NLOHMANN_JSON_EXPAND( x ) x
2221
#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
2222
#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2223
        NLOHMANN_JSON_PASTE64, \
2224
        NLOHMANN_JSON_PASTE63, \
2225
        NLOHMANN_JSON_PASTE62, \
2226
        NLOHMANN_JSON_PASTE61, \
2227
        NLOHMANN_JSON_PASTE60, \
2228
        NLOHMANN_JSON_PASTE59, \
2229
        NLOHMANN_JSON_PASTE58, \
2230
        NLOHMANN_JSON_PASTE57, \
2231
        NLOHMANN_JSON_PASTE56, \
2232
        NLOHMANN_JSON_PASTE55, \
2233
        NLOHMANN_JSON_PASTE54, \
2234
        NLOHMANN_JSON_PASTE53, \
2235
        NLOHMANN_JSON_PASTE52, \
2236
        NLOHMANN_JSON_PASTE51, \
2237
        NLOHMANN_JSON_PASTE50, \
2238
        NLOHMANN_JSON_PASTE49, \
2239
        NLOHMANN_JSON_PASTE48, \
2240
        NLOHMANN_JSON_PASTE47, \
2241
        NLOHMANN_JSON_PASTE46, \
2242
        NLOHMANN_JSON_PASTE45, \
2243
        NLOHMANN_JSON_PASTE44, \
2244
        NLOHMANN_JSON_PASTE43, \
2245
        NLOHMANN_JSON_PASTE42, \
2246
        NLOHMANN_JSON_PASTE41, \
2247
        NLOHMANN_JSON_PASTE40, \
2248
        NLOHMANN_JSON_PASTE39, \
2249
        NLOHMANN_JSON_PASTE38, \
2250
        NLOHMANN_JSON_PASTE37, \
2251
        NLOHMANN_JSON_PASTE36, \
2252
        NLOHMANN_JSON_PASTE35, \
2253
        NLOHMANN_JSON_PASTE34, \
2254
        NLOHMANN_JSON_PASTE33, \
2255
        NLOHMANN_JSON_PASTE32, \
2256
        NLOHMANN_JSON_PASTE31, \
2257
        NLOHMANN_JSON_PASTE30, \
2258
        NLOHMANN_JSON_PASTE29, \
2259
        NLOHMANN_JSON_PASTE28, \
2260
        NLOHMANN_JSON_PASTE27, \
2261
        NLOHMANN_JSON_PASTE26, \
2262
        NLOHMANN_JSON_PASTE25, \
2263
        NLOHMANN_JSON_PASTE24, \
2264
        NLOHMANN_JSON_PASTE23, \
2265
        NLOHMANN_JSON_PASTE22, \
2266
        NLOHMANN_JSON_PASTE21, \
2267
        NLOHMANN_JSON_PASTE20, \
2268
        NLOHMANN_JSON_PASTE19, \
2269
        NLOHMANN_JSON_PASTE18, \
2270
        NLOHMANN_JSON_PASTE17, \
2271
        NLOHMANN_JSON_PASTE16, \
2272
        NLOHMANN_JSON_PASTE15, \
2273
        NLOHMANN_JSON_PASTE14, \
2274
        NLOHMANN_JSON_PASTE13, \
2275
        NLOHMANN_JSON_PASTE12, \
2276
        NLOHMANN_JSON_PASTE11, \
2277
        NLOHMANN_JSON_PASTE10, \
2278
        NLOHMANN_JSON_PASTE9, \
2279
        NLOHMANN_JSON_PASTE8, \
2280
        NLOHMANN_JSON_PASTE7, \
2281
        NLOHMANN_JSON_PASTE6, \
2282
        NLOHMANN_JSON_PASTE5, \
2283
        NLOHMANN_JSON_PASTE4, \
2284
        NLOHMANN_JSON_PASTE3, \
2285
        NLOHMANN_JSON_PASTE2, \
2286
        NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2287
#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2288
#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2289
#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2290
#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2291
#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2292
#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)
2293
#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)
2294
#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)
2295
#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)
2296
#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)
2297
#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)
2298
#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)
2299
#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)
2300
#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)
2301
#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)
2302
#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)
2303
#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)
2304
#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)
2305
#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)
2306
#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)
2307
#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)
2308
#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)
2309
#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)
2310
#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)
2311
#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)
2312
#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)
2313
#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)
2314
#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)
2315
#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)
2316
#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)
2317
#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)
2318
#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)
2319
#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)
2320
#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)
2321
#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)
2322
#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)
2323
#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)
2324
#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)
2325
#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)
2326
#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)
2327
#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)
2328
#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)
2329
#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)
2330
#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)
2331
#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)
2332
#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)
2333
#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)
2334
#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)
2335
#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)
2336
#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)
2337
#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)
2338
#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)
2339
#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)
2340
#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)
2341
#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)
2342
#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)
2343
#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)
2344
#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)
2345
#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)
2346
#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)
2347
#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)
2348
#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)
2349
#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)
2350
2351
#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2352
#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2353
2354
/*!
2355
@brief macro
2356
@def NLOHMANN_DEFINE_TYPE_INTRUSIVE
2357
@since version 3.9.0
2358
*/
2359
#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \
2360
    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__)) } \
2361
    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__)) }
2362
2363
/*!
2364
@brief macro
2365
@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
2366
@since version 3.9.0
2367
*/
2368
#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \
2369
    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__)) } \
2370
    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__)) }
2371
2372
#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2373
    #define JSON_USE_IMPLICIT_CONVERSIONS 1
2374
#endif
2375
2376
#if JSON_USE_IMPLICIT_CONVERSIONS
2377
    #define JSON_EXPLICIT
2378
#else
2379
    #define JSON_EXPLICIT explicit
2380
#endif
2381
2382
2383
namespace nlohmann
2384
{
2385
namespace detail
2386
{
2387
////////////////
2388
// exceptions //
2389
////////////////
2390
2391
/*!
2392
@brief general exception of the @ref basic_json class
2393
2394
This class is an extension of `std::exception` objects with a member @a id for
2395
exception ids. It is used as the base class for all exceptions thrown by the
2396
@ref basic_json class. This class can hence be used as "wildcard" to catch
2397
exceptions.
2398
2399
Subclasses:
2400
- @ref parse_error for exceptions indicating a parse error
2401
- @ref invalid_iterator for exceptions indicating errors with iterators
2402
- @ref type_error for exceptions indicating executing a member function with
2403
                  a wrong type
2404
- @ref out_of_range for exceptions indicating access out of the defined range
2405
- @ref other_error for exceptions indicating other library errors
2406
2407
@internal
2408
@note To have nothrow-copy-constructible exceptions, we internally use
2409
      `std::runtime_error` which can cope with arbitrary-length error messages.
2410
      Intermediate strings are built with static functions and then passed to
2411
      the actual constructor.
2412
@endinternal
2413
2414
@liveexample{The following code shows how arbitrary library exceptions can be
2415
caught.,exception}
2416
2417
@since version 3.0.0
2418
*/
2419
class exception : public std::exception
2420
{
2421
  public:
2422
    /// returns the explanatory string
2423
    JSON_HEDLEY_RETURNS_NON_NULL
2424
    const char* what() const noexcept override
2425
0
    {
2426
0
        return m.what();
2427
0
    }
2428
2429
    /// the id of the exception
2430
    const int id;
2431
2432
  protected:
2433
    JSON_HEDLEY_NON_NULL(3)
2434
0
    exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2435
2436
    static std::string name(const std::string& ename, int id_)
2437
0
    {
2438
0
        return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2439
0
    }
2440
2441
  private:
2442
    /// an exception object as storage for error messages
2443
    std::runtime_error m;
2444
};
2445
2446
/*!
2447
@brief exception indicating a parse error
2448
2449
This exception is thrown by the library when a parse error occurs. Parse errors
2450
can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2451
as when using JSON Patch.
2452
2453
Member @a byte holds the byte index of the last read character in the input
2454
file.
2455
2456
Exceptions have ids 1xx.
2457
2458
name / id                      | example message | description
2459
------------------------------ | --------------- | -------------------------
2460
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.
2461
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.
2462
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.
2463
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.
2464
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.
2465
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`.
2466
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.
2467
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.
2468
json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2469
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.
2470
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.
2471
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.
2472
json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2473
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.
2474
2475
@note For an input with n bytes, 1 is the index of the first character and n+1
2476
      is the index of the terminating null byte or the end of file. This also
2477
      holds true when reading a byte vector (CBOR or MessagePack).
2478
2479
@liveexample{The following code shows how a `parse_error` exception can be
2480
caught.,parse_error}
2481
2482
@sa - @ref exception for the base class of the library exceptions
2483
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2484
@sa - @ref type_error for exceptions indicating executing a member function with
2485
                    a wrong type
2486
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2487
@sa - @ref other_error for exceptions indicating other library errors
2488
2489
@since version 3.0.0
2490
*/
2491
class parse_error : public exception
2492
{
2493
  public:
2494
    /*!
2495
    @brief create a parse error exception
2496
    @param[in] id_       the id of the exception
2497
    @param[in] pos       the position where the error occurred (or with
2498
                         chars_read_total=0 if the position cannot be
2499
                         determined)
2500
    @param[in] what_arg  the explanatory string
2501
    @return parse_error object
2502
    */
2503
    static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2504
0
    {
2505
0
        std::string w = exception::name("parse_error", id_) + "parse error" +
2506
0
                        position_string(pos) + ": " + what_arg;
2507
0
        return parse_error(id_, pos.chars_read_total, w.c_str());
2508
0
    }
2509
2510
    static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2511
0
    {
2512
0
        std::string w = exception::name("parse_error", id_) + "parse error" +
2513
0
                        (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2514
0
                        ": " + what_arg;
2515
0
        return parse_error(id_, byte_, w.c_str());
2516
0
    }
2517
2518
    /*!
2519
    @brief byte index of the parse error
2520
2521
    The byte index of the last read character in the input file.
2522
2523
    @note For an input with n bytes, 1 is the index of the first character and
2524
          n+1 is the index of the terminating null byte or the end of file.
2525
          This also holds true when reading a byte vector (CBOR or MessagePack).
2526
    */
2527
    const std::size_t byte;
2528
2529
  private:
2530
    parse_error(int id_, std::size_t byte_, const char* what_arg)
2531
0
        : exception(id_, what_arg), byte(byte_) {}
2532
2533
    static std::string position_string(const position_t& pos)
2534
0
    {
2535
0
        return " at line " + std::to_string(pos.lines_read + 1) +
2536
0
               ", column " + std::to_string(pos.chars_read_current_line);
2537
0
    }
2538
};
2539
2540
/*!
2541
@brief exception indicating errors with iterators
2542
2543
This exception is thrown if iterators passed to a library function do not match
2544
the expected semantics.
2545
2546
Exceptions have ids 2xx.
2547
2548
name / id                           | example message | description
2549
----------------------------------- | --------------- | -------------------------
2550
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.
2551
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.
2552
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.
2553
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.
2554
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.
2555
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.
2556
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.
2557
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.
2558
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.
2559
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.
2560
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.
2561
json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2562
json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2563
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().
2564
2565
@liveexample{The following code shows how an `invalid_iterator` exception can be
2566
caught.,invalid_iterator}
2567
2568
@sa - @ref exception for the base class of the library exceptions
2569
@sa - @ref parse_error for exceptions indicating a parse error
2570
@sa - @ref type_error for exceptions indicating executing a member function with
2571
                    a wrong type
2572
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2573
@sa - @ref other_error for exceptions indicating other library errors
2574
2575
@since version 3.0.0
2576
*/
2577
class invalid_iterator : public exception
2578
{
2579
  public:
2580
    static invalid_iterator create(int id_, const std::string& what_arg)
2581
0
    {
2582
0
        std::string w = exception::name("invalid_iterator", id_) + what_arg;
2583
0
        return invalid_iterator(id_, w.c_str());
2584
0
    }
2585
2586
  private:
2587
    JSON_HEDLEY_NON_NULL(3)
2588
    invalid_iterator(int id_, const char* what_arg)
2589
0
        : exception(id_, what_arg) {}
2590
};
2591
2592
/*!
2593
@brief exception indicating executing a member function with a wrong type
2594
2595
This exception is thrown in case of a type error; that is, a library function is
2596
executed on a JSON value whose type does not match the expected semantics.
2597
2598
Exceptions have ids 3xx.
2599
2600
name / id                     | example message | description
2601
----------------------------- | --------------- | -------------------------
2602
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.
2603
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.
2604
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 &.
2605
json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
2606
json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
2607
json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
2608
json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
2609
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.
2610
json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
2611
json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
2612
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.
2613
json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
2614
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.
2615
json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
2616
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.
2617
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. |
2618
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) |
2619
2620
@liveexample{The following code shows how a `type_error` exception can be
2621
caught.,type_error}
2622
2623
@sa - @ref exception for the base class of the library exceptions
2624
@sa - @ref parse_error for exceptions indicating a parse error
2625
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2626
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2627
@sa - @ref other_error for exceptions indicating other library errors
2628
2629
@since version 3.0.0
2630
*/
2631
class type_error : public exception
2632
{
2633
  public:
2634
    static type_error create(int id_, const std::string& what_arg)
2635
0
    {
2636
0
        std::string w = exception::name("type_error", id_) + what_arg;
2637
0
        return type_error(id_, w.c_str());
2638
0
    }
2639
2640
  private:
2641
    JSON_HEDLEY_NON_NULL(3)
2642
0
    type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2643
};
2644
2645
/*!
2646
@brief exception indicating access out of the defined range
2647
2648
This exception is thrown in case a library function is called on an input
2649
parameter that exceeds the expected range, for instance in case of array
2650
indices or nonexisting object keys.
2651
2652
Exceptions have ids 4xx.
2653
2654
name / id                       | example message | description
2655
------------------------------- | --------------- | -------------------------
2656
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.
2657
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.
2658
json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
2659
json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
2660
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.
2661
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.
2662
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) |
2663
json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
2664
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 |
2665
2666
@liveexample{The following code shows how an `out_of_range` exception can be
2667
caught.,out_of_range}
2668
2669
@sa - @ref exception for the base class of the library exceptions
2670
@sa - @ref parse_error for exceptions indicating a parse error
2671
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2672
@sa - @ref type_error for exceptions indicating executing a member function with
2673
                    a wrong type
2674
@sa - @ref other_error for exceptions indicating other library errors
2675
2676
@since version 3.0.0
2677
*/
2678
class out_of_range : public exception
2679
{
2680
  public:
2681
    static out_of_range create(int id_, const std::string& what_arg)
2682
0
    {
2683
0
        std::string w = exception::name("out_of_range", id_) + what_arg;
2684
0
        return out_of_range(id_, w.c_str());
2685
0
    }
2686
2687
  private:
2688
    JSON_HEDLEY_NON_NULL(3)
2689
0
    out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2690
};
2691
2692
/*!
2693
@brief exception indicating other library errors
2694
2695
This exception is thrown in case of errors that cannot be classified with the
2696
other exception types.
2697
2698
Exceptions have ids 5xx.
2699
2700
name / id                      | example message | description
2701
------------------------------ | --------------- | -------------------------
2702
json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
2703
2704
@sa - @ref exception for the base class of the library exceptions
2705
@sa - @ref parse_error for exceptions indicating a parse error
2706
@sa - @ref invalid_iterator for exceptions indicating errors with iterators
2707
@sa - @ref type_error for exceptions indicating executing a member function with
2708
                    a wrong type
2709
@sa - @ref out_of_range for exceptions indicating access out of the defined range
2710
2711
@liveexample{The following code shows how an `other_error` exception can be
2712
caught.,other_error}
2713
2714
@since version 3.0.0
2715
*/
2716
class other_error : public exception
2717
{
2718
  public:
2719
    static other_error create(int id_, const std::string& what_arg)
2720
0
    {
2721
0
        std::string w = exception::name("other_error", id_) + what_arg;
2722
0
        return other_error(id_, w.c_str());
2723
0
    }
2724
2725
  private:
2726
    JSON_HEDLEY_NON_NULL(3)
2727
0
    other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2728
};
2729
}  // namespace detail
2730
}  // namespace nlohmann
2731
2732
// #include <nlohmann/detail/macro_scope.hpp>
2733
2734
// #include <nlohmann/detail/meta/cpp_future.hpp>
2735
2736
2737
#include <cstddef> // size_t
2738
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2739
2740
namespace nlohmann
2741
{
2742
namespace detail
2743
{
2744
// alias templates to reduce boilerplate
2745
template<bool B, typename T = void>
2746
using enable_if_t = typename std::enable_if<B, T>::type;
2747
2748
template<typename T>
2749
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2750
2751
// implementation of C++14 index_sequence and affiliates
2752
// source: https://stackoverflow.com/a/32223343
2753
template<std::size_t... Ints>
2754
struct index_sequence
2755
{
2756
    using type = index_sequence;
2757
    using value_type = std::size_t;
2758
    static constexpr std::size_t size() noexcept
2759
    {
2760
        return sizeof...(Ints);
2761
    }
2762
};
2763
2764
template<class Sequence1, class Sequence2>
2765
struct merge_and_renumber;
2766
2767
template<std::size_t... I1, std::size_t... I2>
2768
struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2769
        : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2770
2771
template<std::size_t N>
2772
struct make_index_sequence
2773
    : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2774
      typename make_index_sequence < N - N / 2 >::type > {};
2775
2776
template<> struct make_index_sequence<0> : index_sequence<> {};
2777
template<> struct make_index_sequence<1> : index_sequence<0> {};
2778
2779
template<typename... Ts>
2780
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2781
2782
// dispatch utility (taken from ranges-v3)
2783
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2784
template<> struct priority_tag<0> {};
2785
2786
// taken from ranges-v3
2787
template<typename T>
2788
struct static_const
2789
{
2790
    static constexpr T value{};
2791
};
2792
2793
template<typename T>
2794
constexpr T static_const<T>::value;
2795
}  // namespace detail
2796
}  // namespace nlohmann
2797
2798
// #include <nlohmann/detail/meta/type_traits.hpp>
2799
2800
2801
#include <limits> // numeric_limits
2802
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2803
#include <utility> // declval
2804
2805
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
2806
2807
2808
#include <iterator> // random_access_iterator_tag
2809
2810
// #include <nlohmann/detail/meta/void_t.hpp>
2811
2812
2813
namespace nlohmann
2814
{
2815
namespace detail
2816
{
2817
template<typename ...Ts> struct make_void
2818
{
2819
    using type = void;
2820
};
2821
template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2822
} // namespace detail
2823
}  // namespace nlohmann
2824
2825
// #include <nlohmann/detail/meta/cpp_future.hpp>
2826
2827
2828
namespace nlohmann
2829
{
2830
namespace detail
2831
{
2832
template<typename It, typename = void>
2833
struct iterator_types {};
2834
2835
template<typename It>
2836
struct iterator_types <
2837
    It,
2838
    void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2839
    typename It::reference, typename It::iterator_category >>
2840
{
2841
    using difference_type = typename It::difference_type;
2842
    using value_type = typename It::value_type;
2843
    using pointer = typename It::pointer;
2844
    using reference = typename It::reference;
2845
    using iterator_category = typename It::iterator_category;
2846
};
2847
2848
// This is required as some compilers implement std::iterator_traits in a way that
2849
// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2850
template<typename T, typename = void>
2851
struct iterator_traits
2852
{
2853
};
2854
2855
template<typename T>
2856
struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2857
            : iterator_types<T>
2858
{
2859
};
2860
2861
template<typename T>
2862
struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2863
{
2864
    using iterator_category = std::random_access_iterator_tag;
2865
    using value_type = T;
2866
    using difference_type = ptrdiff_t;
2867
    using pointer = T*;
2868
    using reference = T&;
2869
};
2870
} // namespace detail
2871
} // namespace nlohmann
2872
2873
// #include <nlohmann/detail/macro_scope.hpp>
2874
2875
// #include <nlohmann/detail/meta/cpp_future.hpp>
2876
2877
// #include <nlohmann/detail/meta/detected.hpp>
2878
2879
2880
#include <type_traits>
2881
2882
// #include <nlohmann/detail/meta/void_t.hpp>
2883
2884
2885
// https://en.cppreference.com/w/cpp/experimental/is_detected
2886
namespace nlohmann
2887
{
2888
namespace detail
2889
{
2890
struct nonesuch
2891
{
2892
    nonesuch() = delete;
2893
    ~nonesuch() = delete;
2894
    nonesuch(nonesuch const&) = delete;
2895
    nonesuch(nonesuch const&&) = delete;
2896
    void operator=(nonesuch const&) = delete;
2897
    void operator=(nonesuch&&) = delete;
2898
};
2899
2900
template<class Default,
2901
         class AlwaysVoid,
2902
         template<class...> class Op,
2903
         class... Args>
2904
struct detector
2905
{
2906
    using value_t = std::false_type;
2907
    using type = Default;
2908
};
2909
2910
template<class Default, template<class...> class Op, class... Args>
2911
struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2912
{
2913
    using value_t = std::true_type;
2914
    using type = Op<Args...>;
2915
};
2916
2917
template<template<class...> class Op, class... Args>
2918
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2919
2920
template<template<class...> class Op, class... Args>
2921
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2922
2923
template<class Default, template<class...> class Op, class... Args>
2924
using detected_or = detector<Default, void, Op, Args...>;
2925
2926
template<class Default, template<class...> class Op, class... Args>
2927
using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2928
2929
template<class Expected, template<class...> class Op, class... Args>
2930
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2931
2932
template<class To, template<class...> class Op, class... Args>
2933
using is_detected_convertible =
2934
    std::is_convertible<detected_t<Op, Args...>, To>;
2935
}  // namespace detail
2936
}  // namespace nlohmann
2937
2938
// #include <nlohmann/json_fwd.hpp>
2939
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2940
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2941
2942
#include <cstdint> // int64_t, uint64_t
2943
#include <map> // map
2944
#include <memory> // allocator
2945
#include <string> // string
2946
#include <vector> // vector
2947
2948
/*!
2949
@brief namespace for Niels Lohmann
2950
@see https://github.com/nlohmann
2951
@since version 1.0.0
2952
*/
2953
namespace nlohmann
2954
{
2955
/*!
2956
@brief default JSONSerializer template argument
2957
2958
This serializer ignores the template arguments and uses ADL
2959
([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
2960
for serialization.
2961
*/
2962
template<typename T = void, typename SFINAE = void>
2963
struct adl_serializer;
2964
2965
template<template<typename U, typename V, typename... Args> class ObjectType =
2966
         std::map,
2967
         template<typename U, typename... Args> class ArrayType = std::vector,
2968
         class StringType = std::string, class BooleanType = bool,
2969
         class NumberIntegerType = std::int64_t,
2970
         class NumberUnsignedType = std::uint64_t,
2971
         class NumberFloatType = double,
2972
         template<typename U> class AllocatorType = std::allocator,
2973
         template<typename T, typename SFINAE = void> class JSONSerializer =
2974
         adl_serializer,
2975
         class BinaryType = std::vector<std::uint8_t>>
2976
class basic_json;
2977
2978
/*!
2979
@brief JSON Pointer
2980
2981
A JSON pointer defines a string syntax for identifying a specific value
2982
within a JSON document. It can be used with functions `at` and
2983
`operator[]`. Furthermore, JSON pointers are the base for JSON patches.
2984
2985
@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
2986
2987
@since version 2.0.0
2988
*/
2989
template<typename BasicJsonType>
2990
class json_pointer;
2991
2992
/*!
2993
@brief default JSON class
2994
2995
This type is the default specialization of the @ref basic_json class which
2996
uses the standard template types.
2997
2998
@since version 1.0.0
2999
*/
3000
using json = basic_json<>;
3001
3002
template<class Key, class T, class IgnoredLess, class Allocator>
3003
struct ordered_map;
3004
3005
/*!
3006
@brief ordered JSON class
3007
3008
This type preserves the insertion order of object keys.
3009
3010
@since version 3.9.0
3011
*/
3012
using ordered_json = basic_json<nlohmann::ordered_map>;
3013
3014
}  // namespace nlohmann
3015
3016
#endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3017
3018
3019
namespace nlohmann
3020
{
3021
/*!
3022
@brief detail namespace with internal helper functions
3023
3024
This namespace collects functions that should not be exposed,
3025
implementations of some @ref basic_json methods, and meta-programming helpers.
3026
3027
@since version 2.1.0
3028
*/
3029
namespace detail
3030
{
3031
/////////////
3032
// helpers //
3033
/////////////
3034
3035
// Note to maintainers:
3036
//
3037
// Every trait in this file expects a non CV-qualified type.
3038
// The only exceptions are in the 'aliases for detected' section
3039
// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3040
//
3041
// In this case, T has to be properly CV-qualified to constraint the function arguments
3042
// (e.g. to_json(BasicJsonType&, const T&))
3043
3044
template<typename> struct is_basic_json : std::false_type {};
3045
3046
NLOHMANN_BASIC_JSON_TPL_DECLARATION
3047
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3048
3049
//////////////////////
3050
// json_ref helpers //
3051
//////////////////////
3052
3053
template<typename>
3054
class json_ref;
3055
3056
template<typename>
3057
struct is_json_ref : std::false_type {};
3058
3059
template<typename T>
3060
struct is_json_ref<json_ref<T>> : std::true_type {};
3061
3062
//////////////////////////
3063
// aliases for detected //
3064
//////////////////////////
3065
3066
template<typename T>
3067
using mapped_type_t = typename T::mapped_type;
3068
3069
template<typename T>
3070
using key_type_t = typename T::key_type;
3071
3072
template<typename T>
3073
using value_type_t = typename T::value_type;
3074
3075
template<typename T>
3076
using difference_type_t = typename T::difference_type;
3077
3078
template<typename T>
3079
using pointer_t = typename T::pointer;
3080
3081
template<typename T>
3082
using reference_t = typename T::reference;
3083
3084
template<typename T>
3085
using iterator_category_t = typename T::iterator_category;
3086
3087
template<typename T>
3088
using iterator_t = typename T::iterator;
3089
3090
template<typename T, typename... Args>
3091
using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3092
3093
template<typename T, typename... Args>
3094
using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3095
3096
template<typename T, typename U>
3097
using get_template_function = decltype(std::declval<T>().template get<U>());
3098
3099
// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3100
template<typename BasicJsonType, typename T, typename = void>
3101
struct has_from_json : std::false_type {};
3102
3103
// trait checking if j.get<T> is valid
3104
// use this trait instead of std::is_constructible or std::is_convertible,
3105
// both rely on, or make use of implicit conversions, and thus fail when T
3106
// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3107
template <typename BasicJsonType, typename T>
3108
struct is_getable
3109
{
3110
    static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3111
};
3112
3113
template<typename BasicJsonType, typename T>
3114
struct has_from_json < BasicJsonType, T,
3115
           enable_if_t < !is_basic_json<T>::value >>
3116
{
3117
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
3118
3119
    static constexpr bool value =
3120
        is_detected_exact<void, from_json_function, serializer,
3121
        const BasicJsonType&, T&>::value;
3122
};
3123
3124
// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3125
// this overload is used for non-default-constructible user-defined-types
3126
template<typename BasicJsonType, typename T, typename = void>
3127
struct has_non_default_from_json : std::false_type {};
3128
3129
template<typename BasicJsonType, typename T>
3130
struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3131
{
3132
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
3133
3134
    static constexpr bool value =
3135
        is_detected_exact<T, from_json_function, serializer,
3136
        const BasicJsonType&>::value;
3137
};
3138
3139
// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3140
// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3141
template<typename BasicJsonType, typename T, typename = void>
3142
struct has_to_json : std::false_type {};
3143
3144
template<typename BasicJsonType, typename T>
3145
struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3146
{
3147
    using serializer = typename BasicJsonType::template json_serializer<T, void>;
3148
3149
    static constexpr bool value =
3150
        is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3151
        T>::value;
3152
};
3153
3154
3155
///////////////////
3156
// is_ functions //
3157
///////////////////
3158
3159
template<typename T, typename = void>
3160
struct is_iterator_traits : std::false_type {};
3161
3162
template<typename T>
3163
struct is_iterator_traits<iterator_traits<T>>
3164
{
3165
  private:
3166
    using traits = iterator_traits<T>;
3167
3168
  public:
3169
    static constexpr auto value =
3170
        is_detected<value_type_t, traits>::value &&
3171
        is_detected<difference_type_t, traits>::value &&
3172
        is_detected<pointer_t, traits>::value &&
3173
        is_detected<iterator_category_t, traits>::value &&
3174
        is_detected<reference_t, traits>::value;
3175
};
3176
3177
// source: https://stackoverflow.com/a/37193089/4116453
3178
3179
template<typename T, typename = void>
3180
struct is_complete_type : std::false_type {};
3181
3182
template<typename T>
3183
struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3184
3185
template<typename BasicJsonType, typename CompatibleObjectType,
3186
         typename = void>
3187
struct is_compatible_object_type_impl : std::false_type {};
3188
3189
template<typename BasicJsonType, typename CompatibleObjectType>
3190
struct is_compatible_object_type_impl <
3191
    BasicJsonType, CompatibleObjectType,
3192
    enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3193
    is_detected<key_type_t, CompatibleObjectType>::value >>
3194
{
3195
3196
    using object_t = typename BasicJsonType::object_t;
3197
3198
    // macOS's is_constructible does not play well with nonesuch...
3199
    static constexpr bool value =
3200
        std::is_constructible<typename object_t::key_type,
3201
        typename CompatibleObjectType::key_type>::value &&
3202
        std::is_constructible<typename object_t::mapped_type,
3203
        typename CompatibleObjectType::mapped_type>::value;
3204
};
3205
3206
template<typename BasicJsonType, typename CompatibleObjectType>
3207
struct is_compatible_object_type
3208
    : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3209
3210
template<typename BasicJsonType, typename ConstructibleObjectType,
3211
         typename = void>
3212
struct is_constructible_object_type_impl : std::false_type {};
3213
3214
template<typename BasicJsonType, typename ConstructibleObjectType>
3215
struct is_constructible_object_type_impl <
3216
    BasicJsonType, ConstructibleObjectType,
3217
    enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3218
    is_detected<key_type_t, ConstructibleObjectType>::value >>
3219
{
3220
    using object_t = typename BasicJsonType::object_t;
3221
3222
    static constexpr bool value =
3223
        (std::is_default_constructible<ConstructibleObjectType>::value &&
3224
         (std::is_move_assignable<ConstructibleObjectType>::value ||
3225
          std::is_copy_assignable<ConstructibleObjectType>::value) &&
3226
         (std::is_constructible<typename ConstructibleObjectType::key_type,
3227
          typename object_t::key_type>::value &&
3228
          std::is_same <
3229
          typename object_t::mapped_type,
3230
          typename ConstructibleObjectType::mapped_type >::value)) ||
3231
        (has_from_json<BasicJsonType,
3232
         typename ConstructibleObjectType::mapped_type>::value ||
3233
         has_non_default_from_json <
3234
         BasicJsonType,
3235
         typename ConstructibleObjectType::mapped_type >::value);
3236
};
3237
3238
template<typename BasicJsonType, typename ConstructibleObjectType>
3239
struct is_constructible_object_type
3240
    : is_constructible_object_type_impl<BasicJsonType,
3241
      ConstructibleObjectType> {};
3242
3243
template<typename BasicJsonType, typename CompatibleStringType,
3244
         typename = void>
3245
struct is_compatible_string_type_impl : std::false_type {};
3246
3247
template<typename BasicJsonType, typename CompatibleStringType>
3248
struct is_compatible_string_type_impl <
3249
    BasicJsonType, CompatibleStringType,
3250
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3251
    value_type_t, CompatibleStringType>::value >>
3252
{
3253
    static constexpr auto value =
3254
        std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3255
};
3256
3257
template<typename BasicJsonType, typename ConstructibleStringType>
3258
struct is_compatible_string_type
3259
    : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3260
3261
template<typename BasicJsonType, typename ConstructibleStringType,
3262
         typename = void>
3263
struct is_constructible_string_type_impl : std::false_type {};
3264
3265
template<typename BasicJsonType, typename ConstructibleStringType>
3266
struct is_constructible_string_type_impl <
3267
    BasicJsonType, ConstructibleStringType,
3268
    enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3269
    value_type_t, ConstructibleStringType>::value >>
3270
{
3271
    static constexpr auto value =
3272
        std::is_constructible<ConstructibleStringType,
3273
        typename BasicJsonType::string_t>::value;
3274
};
3275
3276
template<typename BasicJsonType, typename ConstructibleStringType>
3277
struct is_constructible_string_type
3278
    : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3279
3280
template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3281
struct is_compatible_array_type_impl : std::false_type {};
3282
3283
template<typename BasicJsonType, typename CompatibleArrayType>
3284
struct is_compatible_array_type_impl <
3285
    BasicJsonType, CompatibleArrayType,
3286
    enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3287
    is_detected<iterator_t, CompatibleArrayType>::value&&
3288
// This is needed because json_reverse_iterator has a ::iterator type...
3289
// Therefore it is detected as a CompatibleArrayType.
3290
// The real fix would be to have an Iterable concept.
3291
    !is_iterator_traits <
3292
    iterator_traits<CompatibleArrayType >>::value >>
3293
{
3294
    static constexpr bool value =
3295
        std::is_constructible<BasicJsonType,
3296
        typename CompatibleArrayType::value_type>::value;
3297
};
3298
3299
template<typename BasicJsonType, typename CompatibleArrayType>
3300
struct is_compatible_array_type
3301
    : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3302
3303
template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3304
struct is_constructible_array_type_impl : std::false_type {};
3305
3306
template<typename BasicJsonType, typename ConstructibleArrayType>
3307
struct is_constructible_array_type_impl <
3308
    BasicJsonType, ConstructibleArrayType,
3309
    enable_if_t<std::is_same<ConstructibleArrayType,
3310
    typename BasicJsonType::value_type>::value >>
3311
            : std::true_type {};
3312
3313
template<typename BasicJsonType, typename ConstructibleArrayType>
3314
struct is_constructible_array_type_impl <
3315
    BasicJsonType, ConstructibleArrayType,
3316
    enable_if_t < !std::is_same<ConstructibleArrayType,
3317
    typename BasicJsonType::value_type>::value&&
3318
    std::is_default_constructible<ConstructibleArrayType>::value&&
3319
(std::is_move_assignable<ConstructibleArrayType>::value ||
3320
 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3321
is_detected<value_type_t, ConstructibleArrayType>::value&&
3322
is_detected<iterator_t, ConstructibleArrayType>::value&&
3323
is_complete_type <
3324
detected_t<value_type_t, ConstructibleArrayType >>::value >>
3325
{
3326
    static constexpr bool value =
3327
        // This is needed because json_reverse_iterator has a ::iterator type,
3328
        // furthermore, std::back_insert_iterator (and other iterators) have a
3329
        // base class `iterator`... Therefore it is detected as a
3330
        // ConstructibleArrayType. The real fix would be to have an Iterable
3331
        // concept.
3332
        !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3333
3334
        (std::is_same<typename ConstructibleArrayType::value_type,
3335
         typename BasicJsonType::array_t::value_type>::value ||
3336
         has_from_json<BasicJsonType,
3337
         typename ConstructibleArrayType::value_type>::value ||
3338
         has_non_default_from_json <
3339
         BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3340
};
3341
3342
template<typename BasicJsonType, typename ConstructibleArrayType>
3343
struct is_constructible_array_type
3344
    : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3345
3346
template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3347
         typename = void>
3348
struct is_compatible_integer_type_impl : std::false_type {};
3349
3350
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3351
struct is_compatible_integer_type_impl <
3352
    RealIntegerType, CompatibleNumberIntegerType,
3353
    enable_if_t < std::is_integral<RealIntegerType>::value&&
3354
    std::is_integral<CompatibleNumberIntegerType>::value&&
3355
    !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3356
{
3357
    // is there an assert somewhere on overflows?
3358
    using RealLimits = std::numeric_limits<RealIntegerType>;
3359
    using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3360
3361
    static constexpr auto value =
3362
        std::is_constructible<RealIntegerType,
3363
        CompatibleNumberIntegerType>::value &&
3364
        CompatibleLimits::is_integer &&
3365
        RealLimits::is_signed == CompatibleLimits::is_signed;
3366
};
3367
3368
template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3369
struct is_compatible_integer_type
3370
    : is_compatible_integer_type_impl<RealIntegerType,
3371
      CompatibleNumberIntegerType> {};
3372
3373
template<typename BasicJsonType, typename CompatibleType, typename = void>
3374
struct is_compatible_type_impl: std::false_type {};
3375
3376
template<typename BasicJsonType, typename CompatibleType>
3377
struct is_compatible_type_impl <
3378
    BasicJsonType, CompatibleType,
3379
    enable_if_t<is_complete_type<CompatibleType>::value >>
3380
{
3381
    static constexpr bool value =
3382
        has_to_json<BasicJsonType, CompatibleType>::value;
3383
};
3384
3385
template<typename BasicJsonType, typename CompatibleType>
3386
struct is_compatible_type
3387
    : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3388
3389
// https://en.cppreference.com/w/cpp/types/conjunction
3390
template<class...> struct conjunction : std::true_type { };
3391
template<class B1> struct conjunction<B1> : B1 { };
3392
template<class B1, class... Bn>
3393
struct conjunction<B1, Bn...>
3394
: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3395
3396
template<typename T1, typename T2>
3397
struct is_constructible_tuple : std::false_type {};
3398
3399
template<typename T1, typename... Args>
3400
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3401
}  // namespace detail
3402
}  // namespace nlohmann
3403
3404
// #include <nlohmann/detail/value_t.hpp>
3405
3406
3407
#include <array> // array
3408
#include <cstddef> // size_t
3409
#include <cstdint> // uint8_t
3410
#include <string> // string
3411
3412
namespace nlohmann
3413
{
3414
namespace detail
3415
{
3416
///////////////////////////
3417
// JSON type enumeration //
3418
///////////////////////////
3419
3420
/*!
3421
@brief the JSON type enumeration
3422
3423
This enumeration collects the different JSON types. It is internally used to
3424
distinguish the stored values, and the functions @ref basic_json::is_null(),
3425
@ref basic_json::is_object(), @ref basic_json::is_array(),
3426
@ref basic_json::is_string(), @ref basic_json::is_boolean(),
3427
@ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
3428
@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
3429
@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
3430
@ref basic_json::is_structured() rely on it.
3431
3432
@note There are three enumeration entries (number_integer, number_unsigned, and
3433
number_float), because the library distinguishes these three types for numbers:
3434
@ref basic_json::number_unsigned_t is used for unsigned integers,
3435
@ref basic_json::number_integer_t is used for signed integers, and
3436
@ref basic_json::number_float_t is used for floating-point numbers or to
3437
approximate integers which do not fit in the limits of their respective type.
3438
3439
@sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
3440
value with the default value for a given type
3441
3442
@since version 1.0.0
3443
*/
3444
enum class value_t : std::uint8_t
3445
{
3446
    null,             ///< null value
3447
    object,           ///< object (unordered set of name/value pairs)
3448
    array,            ///< array (ordered collection of values)
3449
    string,           ///< string value
3450
    boolean,          ///< boolean value
3451
    number_integer,   ///< number value (signed integer)
3452
    number_unsigned,  ///< number value (unsigned integer)
3453
    number_float,     ///< number value (floating-point)
3454
    binary,           ///< binary array (ordered collection of bytes)
3455
    discarded         ///< discarded by the parser callback function
3456
};
3457
3458
/*!
3459
@brief comparison operator for JSON types
3460
3461
Returns an ordering that is similar to Python:
3462
- order: null < boolean < number < object < array < string < binary
3463
- furthermore, each type is not smaller than itself
3464
- discarded values are not comparable
3465
- binary is represented as a b"" string in python and directly comparable to a
3466
  string; however, making a binary array directly comparable with a string would
3467
  be surprising behavior in a JSON file.
3468
3469
@since version 1.0.0
3470
*/
3471
inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3472
0
{
3473
0
    static constexpr std::array<std::uint8_t, 9> order = {{
3474
0
            0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3475
0
            1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3476
0
            6 /* binary */
3477
0
        }
3478
0
    };
3479
0
3480
0
    const auto l_index = static_cast<std::size_t>(lhs);
3481
0
    const auto r_index = static_cast<std::size_t>(rhs);
3482
0
    return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3483
0
}
3484
}  // namespace detail
3485
}  // namespace nlohmann
3486
3487
3488
namespace nlohmann
3489
{
3490
namespace detail
3491
{
3492
template<typename BasicJsonType>
3493
void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3494
{
3495
    if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3496
    {
3497
        JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3498
    }
3499
    n = nullptr;
3500
}
3501
3502
// overloads for basic_json template parameters
3503
template < typename BasicJsonType, typename ArithmeticType,
3504
           enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3505
                         !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3506
                         int > = 0 >
3507
void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3508
0
{
3509
0
    switch (static_cast<value_t>(j))
3510
0
    {
3511
0
        case value_t::number_unsigned:
3512
0
        {
3513
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3514
0
            break;
3515
0
        }
3516
0
        case value_t::number_integer:
3517
0
        {
3518
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3519
0
            break;
3520
0
        }
3521
0
        case value_t::number_float:
3522
0
        {
3523
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3524
0
            break;
3525
0
        }
3526
0
3527
0
        default:
3528
0
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3529
0
    }
3530
0
}
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> > >, 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&)
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&)
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> > >, 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&)
3531
3532
template<typename BasicJsonType>
3533
void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3534
0
{
3535
0
    if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3536
0
    {
3537
0
        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3538
0
    }
3539
0
    b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3540
0
}
3541
3542
template<typename BasicJsonType>
3543
void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3544
0
{
3545
0
    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3546
0
    {
3547
0
        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3548
0
    }
3549
0
    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3550
0
}
3551
3552
template <
3553
    typename BasicJsonType, typename ConstructibleStringType,
3554
    enable_if_t <
3555
        is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3556
        !std::is_same<typename BasicJsonType::string_t,
3557
                      ConstructibleStringType>::value,
3558
        int > = 0 >
3559
void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3560
0
{
3561
0
    if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3562
0
    {
3563
0
        JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3564
0
    }
3565
3566
0
    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3567
0
}
3568
3569
template<typename BasicJsonType>
3570
void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3571
0
{
3572
0
    get_arithmetic_value(j, val);
3573
0
}
3574
3575
template<typename BasicJsonType>
3576
void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3577
0
{
3578
0
    get_arithmetic_value(j, val);
3579
0
}
3580
3581
template<typename BasicJsonType>
3582
void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3583
0
{
3584
0
    get_arithmetic_value(j, val);
3585
0
}
3586
3587
template<typename BasicJsonType, typename EnumType,
3588
         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3589
void from_json(const BasicJsonType& j, EnumType& e)
3590
{
3591
    typename std::underlying_type<EnumType>::type val;
3592
    get_arithmetic_value(j, val);
3593
    e = static_cast<EnumType>(val);
3594
}
3595
3596
// forward_list doesn't have an insert method
3597
template<typename BasicJsonType, typename T, typename Allocator,
3598
         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3599
void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3600
{
3601
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3602
    {
3603
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3604
    }
3605
    l.clear();
3606
    std::transform(j.rbegin(), j.rend(),
3607
                   std::front_inserter(l), [](const BasicJsonType & i)
3608
    {
3609
        return i.template get<T>();
3610
    });
3611
}
3612
3613
// valarray doesn't have an insert method
3614
template<typename BasicJsonType, typename T,
3615
         enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3616
void from_json(const BasicJsonType& j, std::valarray<T>& l)
3617
{
3618
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3619
    {
3620
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3621
    }
3622
    l.resize(j.size());
3623
    std::transform(j.begin(), j.end(), std::begin(l),
3624
                   [](const BasicJsonType & elem)
3625
    {
3626
        return elem.template get<T>();
3627
    });
3628
}
3629
3630
template<typename BasicJsonType, typename T, std::size_t N>
3631
auto from_json(const BasicJsonType& j, T (&arr)[N])
3632
-> decltype(j.template get<T>(), void())
3633
{
3634
    for (std::size_t i = 0; i < N; ++i)
3635
    {
3636
        arr[i] = j.at(i).template get<T>();
3637
    }
3638
}
3639
3640
template<typename BasicJsonType>
3641
void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3642
{
3643
    arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3644
}
3645
3646
template<typename BasicJsonType, typename T, std::size_t N>
3647
auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3648
                          priority_tag<2> /*unused*/)
3649
-> decltype(j.template get<T>(), void())
3650
{
3651
    for (std::size_t i = 0; i < N; ++i)
3652
    {
3653
        arr[i] = j.at(i).template get<T>();
3654
    }
3655
}
3656
3657
template<typename BasicJsonType, typename ConstructibleArrayType>
3658
auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3659
-> decltype(
3660
    arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3661
    j.template get<typename ConstructibleArrayType::value_type>(),
3662
    void())
3663
{
3664
    using std::end;
3665
3666
    ConstructibleArrayType ret;
3667
    ret.reserve(j.size());
3668
    std::transform(j.begin(), j.end(),
3669
                   std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3670
    {
3671
        // get<BasicJsonType>() returns *this, this won't call a from_json
3672
        // method when value_type is BasicJsonType
3673
        return i.template get<typename ConstructibleArrayType::value_type>();
3674
    });
3675
    arr = std::move(ret);
3676
}
3677
3678
template<typename BasicJsonType, typename ConstructibleArrayType>
3679
void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3680
                          priority_tag<0> /*unused*/)
3681
{
3682
    using std::end;
3683
3684
    ConstructibleArrayType ret;
3685
    std::transform(
3686
        j.begin(), j.end(), std::inserter(ret, end(ret)),
3687
        [](const BasicJsonType & i)
3688
    {
3689
        // get<BasicJsonType>() returns *this, this won't call a from_json
3690
        // method when value_type is BasicJsonType
3691
        return i.template get<typename ConstructibleArrayType::value_type>();
3692
    });
3693
    arr = std::move(ret);
3694
}
3695
3696
template < typename BasicJsonType, typename ConstructibleArrayType,
3697
           enable_if_t <
3698
               is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
3699
               !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
3700
               !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3701
               !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
3702
               !is_basic_json<ConstructibleArrayType>::value,
3703
               int > = 0 >
3704
auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3705
-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3706
j.template get<typename ConstructibleArrayType::value_type>(),
3707
void())
3708
{
3709
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3710
    {
3711
        JSON_THROW(type_error::create(302, "type must be array, but is " +
3712
                                      std::string(j.type_name())));
3713
    }
3714
3715
    from_json_array_impl(j, arr, priority_tag<3> {});
3716
}
3717
3718
template<typename BasicJsonType>
3719
void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3720
{
3721
    if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
3722
    {
3723
        JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3724
    }
3725
3726
    bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3727
}
3728
3729
template<typename BasicJsonType, typename ConstructibleObjectType,
3730
         enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3731
void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3732
{
3733
    if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
3734
    {
3735
        JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3736
    }
3737
3738
    ConstructibleObjectType ret;
3739
    auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3740
    using value_type = typename ConstructibleObjectType::value_type;
3741
    std::transform(
3742
        inner_object->begin(), inner_object->end(),
3743
        std::inserter(ret, ret.begin()),
3744
        [](typename BasicJsonType::object_t::value_type const & p)
3745
    {
3746
        return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3747
    });
3748
    obj = std::move(ret);
3749
}
3750
3751
// overload for arithmetic types, not chosen for basic_json template arguments
3752
// (BooleanType, etc..); note: Is it really necessary to provide explicit
3753
// overloads for boolean_t etc. in case of a custom BooleanType which is not
3754
// an arithmetic type?
3755
template < typename BasicJsonType, typename ArithmeticType,
3756
           enable_if_t <
3757
               std::is_arithmetic<ArithmeticType>::value&&
3758
               !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
3759
               !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
3760
               !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
3761
               !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3762
               int > = 0 >
3763
void from_json(const BasicJsonType& j, ArithmeticType& val)
3764
0
{
3765
0
    switch (static_cast<value_t>(j))
3766
0
    {
3767
0
        case value_t::number_unsigned:
3768
0
        {
3769
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3770
0
            break;
3771
0
        }
3772
0
        case value_t::number_integer:
3773
0
        {
3774
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3775
0
            break;
3776
0
        }
3777
0
        case value_t::number_float:
3778
0
        {
3779
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3780
0
            break;
3781
0
        }
3782
0
        case value_t::boolean:
3783
0
        {
3784
0
            val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3785
0
            break;
3786
0
        }
3787
3788
0
        default:
3789
0
            JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3790
0
    }
3791
0
}
Unexecuted instantiation: void nlohmann::detail::from_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> > >, unsigned 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> > > const&, unsigned int&)
Unexecuted instantiation: void nlohmann::detail::from_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> > >, unsigned 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> > > const&, unsigned char&)
Unexecuted instantiation: void nlohmann::detail::from_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> > >, unsigned short, 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 short&)
3792
3793
template<typename BasicJsonType, typename A1, typename A2>
3794
void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3795
{
3796
    p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3797
}
3798
3799
template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3800
void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3801
{
3802
    t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3803
}
3804
3805
template<typename BasicJsonType, typename... Args>
3806
void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3807
{
3808
    from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3809
}
3810
3811
template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3812
           typename = enable_if_t < !std::is_constructible <
3813
                                        typename BasicJsonType::string_t, Key >::value >>
3814
void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3815
{
3816
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3817
    {
3818
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3819
    }
3820
    m.clear();
3821
    for (const auto& p : j)
3822
    {
3823
        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3824
        {
3825
            JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3826
        }
3827
        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3828
    }
3829
}
3830
3831
template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3832
           typename = enable_if_t < !std::is_constructible <
3833
                                        typename BasicJsonType::string_t, Key >::value >>
3834
void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3835
{
3836
    if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3837
    {
3838
        JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3839
    }
3840
    m.clear();
3841
    for (const auto& p : j)
3842
    {
3843
        if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3844
        {
3845
            JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3846
        }
3847
        m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3848
    }
3849
}
3850
3851
struct from_json_fn
3852
{
3853
    template<typename BasicJsonType, typename T>
3854
    auto operator()(const BasicJsonType& j, T& val) const
3855
    noexcept(noexcept(from_json(j, val)))
3856
    -> decltype(from_json(j, val), void())
3857
0
    {
3858
0
        return from_json(j, val);
3859
0
    }
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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> > > const&, bool&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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> > > const&, long&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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> > > const&, unsigned long&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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> > > const&, double&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, unsigned 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> > > const&, unsigned int&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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> > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, std::__1::basic_string_view<char, std::__1::char_traits<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> > > const&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, 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> > > const&, unsigned char&) const
Unexecuted instantiation: decltype ((from_json({parm#1}, {parm#2})),((void)())) nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >, unsigned short>(nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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 short&) const
3860
};
3861
}  // namespace detail
3862
3863
/// namespace to hold default `from_json` function
3864
/// to see why this is required:
3865
/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
3866
namespace
3867
{
3868
constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3869
} // namespace
3870
} // namespace nlohmann
3871
3872
// #include <nlohmann/detail/conversions/to_json.hpp>
3873
3874
3875
#include <algorithm> // copy
3876
#include <iterator> // begin, end
3877
#include <string> // string
3878
#include <tuple> // tuple, get
3879
#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3880
#include <utility> // move, forward, declval, pair
3881
#include <valarray> // valarray
3882
#include <vector> // vector
3883
3884
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3885
3886
3887
#include <cstddef> // size_t
3888
#include <iterator> // input_iterator_tag
3889
#include <string> // string, to_string
3890
#include <tuple> // tuple_size, get, tuple_element
3891
3892
// #include <nlohmann/detail/meta/type_traits.hpp>
3893
3894
// #include <nlohmann/detail/value_t.hpp>
3895
3896
3897
namespace nlohmann
3898
{
3899
namespace detail
3900
{
3901
template<typename string_type>
3902
void int_to_string( string_type& target, std::size_t value )
3903
0
{
3904
0
    // For ADL
3905
0
    using std::to_string;
3906
0
    target = to_string(value);
3907
0
}
3908
template<typename IteratorType> class iteration_proxy_value
3909
{
3910
  public:
3911
    using difference_type = std::ptrdiff_t;
3912
    using value_type = iteration_proxy_value;
3913
    using pointer = value_type * ;
3914
    using reference = value_type & ;
3915
    using iterator_category = std::input_iterator_tag;
3916
    using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3917
3918
  private:
3919
    /// the iterator
3920
    IteratorType anchor;
3921
    /// an index for arrays (used to create key names)
3922
    std::size_t array_index = 0;
3923
    /// last stringified array index
3924
    mutable std::size_t array_index_last = 0;
3925
    /// a string representation of the array index
3926
    mutable string_type array_index_str = "0";
3927
    /// an empty string (to return a reference for primitive values)
3928
    const string_type empty_str = "";
3929
3930
  public:
3931
    explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3932
3933
    /// dereference operator (needed for range-based for)
3934
    iteration_proxy_value& operator*()
3935
0
    {
3936
0
        return *this;
3937
0
    }
3938
3939
    /// increment operator (needed for range-based for)
3940
    iteration_proxy_value& operator++()
3941
0
    {
3942
0
        ++anchor;
3943
0
        ++array_index;
3944
0
3945
0
        return *this;
3946
0
    }
3947
3948
    /// equality operator (needed for InputIterator)
3949
    bool operator==(const iteration_proxy_value& o) const
3950
    {
3951
        return anchor == o.anchor;
3952
    }
3953
3954
    /// inequality operator (needed for range-based for)
3955
    bool operator!=(const iteration_proxy_value& o) const
3956
0
    {
3957
0
        return anchor != o.anchor;
3958
0
    }
3959
3960
    /// return key of the iterator
3961
    const string_type& key() const
3962
0
    {
3963
0
        JSON_ASSERT(anchor.m_object != nullptr);
3964
0
3965
0
        switch (anchor.m_object->type())
3966
0
        {
3967
0
            // use integer array index as key
3968
0
            case value_t::array:
3969
0
            {
3970
0
                if (array_index != array_index_last)
3971
0
                {
3972
0
                    int_to_string( array_index_str, array_index );
3973
0
                    array_index_last = array_index;
3974
0
                }
3975
0
                return array_index_str;
3976
0
            }
3977
0
3978
0
            // use key from the object
3979
0
            case value_t::object:
3980
0
                return anchor.key();
3981
0
3982
0
            // use an empty key for all primitive types
3983
0
            default:
3984
0
                return empty_str;
3985
0
        }
3986
0
    }
3987
3988
    /// return value of the iterator
3989
    typename IteratorType::reference value() const
3990
0
    {
3991
0
        return anchor.value();
3992
0
    }
3993
};
3994
3995
/// proxy class for the items() function
3996
template<typename IteratorType> class iteration_proxy
3997
{
3998
  private:
3999
    /// the container to iterate
4000
    typename IteratorType::reference container;
4001
4002
  public:
4003
    /// construct iteration proxy from a container
4004
    explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4005
        : container(cont) {}
4006
4007
    /// return iterator begin (needed for range-based for)
4008
    iteration_proxy_value<IteratorType> begin() noexcept
4009
0
    {
4010
0
        return iteration_proxy_value<IteratorType>(container.begin());
4011
0
    }
4012
4013
    /// return iterator end (needed for range-based for)
4014
    iteration_proxy_value<IteratorType> end() noexcept
4015
0
    {
4016
0
        return iteration_proxy_value<IteratorType>(container.end());
4017
0
    }
4018
};
4019
// Structured Bindings Support
4020
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4021
// And see https://github.com/nlohmann/json/pull/1391
4022
template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4023
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4024
{
4025
    return i.key();
4026
}
4027
// Structured Bindings Support
4028
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4029
// And see https://github.com/nlohmann/json/pull/1391
4030
template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4031
auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4032
{
4033
    return i.value();
4034
}
4035
}  // namespace detail
4036
}  // namespace nlohmann
4037
4038
// The Addition to the STD Namespace is required to add
4039
// Structured Bindings Support to the iteration_proxy_value class
4040
// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4041
// And see https://github.com/nlohmann/json/pull/1391
4042
namespace std
4043
{
4044
#if defined(__clang__)
4045
    // Fix: https://github.com/nlohmann/json/issues/1401
4046
    #pragma clang diagnostic push
4047
    #pragma clang diagnostic ignored "-Wmismatched-tags"
4048
#endif
4049
template<typename IteratorType>
4050
class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4051
            : public std::integral_constant<std::size_t, 2> {};
4052
4053
template<std::size_t N, typename IteratorType>
4054
class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4055
{
4056
  public:
4057
    using type = decltype(
4058
                     get<N>(std::declval <
4059
                            ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4060
};
4061
#if defined(__clang__)
4062
    #pragma clang diagnostic pop
4063
#endif
4064
} // namespace std
4065
4066
// #include <nlohmann/detail/meta/cpp_future.hpp>
4067
4068
// #include <nlohmann/detail/meta/type_traits.hpp>
4069
4070
// #include <nlohmann/detail/value_t.hpp>
4071
4072
4073
namespace nlohmann
4074
{
4075
namespace detail
4076
{
4077
//////////////////
4078
// constructors //
4079
//////////////////
4080
4081
template<value_t> struct external_constructor;
4082
4083
template<>
4084
struct external_constructor<value_t::boolean>
4085
{
4086
    template<typename BasicJsonType>
4087
    static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4088
0
    {
4089
0
        j.m_type = value_t::boolean;
4090
0
        j.m_value = b;
4091
0
        j.assert_invariant();
4092
0
    }
4093
};
4094
4095
template<>
4096
struct external_constructor<value_t::string>
4097
{
4098
    template<typename BasicJsonType>
4099
    static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4100
0
    {
4101
0
        j.m_type = value_t::string;
4102
0
        j.m_value = s;
4103
0
        j.assert_invariant();
4104
0
    }
4105
4106
    template<typename BasicJsonType>
4107
    static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4108
0
    {
4109
0
        j.m_type = value_t::string;
4110
0
        j.m_value = std::move(s);
4111
0
        j.assert_invariant();
4112
0
    }
4113
4114
    template < typename BasicJsonType, typename CompatibleStringType,
4115
               enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4116
                             int > = 0 >
4117
    static void construct(BasicJsonType& j, const CompatibleStringType& str)
4118
    {
4119
        j.m_type = value_t::string;
4120
        j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4121
        j.assert_invariant();
4122
    }
4123
};
4124
4125
template<>
4126
struct external_constructor<value_t::binary>
4127
{
4128
    template<typename BasicJsonType>
4129
    static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4130
    {
4131
        j.m_type = value_t::binary;
4132
        typename BasicJsonType::binary_t value{b};
4133
        j.m_value = value;
4134
        j.assert_invariant();
4135
    }
4136
4137
    template<typename BasicJsonType>
4138
    static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4139
    {
4140
        j.m_type = value_t::binary;
4141
        typename BasicJsonType::binary_t value{std::move(b)};
4142
        j.m_value = value;
4143
        j.assert_invariant();
4144
    }
4145
};
4146
4147
template<>
4148
struct external_constructor<value_t::number_float>
4149
{
4150
    template<typename BasicJsonType>
4151
    static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4152
0
    {
4153
0
        j.m_type = value_t::number_float;
4154
0
        j.m_value = val;
4155
0
        j.assert_invariant();
4156
0
    }
4157
};
4158
4159
template<>
4160
struct external_constructor<value_t::number_unsigned>
4161
{
4162
    template<typename BasicJsonType>
4163
    static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4164
0
    {
4165
0
        j.m_type = value_t::number_unsigned;
4166
0
        j.m_value = val;
4167
0
        j.assert_invariant();
4168
0
    }
4169
};
4170
4171
template<>
4172
struct external_constructor<value_t::number_integer>
4173
{
4174
    template<typename BasicJsonType>
4175
    static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4176
0
    {
4177
0
        j.m_type = value_t::number_integer;
4178
0
        j.m_value = val;
4179
0
        j.assert_invariant();
4180
0
    }
4181
};
4182
4183
template<>
4184
struct external_constructor<value_t::array>
4185
{
4186
    template<typename BasicJsonType>
4187
    static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4188
    {
4189
        j.m_type = value_t::array;
4190
        j.m_value = arr;
4191
        j.assert_invariant();
4192
    }
4193
4194
    template<typename BasicJsonType>
4195
    static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4196
    {
4197
        j.m_type = value_t::array;
4198
        j.m_value = std::move(arr);
4199
        j.assert_invariant();
4200
    }
4201
4202
    template < typename BasicJsonType, typename CompatibleArrayType,
4203
               enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4204
                             int > = 0 >
4205
    static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4206
    {
4207
        using std::begin;
4208
        using std::end;
4209
        j.m_type = value_t::array;
4210
        j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4211
        j.assert_invariant();
4212
    }
4213
4214
    template<typename BasicJsonType>
4215
    static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4216
    {
4217
        j.m_type = value_t::array;
4218
        j.m_value = value_t::array;
4219
        j.m_value.array->reserve(arr.size());
4220
        for (const bool x : arr)
4221
        {
4222
            j.m_value.array->push_back(x);
4223
        }
4224
        j.assert_invariant();
4225
    }
4226
4227
    template<typename BasicJsonType, typename T,
4228
             enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4229
    static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4230
    {
4231
        j.m_type = value_t::array;
4232
        j.m_value = value_t::array;
4233
        j.m_value.array->resize(arr.size());
4234
        if (arr.size() > 0)
4235
        {
4236
            std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4237
        }
4238
        j.assert_invariant();
4239
    }
4240
};
4241
4242
template<>
4243
struct external_constructor<value_t::object>
4244
{
4245
    template<typename BasicJsonType>
4246
    static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4247
    {
4248
        j.m_type = value_t::object;
4249
        j.m_value = obj;
4250
        j.assert_invariant();
4251
    }
4252
4253
    template<typename BasicJsonType>
4254
    static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4255
    {
4256
        j.m_type = value_t::object;
4257
        j.m_value = std::move(obj);
4258
        j.assert_invariant();
4259
    }
4260
4261
    template < typename BasicJsonType, typename CompatibleObjectType,
4262
               enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4263
    static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4264
    {
4265
        using std::begin;
4266
        using std::end;
4267
4268
        j.m_type = value_t::object;
4269
        j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4270
        j.assert_invariant();
4271
    }
4272
};
4273
4274
/////////////
4275
// to_json //
4276
/////////////
4277
4278
template<typename BasicJsonType, typename T,
4279
         enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4280
void to_json(BasicJsonType& j, T b) noexcept
4281
0
{
4282
0
    external_constructor<value_t::boolean>::construct(j, b);
4283
0
}
4284
4285
template<typename BasicJsonType, typename CompatibleString,
4286
         enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4287
void to_json(BasicJsonType& j, const CompatibleString& s)
4288
0
{
4289
0
    external_constructor<value_t::string>::construct(j, s);
4290
0
}
4291
4292
template<typename BasicJsonType>
4293
void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4294
0
{
4295
0
    external_constructor<value_t::string>::construct(j, std::move(s));
4296
0
}
4297
4298
template<typename BasicJsonType, typename FloatType,
4299
         enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4300
void to_json(BasicJsonType& j, FloatType val) noexcept
4301
0
{
4302
0
    external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4303
0
}
4304
4305
template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4306
         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4307
void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4308
0
{
4309
0
    external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4310
0
}
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> > >, 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> > >&, unsigned long)
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> > >, unsigned short, 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> > >&, unsigned short)
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> > >, unsigned 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> > >&, unsigned int)
4311
4312
template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4313
         enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4314
void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4315
0
{
4316
0
    external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4317
0
}
4318
4319
template<typename BasicJsonType, typename EnumType,
4320
         enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4321
void to_json(BasicJsonType& j, EnumType e) noexcept
4322
0
{
4323
0
    using underlying_type = typename std::underlying_type<EnumType>::type;
4324
0
    external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4325
0
}
4326
4327
template<typename BasicJsonType>
4328
void to_json(BasicJsonType& j, const std::vector<bool>& e)
4329
{
4330
    external_constructor<value_t::array>::construct(j, e);
4331
}
4332
4333
template < typename BasicJsonType, typename CompatibleArrayType,
4334
           enable_if_t < is_compatible_array_type<BasicJsonType,
4335
                         CompatibleArrayType>::value&&
4336
                         !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4337
                         !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4338
                         !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4339
                         !is_basic_json<CompatibleArrayType>::value,
4340
                         int > = 0 >
4341
void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4342
{
4343
    external_constructor<value_t::array>::construct(j, arr);
4344
}
4345
4346
template<typename BasicJsonType>
4347
void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4348
{
4349
    external_constructor<value_t::binary>::construct(j, bin);
4350
}
4351
4352
template<typename BasicJsonType, typename T,
4353
         enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4354
void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4355
{
4356
    external_constructor<value_t::array>::construct(j, std::move(arr));
4357
}
4358
4359
template<typename BasicJsonType>
4360
void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4361
{
4362
    external_constructor<value_t::array>::construct(j, std::move(arr));
4363
}
4364
4365
template < typename BasicJsonType, typename CompatibleObjectType,
4366
           enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4367
void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4368
{
4369
    external_constructor<value_t::object>::construct(j, obj);
4370
}
4371
4372
template<typename BasicJsonType>
4373
void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4374
{
4375
    external_constructor<value_t::object>::construct(j, std::move(obj));
4376
}
4377
4378
template <
4379
    typename BasicJsonType, typename T, std::size_t N,
4380
    enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4381
                  const T(&)[N]>::value,
4382
                  int > = 0 >
4383
void to_json(BasicJsonType& j, const T(&arr)[N])
4384
{
4385
    external_constructor<value_t::array>::construct(j, arr);
4386
}
4387
4388
template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4389
void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4390
{
4391
    j = { p.first, p.second };
4392
}
4393
4394
// for https://github.com/nlohmann/json/pull/1134
4395
template<typename BasicJsonType, typename T,
4396
         enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4397
void to_json(BasicJsonType& j, const T& b)
4398
{
4399
    j = { {b.key(), b.value()} };
4400
}
4401
4402
template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4403
void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4404
{
4405
    j = { std::get<Idx>(t)... };
4406
}
4407
4408
template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4409
void to_json(BasicJsonType& j, const T& t)
4410
{
4411
    to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4412
}
4413
4414
struct to_json_fn
4415
{
4416
    template<typename BasicJsonType, typename T>
4417
    auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4418
    -> decltype(to_json(j, std::forward<T>(val)), void())
4419
0
    {
4420
0
        return to_json(j, std::forward<T>(val));
4421
0
    }
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERSC_EEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERdEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERbEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERlEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERmEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
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_IhEEEEEESC_EEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSH_
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_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERKN8eprosima8fastrtps4rtps12ChangeKind_tEEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSN_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERKtEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEERKjEEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZNK8nlohmann6detail10to_json_fnclINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_NS_14adl_serializerENS6_IhNSA_IhEEEEEEKSC_EEDTcmcl7to_jsonfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
4422
};
4423
}  // namespace detail
4424
4425
/// namespace to hold default `to_json` function
4426
namespace
4427
{
4428
constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4429
} // namespace
4430
} // namespace nlohmann
4431
4432
4433
namespace nlohmann
4434
{
4435
4436
template<typename, typename>
4437
struct adl_serializer
4438
{
4439
    /*!
4440
    @brief convert a JSON value to any value type
4441
4442
    This function is usually called by the `get()` function of the
4443
    @ref basic_json class (either explicit or via conversion operators).
4444
4445
    @param[in] j        JSON value to read from
4446
    @param[in,out] val  value to write to
4447
    */
4448
    template<typename BasicJsonType, typename ValueType>
4449
    static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4450
        noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4451
    -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4452
0
    {
4453
0
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4454
0
    }
Unexecuted instantiation: _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_
Unexecuted instantiation: _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_
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_
Unexecuted instantiation: _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_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIjvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEEjEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSJ_RT0_
Unexecuted instantiation: _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_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerINSt3__117basic_string_viewIcNS1_11char_traitsIcEEEEvE9from_jsonIRKNS_10basic_jsonINS1_3mapENS1_6vectorENS1_12basic_stringIcS4_NS1_9allocatorIcEEEEblmdSC_S0_NSA_IhNSC_IhEEEEEES5_EEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSL_RT0_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIhvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEEhEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSJ_RT0_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerItvE9from_jsonIRKNS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEEtEEDTcmclL_ZNS_12_GLOBAL__N_19from_jsonEEclsr3stdE7forwardIT_Efp_Efp0_Ecvv_EEOSJ_RT0_
4455
4456
    /*!
4457
    @brief convert any value type to a JSON value
4458
4459
    This function is usually called by the constructors of the @ref basic_json
4460
    class.
4461
4462
    @param[in,out] j  JSON value to write to
4463
    @param[in] val    value to read from
4464
    */
4465
    template<typename BasicJsonType, typename ValueType>
4466
    static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4467
        noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4468
    -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4469
0
    {
4470
0
        ::nlohmann::to_json(j, std::forward<ValueType>(val));
4471
0
    }
Unexecuted instantiation: _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_
Unexecuted instantiation: _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_
Unexecuted instantiation: _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_
Unexecuted instantiation: _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_
Unexecuted instantiation: _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_
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_IhEEEEEES7_EEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSH_
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_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIN8eprosima8fastrtps4rtps12ChangeKind_tEvE7to_jsonINS_10basic_jsonINSt3__13mapENS8_6vectorENS8_12basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEblmdSE_S0_NSA_IhNSE_IhEEEEEERKS4_EEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSN_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerItvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERKtEEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSJ_
Unexecuted instantiation: _ZN8nlohmann14adl_serializerIjvE7to_jsonINS_10basic_jsonINSt3__13mapENS4_6vectorENS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEblmdSA_S0_NS6_IhNSA_IhEEEEEERKjEEDTcmclL_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_IhEEEEEEKS7_EEDTcmclL_ZNS_12_GLOBAL__N_17to_jsonEEfp_clsr3stdE7forwardIT0_Efp0_EEcvv_EERT_OSI_
4472
};
4473
4474
}  // namespace nlohmann
4475
4476
// #include <nlohmann/byte_container_with_subtype.hpp>
4477
4478
4479
#include <cstdint> // uint8_t
4480
#include <tuple> // tie
4481
#include <utility> // move
4482
4483
namespace nlohmann
4484
{
4485
4486
/*!
4487
@brief an internal type for a backed binary type
4488
4489
This type extends the template parameter @a BinaryType provided to `basic_json`
4490
with a subtype used by BSON and MessagePack. This type exists so that the user
4491
does not have to specify a type themselves with a specific naming scheme in
4492
order to override the binary type.
4493
4494
@tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
4495
                   default)
4496
4497
@since version 3.8.0
4498
*/
4499
template<typename BinaryType>
4500
class byte_container_with_subtype : public BinaryType
4501
{
4502
  public:
4503
    /// the type of the underlying container
4504
    using container_type = BinaryType;
4505
4506
    byte_container_with_subtype() noexcept(noexcept(container_type()))
4507
        : container_type()
4508
0
    {}
4509
4510
    byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
4511
        : container_type(b)
4512
    {}
4513
4514
    byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4515
        : container_type(std::move(b))
4516
    {}
4517
4518
    byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4519
        : container_type(b)
4520
        , m_subtype(subtype)
4521
        , m_has_subtype(true)
4522
    {}
4523
4524
    byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4525
        : container_type(std::move(b))
4526
        , m_subtype(subtype)
4527
        , m_has_subtype(true)
4528
    {}
4529
4530
    bool operator==(const byte_container_with_subtype& rhs) const
4531
0
    {
4532
0
        return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4533
0
               std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4534
0
    }
4535
4536
    bool operator!=(const byte_container_with_subtype& rhs) const
4537
    {
4538
        return !(rhs == *this);
4539
    }
4540
4541
    /*!
4542
    @brief sets the binary subtype
4543
4544
    Sets the binary subtype of the value, also flags a binary JSON value as
4545
    having a subtype, which has implications for serialization.
4546
4547
    @complexity Constant.
4548
4549
    @exceptionsafety No-throw guarantee: this member function never throws
4550
    exceptions.
4551
4552
    @sa @ref subtype() -- return the binary subtype
4553
    @sa @ref clear_subtype() -- clears the binary subtype
4554
    @sa @ref has_subtype() -- returns whether or not the binary value has a
4555
    subtype
4556
4557
    @since version 3.8.0
4558
    */
4559
    void set_subtype(std::uint8_t subtype) noexcept
4560
    {
4561
        m_subtype = subtype;
4562
        m_has_subtype = true;
4563
    }
4564
4565
    /*!
4566
    @brief return the binary subtype
4567
4568
    Returns the numerical subtype of the value if it has a subtype. If it does
4569
    not have a subtype, this function will return size_t(-1) as a sentinel
4570
    value.
4571
4572
    @return the numerical subtype of the binary value
4573
4574
    @complexity Constant.
4575
4576
    @exceptionsafety No-throw guarantee: this member function never throws
4577
    exceptions.
4578
4579
    @sa @ref set_subtype() -- sets the binary subtype
4580
    @sa @ref clear_subtype() -- clears the binary subtype
4581
    @sa @ref has_subtype() -- returns whether or not the binary value has a
4582
    subtype
4583
4584
    @since version 3.8.0
4585
    */
4586
    constexpr std::uint8_t subtype() const noexcept
4587
0
    {
4588
0
        return m_subtype;
4589
0
    }
4590
4591
    /*!
4592
    @brief return whether the value has a subtype
4593
4594
    @return whether the value has a subtype
4595
4596
    @complexity Constant.
4597
4598
    @exceptionsafety No-throw guarantee: this member function never throws
4599
    exceptions.
4600
4601
    @sa @ref subtype() -- return the binary subtype
4602
    @sa @ref set_subtype() -- sets the binary subtype
4603
    @sa @ref clear_subtype() -- clears the binary subtype
4604
4605
    @since version 3.8.0
4606
    */
4607
    constexpr bool has_subtype() const noexcept
4608
0
    {
4609
0
        return m_has_subtype;
4610
0
    }
4611
4612
    /*!
4613
    @brief clears the binary subtype
4614
4615
    Clears the binary subtype and flags the value as not having a subtype, which
4616
    has implications for serialization; for instance MessagePack will prefer the
4617
    bin family over the ext family.
4618
4619
    @complexity Constant.
4620
4621
    @exceptionsafety No-throw guarantee: this member function never throws
4622
    exceptions.
4623
4624
    @sa @ref subtype() -- return the binary subtype
4625
    @sa @ref set_subtype() -- sets the binary subtype
4626
    @sa @ref has_subtype() -- returns whether or not the binary value has a
4627
    subtype
4628
4629
    @since version 3.8.0
4630
    */
4631
    void clear_subtype() noexcept
4632
    {
4633
        m_subtype = 0;
4634
        m_has_subtype = false;
4635
    }
4636
4637
  private:
4638
    std::uint8_t m_subtype = 0;
4639
    bool m_has_subtype = false;
4640
};
4641
4642
}  // namespace nlohmann
4643
4644
// #include <nlohmann/detail/conversions/from_json.hpp>
4645
4646
// #include <nlohmann/detail/conversions/to_json.hpp>
4647
4648
// #include <nlohmann/detail/exceptions.hpp>
4649
4650
// #include <nlohmann/detail/hash.hpp>
4651
4652
4653
#include <cstddef> // size_t, uint8_t
4654
#include <functional> // hash
4655
4656
namespace nlohmann
4657
{
4658
namespace detail
4659
{
4660
4661
// boost::hash_combine
4662
inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
4663
0
{
4664
0
    seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
4665
0
    return seed;
4666
0
}
4667
4668
/*!
4669
@brief hash a JSON value
4670
4671
The hash function tries to rely on std::hash where possible. Furthermore, the
4672
type of the JSON value is taken into account to have different hash values for
4673
null, 0, 0U, and false, etc.
4674
4675
@tparam BasicJsonType basic_json specialization
4676
@param j JSON value to hash
4677
@return hash value of j
4678
*/
4679
template<typename BasicJsonType>
4680
std::size_t hash(const BasicJsonType& j)
4681
0
{
4682
0
    using string_t = typename BasicJsonType::string_t;
4683
0
    using number_integer_t = typename BasicJsonType::number_integer_t;
4684
0
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4685
0
    using number_float_t = typename BasicJsonType::number_float_t;
4686
0
4687
0
    const auto type = static_cast<std::size_t>(j.type());
4688
0
    switch (j.type())
4689
0
    {
4690
0
        case BasicJsonType::value_t::null:
4691
0
        case BasicJsonType::value_t::discarded:
4692
0
        {
4693
0
            return combine(type, 0);
4694
0
        }
4695
0
4696
0
        case BasicJsonType::value_t::object:
4697
0
        {
4698
0
            auto seed = combine(type, j.size());
4699
0
            for (const auto& element : j.items())
4700
0
            {
4701
0
                const auto h = std::hash<string_t> {}(element.key());
4702
0
                seed = combine(seed, h);
4703
0
                seed = combine(seed, hash(element.value()));
4704
0
            }
4705
0
            return seed;
4706
0
        }
4707
0
4708
0
        case BasicJsonType::value_t::array:
4709
0
        {
4710
0
            auto seed = combine(type, j.size());
4711
0
            for (const auto& element : j)
4712
0
            {
4713
0
                seed = combine(seed, hash(element));
4714
0
            }
4715
0
            return seed;
4716
0
        }
4717
0
4718
0
        case BasicJsonType::value_t::string:
4719
0
        {
4720
0
            const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
4721
0
            return combine(type, h);
4722
0
        }
4723
0
4724
0
        case BasicJsonType::value_t::boolean:
4725
0
        {
4726
0
            const auto h = std::hash<bool> {}(j.template get<bool>());
4727
0
            return combine(type, h);
4728
0
        }
4729
0
4730
0
        case BasicJsonType::value_t::number_integer:
4731
0
        {
4732
0
            const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
4733
0
            return combine(type, h);
4734
0
        }
4735
0
4736
0
        case BasicJsonType::value_t::number_unsigned:
4737
0
        {
4738
0
            const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
4739
0
            return combine(type, h);
4740
0
        }
4741
0
4742
0
        case BasicJsonType::value_t::number_float:
4743
0
        {
4744
0
            const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
4745
0
            return combine(type, h);
4746
0
        }
4747
0
4748
0
        case BasicJsonType::value_t::binary:
4749
0
        {
4750
0
            auto seed = combine(type, j.get_binary().size());
4751
0
            const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
4752
0
            seed = combine(seed, h);
4753
0
            seed = combine(seed, j.get_binary().subtype());
4754
0
            for (const auto byte : j.get_binary())
4755
0
            {
4756
0
                seed = combine(seed, std::hash<std::uint8_t> {}(byte));
4757
0
            }
4758
0
            return seed;
4759
0
        }
4760
0
4761
0
        default:                   // LCOV_EXCL_LINE
4762
0
            JSON_ASSERT(false);    // LCOV_EXCL_LINE
4763
0
            return 0;              // LCOV_EXCL_LINE
4764
0
    }
4765
0
}
4766
4767
}  // namespace detail
4768
}  // namespace nlohmann
4769
4770
// #include <nlohmann/detail/input/binary_reader.hpp>
4771
4772
4773
#include <algorithm> // generate_n
4774
#include <array> // array
4775
#include <cmath> // ldexp
4776
#include <cstddef> // size_t
4777
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4778
#include <cstdio> // snprintf
4779
#include <cstring> // memcpy
4780
#include <iterator> // back_inserter
4781
#include <limits> // numeric_limits
4782
#include <string> // char_traits, string
4783
#include <utility> // make_pair, move
4784
4785
// #include <nlohmann/detail/exceptions.hpp>
4786
4787
// #include <nlohmann/detail/input/input_adapters.hpp>
4788
4789
4790
#include <array> // array
4791
#include <cstddef> // size_t
4792
#include <cstdio> //FILE *
4793
#include <cstring> // strlen
4794
#include <istream> // istream
4795
#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4796
#include <memory> // shared_ptr, make_shared, addressof
4797
#include <numeric> // accumulate
4798
#include <string> // string, char_traits
4799
#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4800
#include <utility> // pair, declval
4801
4802
// #include <nlohmann/detail/iterators/iterator_traits.hpp>
4803
4804
// #include <nlohmann/detail/macro_scope.hpp>
4805
4806
4807
namespace nlohmann
4808
{
4809
namespace detail
4810
{
4811
/// the supported input formats
4812
enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4813
4814
////////////////////
4815
// input adapters //
4816
////////////////////
4817
4818
/*!
4819
Input adapter for stdio file access. This adapter read only 1 byte and do not use any
4820
 buffer. This adapter is a very low level adapter.
4821
*/
4822
class file_input_adapter
4823
{
4824
  public:
4825
    using char_type = char;
4826
4827
    JSON_HEDLEY_NON_NULL(2)
4828
    explicit file_input_adapter(std::FILE* f) noexcept
4829
        : m_file(f)
4830
0
    {}
4831
4832
    // make class move-only
4833
    file_input_adapter(const file_input_adapter&) = delete;
4834
    file_input_adapter(file_input_adapter&&) = default;
4835
    file_input_adapter& operator=(const file_input_adapter&) = delete;
4836
    file_input_adapter& operator=(file_input_adapter&&) = delete;
4837
4838
    std::char_traits<char>::int_type get_character() noexcept
4839
0
    {
4840
0
        return std::fgetc(m_file);
4841
0
    }
4842
4843
  private:
4844
    /// the file pointer to read from
4845
    std::FILE* m_file;
4846
};
4847
4848
4849
/*!
4850
Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
4851
beginning of input. Does not support changing the underlying std::streambuf
4852
in mid-input. Maintains underlying std::istream and std::streambuf to support
4853
subsequent use of standard std::istream operations to process any input
4854
characters following those used in parsing the JSON input.  Clears the
4855
std::istream flags; any input errors (e.g., EOF) will be detected by the first
4856
subsequent call for input from the std::istream.
4857
*/
4858
class input_stream_adapter
4859
{
4860
  public:
4861
    using char_type = char;
4862
4863
    ~input_stream_adapter()
4864
0
    {
4865
        // clear stream flags; we use underlying streambuf I/O, do not
4866
        // maintain ifstream flags, except eof
4867
0
        if (is != nullptr)
4868
0
        {
4869
0
            is->clear(is->rdstate() & std::ios::eofbit);
4870
0
        }
4871
0
    }
4872
4873
    explicit input_stream_adapter(std::istream& i)
4874
        : is(&i), sb(i.rdbuf())
4875
0
    {}
4876
4877
    // delete because of pointer members
4878
    input_stream_adapter(const input_stream_adapter&) = delete;
4879
    input_stream_adapter& operator=(input_stream_adapter&) = delete;
4880
    input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4881
4882
    input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)
4883
0
    {
4884
0
        rhs.is = nullptr;
4885
0
        rhs.sb = nullptr;
4886
0
    }
4887
4888
    // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4889
    // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4890
    // end up as the same value, eg. 0xFFFFFFFF.
4891
    std::char_traits<char>::int_type get_character()
4892
0
    {
4893
0
        auto res = sb->sbumpc();
4894
        // set eof manually, as we don't use the istream interface.
4895
0
        if (JSON_HEDLEY_UNLIKELY(res == EOF))
4896
0
        {
4897
0
            is->clear(is->rdstate() | std::ios::eofbit);
4898
0
        }
4899
0
        return res;
4900
0
    }
4901
4902
  private:
4903
    /// the associated input stream
4904
    std::istream* is = nullptr;
4905
    std::streambuf* sb = nullptr;
4906
};
4907
4908
// General-purpose iterator-based adapter. It might not be as fast as
4909
// theoretically possible for some containers, but it is extremely versatile.
4910
template<typename IteratorType>
4911
class iterator_input_adapter
4912
{
4913
  public:
4914
    using char_type = typename std::iterator_traits<IteratorType>::value_type;
4915
4916
    iterator_input_adapter(IteratorType first, IteratorType last)
4917
        : current(std::move(first)), end(std::move(last)) {}
4918
4919
    typename std::char_traits<char_type>::int_type get_character()
4920
0
    {
4921
0
        if (JSON_HEDLEY_LIKELY(current != end))
4922
0
        {
4923
0
            auto result = std::char_traits<char_type>::to_int_type(*current);
4924
0
            std::advance(current, 1);
4925
0
            return result;
4926
0
        }
4927
0
        else
4928
0
        {
4929
0
            return std::char_traits<char_type>::eof();
4930
0
        }
4931
0
    }
4932
4933
  private:
4934
    IteratorType current;
4935
    IteratorType end;
4936
4937
    template<typename BaseInputAdapter, size_t T>
4938
    friend struct wide_string_input_helper;
4939
4940
    bool empty() const
4941
    {
4942
        return current == end;
4943
    }
4944
4945
};
4946
4947
4948
template<typename BaseInputAdapter, size_t T>
4949
struct wide_string_input_helper;
4950
4951
template<typename BaseInputAdapter>
4952
struct wide_string_input_helper<BaseInputAdapter, 4>
4953
{
4954
    // UTF-32
4955
    static void fill_buffer(BaseInputAdapter& input,
4956
                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4957
                            size_t& utf8_bytes_index,
4958
                            size_t& utf8_bytes_filled)
4959
    {
4960
        utf8_bytes_index = 0;
4961
4962
        if (JSON_HEDLEY_UNLIKELY(input.empty()))
4963
        {
4964
            utf8_bytes[0] = std::char_traits<char>::eof();
4965
            utf8_bytes_filled = 1;
4966
        }
4967
        else
4968
        {
4969
            // get the current character
4970
            const auto wc = input.get_character();
4971
4972
            // UTF-32 to UTF-8 encoding
4973
            if (wc < 0x80)
4974
            {
4975
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4976
                utf8_bytes_filled = 1;
4977
            }
4978
            else if (wc <= 0x7FF)
4979
            {
4980
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4981
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4982
                utf8_bytes_filled = 2;
4983
            }
4984
            else if (wc <= 0xFFFF)
4985
            {
4986
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4987
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4988
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4989
                utf8_bytes_filled = 3;
4990
            }
4991
            else if (wc <= 0x10FFFF)
4992
            {
4993
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4994
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4995
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4996
                utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4997
                utf8_bytes_filled = 4;
4998
            }
4999
            else
5000
            {
5001
                // unknown character
5002
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5003
                utf8_bytes_filled = 1;
5004
            }
5005
        }
5006
    }
5007
};
5008
5009
template<typename BaseInputAdapter>
5010
struct wide_string_input_helper<BaseInputAdapter, 2>
5011
{
5012
    // UTF-16
5013
    static void fill_buffer(BaseInputAdapter& input,
5014
                            std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5015
                            size_t& utf8_bytes_index,
5016
                            size_t& utf8_bytes_filled)
5017
    {
5018
        utf8_bytes_index = 0;
5019
5020
        if (JSON_HEDLEY_UNLIKELY(input.empty()))
5021
        {
5022
            utf8_bytes[0] = std::char_traits<char>::eof();
5023
            utf8_bytes_filled = 1;
5024
        }
5025
        else
5026
        {
5027
            // get the current character
5028
            const auto wc = input.get_character();
5029
5030
            // UTF-16 to UTF-8 encoding
5031
            if (wc < 0x80)
5032
            {
5033
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5034
                utf8_bytes_filled = 1;
5035
            }
5036
            else if (wc <= 0x7FF)
5037
            {
5038
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5039
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5040
                utf8_bytes_filled = 2;
5041
            }
5042
            else if (0xD800 > wc || wc >= 0xE000)
5043
            {
5044
                utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5045
                utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5046
                utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5047
                utf8_bytes_filled = 3;
5048
            }
5049
            else
5050
            {
5051
                if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5052
                {
5053
                    const auto wc2 = static_cast<unsigned int>(input.get_character());
5054
                    const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5055
                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5056
                    utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5057
                    utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5058
                    utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5059
                    utf8_bytes_filled = 4;
5060
                }
5061
                else
5062
                {
5063
                    utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5064
                    utf8_bytes_filled = 1;
5065
                }
5066
            }
5067
        }
5068
    }
5069
};
5070
5071
// Wraps another input apdater to convert wide character types into individual bytes.
5072
template<typename BaseInputAdapter, typename WideCharType>
5073
class wide_string_input_adapter
5074
{
5075
  public:
5076
    using char_type = char;
5077
5078
    wide_string_input_adapter(BaseInputAdapter base)
5079
        : base_adapter(base) {}
5080
5081
    typename std::char_traits<char>::int_type get_character() noexcept
5082
    {
5083
        // check if buffer needs to be filled
5084
        if (utf8_bytes_index == utf8_bytes_filled)
5085
        {
5086
            fill_buffer<sizeof(WideCharType)>();
5087
5088
            JSON_ASSERT(utf8_bytes_filled > 0);
5089
            JSON_ASSERT(utf8_bytes_index == 0);
5090
        }
5091
5092
        // use buffer
5093
        JSON_ASSERT(utf8_bytes_filled > 0);
5094
        JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5095
        return utf8_bytes[utf8_bytes_index++];
5096
    }
5097
5098
  private:
5099
    BaseInputAdapter base_adapter;
5100
5101
    template<size_t T>
5102
    void fill_buffer()
5103
    {
5104
        wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5105
    }
5106
5107
    /// a buffer for UTF-8 bytes
5108
    std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5109
5110
    /// index to the utf8_codes array for the next valid byte
5111
    std::size_t utf8_bytes_index = 0;
5112
    /// number of valid bytes in the utf8_codes array
5113
    std::size_t utf8_bytes_filled = 0;
5114
};
5115
5116
5117
template<typename IteratorType, typename Enable = void>
5118
struct iterator_input_adapter_factory
5119
{
5120
    using iterator_type = IteratorType;
5121
    using char_type = typename std::iterator_traits<iterator_type>::value_type;
5122
    using adapter_type = iterator_input_adapter<iterator_type>;
5123
5124
    static adapter_type create(IteratorType first, IteratorType last)
5125
0
    {
5126
0
        return adapter_type(std::move(first), std::move(last));
5127
0
    }
5128
};
5129
5130
template<typename T>
5131
struct is_iterator_of_multibyte
5132
{
5133
    using value_type = typename std::iterator_traits<T>::value_type;
5134
    enum
5135
    {
5136
        value = sizeof(value_type) > 1
5137
    };
5138
};
5139
5140
template<typename IteratorType>
5141
struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5142
{
5143
    using iterator_type = IteratorType;
5144
    using char_type = typename std::iterator_traits<iterator_type>::value_type;
5145
    using base_adapter_type = iterator_input_adapter<iterator_type>;
5146
    using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5147
5148
    static adapter_type create(IteratorType first, IteratorType last)
5149
    {
5150
        return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5151
    }
5152
};
5153
5154
// General purpose iterator-based input
5155
template<typename IteratorType>
5156
typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5157
0
{
5158
0
    using factory_type = iterator_input_adapter_factory<IteratorType>;
5159
0
    return factory_type::create(first, last);
5160
0
}
5161
5162
// Convenience shorthand from container to iterator
5163
template<typename ContainerType>
5164
auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
5165
{
5166
    // Enable ADL
5167
    using std::begin;
5168
    using std::end;
5169
5170
    return input_adapter(begin(container), end(container));
5171
}
5172
5173
// Special cases with fast paths
5174
inline file_input_adapter input_adapter(std::FILE* file)
5175
0
{
5176
0
    return file_input_adapter(file);
5177
0
}
5178
5179
inline input_stream_adapter input_adapter(std::istream& stream)
5180
0
{
5181
0
    return input_stream_adapter(stream);
5182
0
}
5183
5184
inline input_stream_adapter input_adapter(std::istream&& stream)
5185
0
{
5186
0
    return input_stream_adapter(stream);
5187
0
}
5188
5189
using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5190
5191
// Null-delimited strings, and the like.
5192
template < typename CharT,
5193
           typename std::enable_if <
5194
               std::is_pointer<CharT>::value&&
5195
               !std::is_array<CharT>::value&&
5196
               std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5197
               sizeof(typename std::remove_pointer<CharT>::type) == 1,
5198
               int >::type = 0 >
5199
contiguous_bytes_input_adapter input_adapter(CharT b)
5200
{
5201
    auto length = std::strlen(reinterpret_cast<const char*>(b));
5202
    const auto* ptr = reinterpret_cast<const char*>(b);
5203
    return input_adapter(ptr, ptr + length);
5204
}
5205
5206
template<typename T, std::size_t N>
5207
auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
5208
{
5209
    return input_adapter(array, array + N);
5210
}
5211
5212
// This class only handles inputs of input_buffer_adapter type.
5213
// It's required so that expressions like {ptr, len} can be implicitely casted
5214
// to the correct adapter.
5215
class span_input_adapter
5216
{
5217
  public:
5218
    template < typename CharT,
5219
               typename std::enable_if <
5220
                   std::is_pointer<CharT>::value&&
5221
                   std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5222
                   sizeof(typename std::remove_pointer<CharT>::type) == 1,
5223
                   int >::type = 0 >
5224
    span_input_adapter(CharT b, std::size_t l)
5225
        : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5226
5227
    template<class IteratorType,
5228
             typename std::enable_if<
5229
                 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5230
                 int>::type = 0>
5231
    span_input_adapter(IteratorType first, IteratorType last)
5232
        : ia(input_adapter(first, last)) {}
5233
5234
    contiguous_bytes_input_adapter&& get()
5235
0
    {
5236
0
        return std::move(ia);
5237
0
    }
5238
5239
  private:
5240
    contiguous_bytes_input_adapter ia;
5241
};
5242
}  // namespace detail
5243
}  // namespace nlohmann
5244
5245
// #include <nlohmann/detail/input/json_sax.hpp>
5246
5247
5248
#include <cstddef>
5249
#include <string> // string
5250
#include <utility> // move
5251
#include <vector> // vector
5252
5253
// #include <nlohmann/detail/exceptions.hpp>
5254
5255
// #include <nlohmann/detail/macro_scope.hpp>
5256
5257
5258
namespace nlohmann
5259
{
5260
5261
/*!
5262
@brief SAX interface
5263
5264
This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
5265
Each function is called in different situations while the input is parsed. The
5266
boolean return value informs the parser whether to continue processing the
5267
input.
5268
*/
5269
template<typename BasicJsonType>
5270
struct json_sax
5271
{
5272
    using number_integer_t = typename BasicJsonType::number_integer_t;
5273
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5274
    using number_float_t = typename BasicJsonType::number_float_t;
5275
    using string_t = typename BasicJsonType::string_t;
5276
    using binary_t = typename BasicJsonType::binary_t;
5277
5278
    /*!
5279
    @brief a null value was read
5280
    @return whether parsing should proceed
5281
    */
5282
    virtual bool null() = 0;
5283
5284
    /*!
5285
    @brief a boolean value was read
5286
    @param[in] val  boolean value
5287
    @return whether parsing should proceed
5288
    */
5289
    virtual bool boolean(bool val) = 0;
5290
5291
    /*!
5292
    @brief an integer number was read
5293
    @param[in] val  integer value
5294
    @return whether parsing should proceed
5295
    */
5296
    virtual bool number_integer(number_integer_t val) = 0;
5297
5298
    /*!
5299
    @brief an unsigned integer number was read
5300
    @param[in] val  unsigned integer value
5301
    @return whether parsing should proceed
5302
    */
5303
    virtual bool number_unsigned(number_unsigned_t val) = 0;
5304
5305
    /*!
5306
    @brief an floating-point number was read
5307
    @param[in] val  floating-point value
5308
    @param[in] s    raw token value
5309
    @return whether parsing should proceed
5310
    */
5311
    virtual bool number_float(number_float_t val, const string_t& s) = 0;
5312
5313
    /*!
5314
    @brief a string was read
5315
    @param[in] val  string value
5316
    @return whether parsing should proceed
5317
    @note It is safe to move the passed string.
5318
    */
5319
    virtual bool string(string_t& val) = 0;
5320
5321
    /*!
5322
    @brief a binary string was read
5323
    @param[in] val  binary value
5324
    @return whether parsing should proceed
5325
    @note It is safe to move the passed binary.
5326
    */
5327
    virtual bool binary(binary_t& val) = 0;
5328
5329
    /*!
5330
    @brief the beginning of an object was read
5331
    @param[in] elements  number of object elements or -1 if unknown
5332
    @return whether parsing should proceed
5333
    @note binary formats may report the number of elements
5334
    */
5335
    virtual bool start_object(std::size_t elements) = 0;
5336
5337
    /*!
5338
    @brief an object key was read
5339
    @param[in] val  object key
5340
    @return whether parsing should proceed
5341
    @note It is safe to move the passed string.
5342
    */
5343
    virtual bool key(string_t& val) = 0;
5344
5345
    /*!
5346
    @brief the end of an object was read
5347
    @return whether parsing should proceed
5348
    */
5349
    virtual bool end_object() = 0;
5350
5351
    /*!
5352
    @brief the beginning of an array was read
5353
    @param[in] elements  number of array elements or -1 if unknown
5354
    @return whether parsing should proceed
5355
    @note binary formats may report the number of elements
5356
    */
5357
    virtual bool start_array(std::size_t elements) = 0;
5358
5359
    /*!
5360
    @brief the end of an array was read
5361
    @return whether parsing should proceed
5362
    */
5363
    virtual bool end_array() = 0;
5364
5365
    /*!
5366
    @brief a parse error occurred
5367
    @param[in] position    the position in the input where the error occurs
5368
    @param[in] last_token  the last read token
5369
    @param[in] ex          an exception object describing the error
5370
    @return whether parsing should proceed (must return false)
5371
    */
5372
    virtual bool parse_error(std::size_t position,
5373
                             const std::string& last_token,
5374
                             const detail::exception& ex) = 0;
5375
5376
    virtual ~json_sax() = default;
5377
};
5378
5379
5380
namespace detail
5381
{
5382
/*!
5383
@brief SAX implementation to create a JSON value from SAX events
5384
5385
This class implements the @ref json_sax interface and processes the SAX events
5386
to create a JSON value which makes it basically a DOM parser. The structure or
5387
hierarchy of the JSON value is managed by the stack `ref_stack` which contains
5388
a pointer to the respective array or object for each recursion depth.
5389
5390
After successful parsing, the value that is passed by reference to the
5391
constructor contains the parsed value.
5392
5393
@tparam BasicJsonType  the JSON type
5394
*/
5395
template<typename BasicJsonType>
5396
class json_sax_dom_parser
5397
{
5398
  public:
5399
    using number_integer_t = typename BasicJsonType::number_integer_t;
5400
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5401
    using number_float_t = typename BasicJsonType::number_float_t;
5402
    using string_t = typename BasicJsonType::string_t;
5403
    using binary_t = typename BasicJsonType::binary_t;
5404
5405
    /*!
5406
    @param[in, out] r  reference to a JSON value that is manipulated while
5407
                       parsing
5408
    @param[in] allow_exceptions_  whether parse errors yield exceptions
5409
    */
5410
    explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5411
        : root(r), allow_exceptions(allow_exceptions_)
5412
0
    {}
5413
5414
    // make class move-only
5415
    json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5416
    json_sax_dom_parser(json_sax_dom_parser&&) = default;
5417
    json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5418
    json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5419
0
    ~json_sax_dom_parser() = default;
5420
5421
    bool null()
5422
0
    {
5423
0
        handle_value(nullptr);
5424
0
        return true;
5425
0
    }
5426
5427
    bool boolean(bool val)
5428
0
    {
5429
0
        handle_value(val);
5430
0
        return true;
5431
0
    }
5432
5433
    bool number_integer(number_integer_t val)
5434
0
    {
5435
0
        handle_value(val);
5436
0
        return true;
5437
0
    }
5438
5439
    bool number_unsigned(number_unsigned_t val)
5440
0
    {
5441
0
        handle_value(val);
5442
0
        return true;
5443
0
    }
5444
5445
    bool number_float(number_float_t val, const string_t& /*unused*/)
5446
0
    {
5447
0
        handle_value(val);
5448
0
        return true;
5449
0
    }
5450
5451
    bool string(string_t& val)
5452
0
    {
5453
0
        handle_value(val);
5454
0
        return true;
5455
0
    }
5456
5457
    bool binary(binary_t& val)
5458
    {
5459
        handle_value(std::move(val));
5460
        return true;
5461
    }
5462
5463
    bool start_object(std::size_t len)
5464
0
    {
5465
0
        ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5466
5467
0
        if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5468
0
        {
5469
0
            JSON_THROW(out_of_range::create(408,
5470
0
                                            "excessive object size: " + std::to_string(len)));
5471
0
        }
5472
5473
0
        return true;
5474
0
    }
5475
5476
    bool key(string_t& val)
5477
0
    {
5478
        // add null at given key and store the reference for later
5479
0
        object_element = &(ref_stack.back()->m_value.object->operator[](val));
5480
0
        return true;
5481
0
    }
5482
5483
    bool end_object()
5484
0
    {
5485
0
        ref_stack.pop_back();
5486
0
        return true;
5487
0
    }
5488
5489
    bool start_array(std::size_t len)
5490
0
    {
5491
0
        ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5492
5493
0
        if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5494
0
        {
5495
0
            JSON_THROW(out_of_range::create(408,
5496
0
                                            "excessive array size: " + std::to_string(len)));
5497
0
        }
5498
5499
0
        return true;
5500
0
    }
5501
5502
    bool end_array()
5503
0
    {
5504
0
        ref_stack.pop_back();
5505
0
        return true;
5506
0
    }
5507
5508
    template<class Exception>
5509
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5510
                     const Exception& ex)
5511
0
    {
5512
0
        errored = true;
5513
0
        static_cast<void>(ex);
5514
0
        if (allow_exceptions)
5515
0
        {
5516
0
            JSON_THROW(ex);
5517
0
        }
5518
0
        return false;
5519
0
    }
Unexecuted instantiation: 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&)
Unexecuted instantiation: 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&)
5520
5521
    constexpr bool is_errored() const
5522
0
    {
5523
0
        return errored;
5524
0
    }
5525
5526
  private:
5527
    /*!
5528
    @invariant If the ref stack is empty, then the passed value will be the new
5529
               root.
5530
    @invariant If the ref stack contains a value, then it is an array or an
5531
               object to which we can add elements
5532
    */
5533
    template<typename Value>
5534
    JSON_HEDLEY_RETURNS_NON_NULL
5535
    BasicJsonType* handle_value(Value&& v)
5536
0
    {
5537
0
        if (ref_stack.empty())
5538
0
        {
5539
0
            root = BasicJsonType(std::forward<Value>(v));
5540
0
            return &root;
5541
0
        }
5542
5543
0
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5544
5545
0
        if (ref_stack.back()->is_array())
5546
0
        {
5547
0
            ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5548
0
            return &(ref_stack.back()->m_value.array->back());
5549
0
        }
5550
5551
0
        JSON_ASSERT(ref_stack.back()->is_object());
5552
0
        JSON_ASSERT(object_element);
5553
0
        *object_element = BasicJsonType(std::forward<Value>(v));
5554
0
        return object_element;
5555
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> > >* 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&&)
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> > >* 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&)
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> > >* 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&)
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> > >* 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)&&)
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> > >* 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&)
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> > >* 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> >&)
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> > >* 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&)
5556
5557
    /// the parsed JSON value
5558
    BasicJsonType& root;
5559
    /// stack to model hierarchy of values
5560
    std::vector<BasicJsonType*> ref_stack {};
5561
    /// helper to hold the reference for the next object element
5562
    BasicJsonType* object_element = nullptr;
5563
    /// whether a syntax error occurred
5564
    bool errored = false;
5565
    /// whether to throw exceptions in case of errors
5566
    const bool allow_exceptions = true;
5567
};
5568
5569
template<typename BasicJsonType>
5570
class json_sax_dom_callback_parser
5571
{
5572
  public:
5573
    using number_integer_t = typename BasicJsonType::number_integer_t;
5574
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5575
    using number_float_t = typename BasicJsonType::number_float_t;
5576
    using string_t = typename BasicJsonType::string_t;
5577
    using binary_t = typename BasicJsonType::binary_t;
5578
    using parser_callback_t = typename BasicJsonType::parser_callback_t;
5579
    using parse_event_t = typename BasicJsonType::parse_event_t;
5580
5581
    json_sax_dom_callback_parser(BasicJsonType& r,
5582
                                 const parser_callback_t cb,
5583
                                 const bool allow_exceptions_ = true)
5584
        : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5585
0
    {
5586
0
        keep_stack.push_back(true);
5587
0
    }
5588
5589
    // make class move-only
5590
    json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5591
    json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5592
    json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5593
    json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5594
0
    ~json_sax_dom_callback_parser() = default;
5595
5596
    bool null()
5597
0
    {
5598
0
        handle_value(nullptr);
5599
0
        return true;
5600
0
    }
5601
5602
    bool boolean(bool val)
5603
0
    {
5604
0
        handle_value(val);
5605
0
        return true;
5606
0
    }
5607
5608
    bool number_integer(number_integer_t val)
5609
0
    {
5610
0
        handle_value(val);
5611
0
        return true;
5612
0
    }
5613
5614
    bool number_unsigned(number_unsigned_t val)
5615
0
    {
5616
0
        handle_value(val);
5617
0
        return true;
5618
0
    }
5619
5620
    bool number_float(number_float_t val, const string_t& /*unused*/)
5621
0
    {
5622
0
        handle_value(val);
5623
0
        return true;
5624
0
    }
5625
5626
    bool string(string_t& val)
5627
0
    {
5628
0
        handle_value(val);
5629
0
        return true;
5630
0
    }
5631
5632
    bool binary(binary_t& val)
5633
    {
5634
        handle_value(std::move(val));
5635
        return true;
5636
    }
5637
5638
    bool start_object(std::size_t len)
5639
0
    {
5640
        // check callback for object start
5641
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5642
0
        keep_stack.push_back(keep);
5643
5644
0
        auto val = handle_value(BasicJsonType::value_t::object, true);
5645
0
        ref_stack.push_back(val.second);
5646
5647
        // check object limit
5648
0
        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5649
0
        {
5650
0
            JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5651
0
        }
5652
5653
0
        return true;
5654
0
    }
5655
5656
    bool key(string_t& val)
5657
0
    {
5658
0
        BasicJsonType k = BasicJsonType(val);
5659
5660
        // check callback for key
5661
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5662
0
        key_keep_stack.push_back(keep);
5663
5664
        // add discarded value at given key and store the reference for later
5665
0
        if (keep && ref_stack.back())
5666
0
        {
5667
0
            object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5668
0
        }
5669
5670
0
        return true;
5671
0
    }
5672
5673
    bool end_object()
5674
0
    {
5675
0
        if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5676
0
        {
5677
            // discard object
5678
0
            *ref_stack.back() = discarded;
5679
0
        }
5680
5681
0
        JSON_ASSERT(!ref_stack.empty());
5682
0
        JSON_ASSERT(!keep_stack.empty());
5683
0
        ref_stack.pop_back();
5684
0
        keep_stack.pop_back();
5685
5686
0
        if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
5687
0
        {
5688
            // remove discarded value
5689
0
            for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5690
0
            {
5691
0
                if (it->is_discarded())
5692
0
                {
5693
0
                    ref_stack.back()->erase(it);
5694
0
                    break;
5695
0
                }
5696
0
            }
5697
0
        }
5698
5699
0
        return true;
5700
0
    }
5701
5702
    bool start_array(std::size_t len)
5703
0
    {
5704
0
        const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5705
0
        keep_stack.push_back(keep);
5706
5707
0
        auto val = handle_value(BasicJsonType::value_t::array, true);
5708
0
        ref_stack.push_back(val.second);
5709
5710
        // check array limit
5711
0
        if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5712
0
        {
5713
0
            JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5714
0
        }
5715
5716
0
        return true;
5717
0
    }
5718
5719
    bool end_array()
5720
0
    {
5721
0
        bool keep = true;
5722
5723
0
        if (ref_stack.back())
5724
0
        {
5725
0
            keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5726
0
            if (!keep)
5727
0
            {
5728
                // discard array
5729
0
                *ref_stack.back() = discarded;
5730
0
            }
5731
0
        }
5732
5733
0
        JSON_ASSERT(!ref_stack.empty());
5734
0
        JSON_ASSERT(!keep_stack.empty());
5735
0
        ref_stack.pop_back();
5736
0
        keep_stack.pop_back();
5737
5738
        // remove discarded value
5739
0
        if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
5740
0
        {
5741
0
            ref_stack.back()->m_value.array->pop_back();
5742
0
        }
5743
5744
0
        return true;
5745
0
    }
5746
5747
    template<class Exception>
5748
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5749
                     const Exception& ex)
5750
0
    {
5751
0
        errored = true;
5752
0
        static_cast<void>(ex);
5753
0
        if (allow_exceptions)
5754
0
        {
5755
0
            JSON_THROW(ex);
5756
0
        }
5757
0
        return false;
5758
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&)
5759
5760
    constexpr bool is_errored() const
5761
0
    {
5762
0
        return errored;
5763
0
    }
5764
5765
  private:
5766
    /*!
5767
    @param[in] v  value to add to the JSON value we build during parsing
5768
    @param[in] skip_callback  whether we should skip calling the callback
5769
               function; this is required after start_array() and
5770
               start_object() SAX events, because otherwise we would call the
5771
               callback function with an empty array or object, respectively.
5772
5773
    @invariant If the ref stack is empty, then the passed value will be the new
5774
               root.
5775
    @invariant If the ref stack contains a value, then it is an array or an
5776
               object to which we can add elements
5777
5778
    @return pair of boolean (whether value should be kept) and pointer (to the
5779
            passed value in the ref_stack hierarchy; nullptr if not kept)
5780
    */
5781
    template<typename Value>
5782
    std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5783
0
    {
5784
0
        JSON_ASSERT(!keep_stack.empty());
5785
5786
        // do not handle this value if we know it would be added to a discarded
5787
        // container
5788
0
        if (!keep_stack.back())
5789
0
        {
5790
0
            return {false, nullptr};
5791
0
        }
5792
5793
        // create value
5794
0
        auto value = BasicJsonType(std::forward<Value>(v));
5795
5796
        // check callback
5797
0
        const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5798
5799
        // do not handle this value if we just learnt it shall be discarded
5800
0
        if (!keep)
5801
0
        {
5802
0
            return {false, nullptr};
5803
0
        }
5804
5805
0
        if (ref_stack.empty())
5806
0
        {
5807
0
            root = std::move(value);
5808
0
            return {true, &root};
5809
0
        }
5810
5811
        // skip this value if we already decided to skip the parent
5812
        // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5813
0
        if (!ref_stack.back())
5814
0
        {
5815
0
            return {false, nullptr};
5816
0
        }
5817
5818
        // we now only expect arrays and objects
5819
0
        JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5820
5821
        // array
5822
0
        if (ref_stack.back()->is_array())
5823
0
        {
5824
0
            ref_stack.back()->m_value.array->push_back(std::move(value));
5825
0
            return {true, &(ref_stack.back()->m_value.array->back())};
5826
0
        }
5827
5828
        // object
5829
0
        JSON_ASSERT(ref_stack.back()->is_object());
5830
        // check if we should store an element for the current key
5831
0
        JSON_ASSERT(!key_keep_stack.empty());
5832
0
        const bool store_element = key_keep_stack.back();
5833
0
        key_keep_stack.pop_back();
5834
5835
0
        if (!store_element)
5836
0
        {
5837
0
            return {false, nullptr};
5838
0
        }
5839
5840
0
        JSON_ASSERT(object_element);
5841
0
        *object_element = std::move(value);
5842
0
        return {true, object_element};
5843
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)
5844
5845
    /// the parsed JSON value
5846
    BasicJsonType& root;
5847
    /// stack to model hierarchy of values
5848
    std::vector<BasicJsonType*> ref_stack {};
5849
    /// stack to manage which values to keep
5850
    std::vector<bool> keep_stack {};
5851
    /// stack to manage which object keys to keep
5852
    std::vector<bool> key_keep_stack {};
5853
    /// helper to hold the reference for the next object element
5854
    BasicJsonType* object_element = nullptr;
5855
    /// whether a syntax error occurred
5856
    bool errored = false;
5857
    /// callback function
5858
    const parser_callback_t callback = nullptr;
5859
    /// whether to throw exceptions in case of errors
5860
    const bool allow_exceptions = true;
5861
    /// a discarded value for the callback
5862
    BasicJsonType discarded = BasicJsonType::value_t::discarded;
5863
};
5864
5865
template<typename BasicJsonType>
5866
class json_sax_acceptor
5867
{
5868
  public:
5869
    using number_integer_t = typename BasicJsonType::number_integer_t;
5870
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5871
    using number_float_t = typename BasicJsonType::number_float_t;
5872
    using string_t = typename BasicJsonType::string_t;
5873
    using binary_t = typename BasicJsonType::binary_t;
5874
5875
    bool null()
5876
    {
5877
        return true;
5878
    }
5879
5880
    bool boolean(bool /*unused*/)
5881
    {
5882
        return true;
5883
    }
5884
5885
    bool number_integer(number_integer_t /*unused*/)
5886
    {
5887
        return true;
5888
    }
5889
5890
    bool number_unsigned(number_unsigned_t /*unused*/)
5891
    {
5892
        return true;
5893
    }
5894
5895
    bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5896
    {
5897
        return true;
5898
    }
5899
5900
    bool string(string_t& /*unused*/)
5901
    {
5902
        return true;
5903
    }
5904
5905
    bool binary(binary_t& /*unused*/)
5906
    {
5907
        return true;
5908
    }
5909
5910
    bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5911
    {
5912
        return true;
5913
    }
5914
5915
    bool key(string_t& /*unused*/)
5916
    {
5917
        return true;
5918
    }
5919
5920
    bool end_object()
5921
    {
5922
        return true;
5923
    }
5924
5925
    bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5926
    {
5927
        return true;
5928
    }
5929
5930
    bool end_array()
5931
    {
5932
        return true;
5933
    }
5934
5935
    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5936
    {
5937
        return false;
5938
    }
5939
};
5940
}  // namespace detail
5941
5942
}  // namespace nlohmann
5943
5944
// #include <nlohmann/detail/input/lexer.hpp>
5945
5946
5947
#include <array> // array
5948
#include <clocale> // localeconv
5949
#include <cstddef> // size_t
5950
#include <cstdio> // snprintf
5951
#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5952
#include <initializer_list> // initializer_list
5953
#include <string> // char_traits, string
5954
#include <utility> // move
5955
#include <vector> // vector
5956
5957
// #include <nlohmann/detail/input/input_adapters.hpp>
5958
5959
// #include <nlohmann/detail/input/position_t.hpp>
5960
5961
// #include <nlohmann/detail/macro_scope.hpp>
5962
5963
5964
namespace nlohmann
5965
{
5966
namespace detail
5967
{
5968
///////////
5969
// lexer //
5970
///////////
5971
5972
template<typename BasicJsonType>
5973
class lexer_base
5974
{
5975
  public:
5976
    /// token types for the parser
5977
    enum class token_type
5978
    {
5979
        uninitialized,    ///< indicating the scanner is uninitialized
5980
        literal_true,     ///< the `true` literal
5981
        literal_false,    ///< the `false` literal
5982
        literal_null,     ///< the `null` literal
5983
        value_string,     ///< a string -- use get_string() for actual value
5984
        value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
5985
        value_integer,    ///< a signed integer -- use get_number_integer() for actual value
5986
        value_float,      ///< an floating point number -- use get_number_float() for actual value
5987
        begin_array,      ///< the character for array begin `[`
5988
        begin_object,     ///< the character for object begin `{`
5989
        end_array,        ///< the character for array end `]`
5990
        end_object,       ///< the character for object end `}`
5991
        name_separator,   ///< the name separator `:`
5992
        value_separator,  ///< the value separator `,`
5993
        parse_error,      ///< indicating a parse error
5994
        end_of_input,     ///< indicating the end of the input buffer
5995
        literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
5996
    };
5997
5998
    /// return name of values of type token_type (only used for errors)
5999
    JSON_HEDLEY_RETURNS_NON_NULL
6000
    JSON_HEDLEY_CONST
6001
    static const char* token_type_name(const token_type t) noexcept
6002
0
    {
6003
0
        switch (t)
6004
0
        {
6005
0
            case token_type::uninitialized:
6006
0
                return "<uninitialized>";
6007
0
            case token_type::literal_true:
6008
0
                return "true literal";
6009
0
            case token_type::literal_false:
6010
0
                return "false literal";
6011
0
            case token_type::literal_null:
6012
0
                return "null literal";
6013
0
            case token_type::value_string:
6014
0
                return "string literal";
6015
0
            case token_type::value_unsigned:
6016
0
            case token_type::value_integer:
6017
0
            case token_type::value_float:
6018
0
                return "number literal";
6019
0
            case token_type::begin_array:
6020
0
                return "'['";
6021
0
            case token_type::begin_object:
6022
0
                return "'{'";
6023
0
            case token_type::end_array:
6024
0
                return "']'";
6025
0
            case token_type::end_object:
6026
0
                return "'}'";
6027
0
            case token_type::name_separator:
6028
0
                return "':'";
6029
0
            case token_type::value_separator:
6030
0
                return "','";
6031
0
            case token_type::parse_error:
6032
0
                return "<parse error>";
6033
0
            case token_type::end_of_input:
6034
0
                return "end of input";
6035
0
            case token_type::literal_or_value:
6036
0
                return "'[', '{', or a literal";
6037
            // LCOV_EXCL_START
6038
0
            default: // catch non-enum values
6039
0
                return "unknown token";
6040
                // LCOV_EXCL_STOP
6041
0
        }
6042
0
    }
6043
};
6044
/*!
6045
@brief lexical analysis
6046
6047
This class organizes the lexical analysis during JSON deserialization.
6048
*/
6049
template<typename BasicJsonType, typename InputAdapterType>
6050
class lexer : public lexer_base<BasicJsonType>
6051
{
6052
    using number_integer_t = typename BasicJsonType::number_integer_t;
6053
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6054
    using number_float_t = typename BasicJsonType::number_float_t;
6055
    using string_t = typename BasicJsonType::string_t;
6056
    using char_type = typename InputAdapterType::char_type;
6057
    using char_int_type = typename std::char_traits<char_type>::int_type;
6058
6059
  public:
6060
    using token_type = typename lexer_base<BasicJsonType>::token_type;
6061
6062
    explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
6063
        : ia(std::move(adapter))
6064
        , ignore_comments(ignore_comments_)
6065
        , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6066
0
    {}
6067
6068
    // delete because of pointer members
6069
    lexer(const lexer&) = delete;
6070
    lexer(lexer&&) = default;
6071
    lexer& operator=(lexer&) = delete;
6072
    lexer& operator=(lexer&&) = default;
6073
0
    ~lexer() = default;
6074
6075
  private:
6076
    /////////////////////
6077
    // locales
6078
    /////////////////////
6079
6080
    /// return the locale-dependent decimal point
6081
    JSON_HEDLEY_PURE
6082
    static char get_decimal_point() noexcept
6083
0
    {
6084
0
        const auto* loc = localeconv();
6085
0
        JSON_ASSERT(loc != nullptr);
6086
0
        return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6087
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_decimal_point()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_decimal_point()
6088
6089
    /////////////////////
6090
    // scan functions
6091
    /////////////////////
6092
6093
    /*!
6094
    @brief get codepoint from 4 hex characters following `\u`
6095
6096
    For input "\u c1 c2 c3 c4" the codepoint is:
6097
      (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
6098
    = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
6099
6100
    Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
6101
    must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
6102
    conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
6103
    between the ASCII value of the character and the desired integer value.
6104
6105
    @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
6106
            non-hex character)
6107
    */
6108
    int get_codepoint()
6109
0
    {
6110
        // this function only makes sense after reading `\u`
6111
0
        JSON_ASSERT(current == 'u');
6112
0
        int codepoint = 0;
6113
6114
0
        const auto factors = { 12u, 8u, 4u, 0u };
6115
0
        for (const auto factor : factors)
6116
0
        {
6117
0
            get();
6118
6119
0
            if (current >= '0' && current <= '9')
6120
0
            {
6121
0
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6122
0
            }
6123
0
            else if (current >= 'A' && current <= 'F')
6124
0
            {
6125
0
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6126
0
            }
6127
0
            else if (current >= 'a' && current <= 'f')
6128
0
            {
6129
0
                codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6130
0
            }
6131
0
            else
6132
0
            {
6133
0
                return -1;
6134
0
            }
6135
0
        }
6136
6137
0
        JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6138
0
        return codepoint;
6139
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_codepoint()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_codepoint()
6140
6141
    /*!
6142
    @brief check if the next byte(s) are inside a given range
6143
6144
    Adds the current byte and, for each passed range, reads a new byte and
6145
    checks if it is inside the range. If a violation was detected, set up an
6146
    error message and return false. Otherwise, return true.
6147
6148
    @param[in] ranges  list of integers; interpreted as list of pairs of
6149
                       inclusive lower and upper bound, respectively
6150
6151
    @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
6152
         1, 2, or 3 pairs. This precondition is enforced by an assertion.
6153
6154
    @return true if and only if no range violation was detected
6155
    */
6156
    bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6157
0
    {
6158
0
        JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6159
0
        add(current);
6160
6161
0
        for (auto range = ranges.begin(); range != ranges.end(); ++range)
6162
0
        {
6163
0
            get();
6164
0
            if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6165
0
            {
6166
0
                add(current);
6167
0
            }
6168
0
            else
6169
0
            {
6170
0
                error_message = "invalid string: ill-formed UTF-8 byte";
6171
0
                return false;
6172
0
            }
6173
0
        }
6174
6175
0
        return true;
6176
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::next_byte_in_range(std::initializer_list<int>)
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::next_byte_in_range(std::initializer_list<int>)
6177
6178
    /*!
6179
    @brief scan a string literal
6180
6181
    This function scans a string according to Sect. 7 of RFC 7159. While
6182
    scanning, bytes are escaped and copied into buffer token_buffer. Then the
6183
    function returns successfully, token_buffer is *not* null-terminated (as it
6184
    may contain \0 bytes), and token_buffer.size() is the number of bytes in the
6185
    string.
6186
6187
    @return token_type::value_string if string could be successfully scanned,
6188
            token_type::parse_error otherwise
6189
6190
    @note In case of errors, variable error_message contains a textual
6191
          description.
6192
    */
6193
    token_type scan_string()
6194
0
    {
6195
        // reset token_buffer (ignore opening quote)
6196
0
        reset();
6197
6198
        // we entered the function by reading an open quote
6199
0
        JSON_ASSERT(current == '\"');
6200
6201
0
        while (true)
6202
0
        {
6203
            // get next character
6204
0
            switch (get())
6205
0
            {
6206
                // end of file while parsing string
6207
0
                case std::char_traits<char_type>::eof():
6208
0
                {
6209
0
                    error_message = "invalid string: missing closing quote";
6210
0
                    return token_type::parse_error;
6211
0
                }
6212
6213
                // closing quote
6214
0
                case '\"':
6215
0
                {
6216
0
                    return token_type::value_string;
6217
0
                }
6218
6219
                // escapes
6220
0
                case '\\':
6221
0
                {
6222
0
                    switch (get())
6223
0
                    {
6224
                        // quotation mark
6225
0
                        case '\"':
6226
0
                            add('\"');
6227
0
                            break;
6228
                        // reverse solidus
6229
0
                        case '\\':
6230
0
                            add('\\');
6231
0
                            break;
6232
                        // solidus
6233
0
                        case '/':
6234
0
                            add('/');
6235
0
                            break;
6236
                        // backspace
6237
0
                        case 'b':
6238
0
                            add('\b');
6239
0
                            break;
6240
                        // form feed
6241
0
                        case 'f':
6242
0
                            add('\f');
6243
0
                            break;
6244
                        // line feed
6245
0
                        case 'n':
6246
0
                            add('\n');
6247
0
                            break;
6248
                        // carriage return
6249
0
                        case 'r':
6250
0
                            add('\r');
6251
0
                            break;
6252
                        // tab
6253
0
                        case 't':
6254
0
                            add('\t');
6255
0
                            break;
6256
6257
                        // unicode escapes
6258
0
                        case 'u':
6259
0
                        {
6260
0
                            const int codepoint1 = get_codepoint();
6261
0
                            int codepoint = codepoint1; // start with codepoint1
6262
6263
0
                            if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6264
0
                            {
6265
0
                                error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6266
0
                                return token_type::parse_error;
6267
0
                            }
6268
6269
                            // check if code point is a high surrogate
6270
0
                            if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6271
0
                            {
6272
                                // expect next \uxxxx entry
6273
0
                                if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6274
0
                                {
6275
0
                                    const int codepoint2 = get_codepoint();
6276
6277
0
                                    if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6278
0
                                    {
6279
0
                                        error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6280
0
                                        return token_type::parse_error;
6281
0
                                    }
6282
6283
                                    // check if codepoint2 is a low surrogate
6284
0
                                    if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6285
0
                                    {
6286
                                        // overwrite codepoint
6287
0
                                        codepoint = static_cast<int>(
6288
                                                        // high surrogate occupies the most significant 22 bits
6289
0
                                                        (static_cast<unsigned int>(codepoint1) << 10u)
6290
                                                        // low surrogate occupies the least significant 15 bits
6291
0
                                                        + static_cast<unsigned int>(codepoint2)
6292
                                                        // there is still the 0xD800, 0xDC00 and 0x10000 noise
6293
                                                        // in the result so we have to subtract with:
6294
                                                        // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6295
0
                                                        - 0x35FDC00u);
6296
0
                                    }
6297
0
                                    else
6298
0
                                    {
6299
0
                                        error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6300
0
                                        return token_type::parse_error;
6301
0
                                    }
6302
0
                                }
6303
0
                                else
6304
0
                                {
6305
0
                                    error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6306
0
                                    return token_type::parse_error;
6307
0
                                }
6308
0
                            }
6309
0
                            else
6310
0
                            {
6311
0
                                if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6312
0
                                {
6313
0
                                    error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6314
0
                                    return token_type::parse_error;
6315
0
                                }
6316
0
                            }
6317
6318
                            // result of the above calculation yields a proper codepoint
6319
0
                            JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6320
6321
                            // translate codepoint into bytes
6322
0
                            if (codepoint < 0x80)
6323
0
                            {
6324
                                // 1-byte characters: 0xxxxxxx (ASCII)
6325
0
                                add(static_cast<char_int_type>(codepoint));
6326
0
                            }
6327
0
                            else if (codepoint <= 0x7FF)
6328
0
                            {
6329
                                // 2-byte characters: 110xxxxx 10xxxxxx
6330
0
                                add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6331
0
                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6332
0
                            }
6333
0
                            else if (codepoint <= 0xFFFF)
6334
0
                            {
6335
                                // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6336
0
                                add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6337
0
                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6338
0
                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6339
0
                            }
6340
0
                            else
6341
0
                            {
6342
                                // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6343
0
                                add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6344
0
                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6345
0
                                add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6346
0
                                add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6347
0
                            }
6348
6349
0
                            break;
6350
0
                        }
6351
6352
                        // other characters after escape
6353
0
                        default:
6354
0
                            error_message = "invalid string: forbidden character after backslash";
6355
0
                            return token_type::parse_error;
6356
0
                    }
6357
6358
0
                    break;
6359
0
                }
6360
6361
                // invalid control characters
6362
0
                case 0x00:
6363
0
                {
6364
0
                    error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6365
0
                    return token_type::parse_error;
6366
0
                }
6367
6368
0
                case 0x01:
6369
0
                {
6370
0
                    error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6371
0
                    return token_type::parse_error;
6372
0
                }
6373
6374
0
                case 0x02:
6375
0
                {
6376
0
                    error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6377
0
                    return token_type::parse_error;
6378
0
                }
6379
6380
0
                case 0x03:
6381
0
                {
6382
0
                    error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6383
0
                    return token_type::parse_error;
6384
0
                }
6385
6386
0
                case 0x04:
6387
0
                {
6388
0
                    error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6389
0
                    return token_type::parse_error;
6390
0
                }
6391
6392
0
                case 0x05:
6393
0
                {
6394
0
                    error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6395
0
                    return token_type::parse_error;
6396
0
                }
6397
6398
0
                case 0x06:
6399
0
                {
6400
0
                    error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6401
0
                    return token_type::parse_error;
6402
0
                }
6403
6404
0
                case 0x07:
6405
0
                {
6406
0
                    error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6407
0
                    return token_type::parse_error;
6408
0
                }
6409
6410
0
                case 0x08:
6411
0
                {
6412
0
                    error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6413
0
                    return token_type::parse_error;
6414
0
                }
6415
6416
0
                case 0x09:
6417
0
                {
6418
0
                    error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6419
0
                    return token_type::parse_error;
6420
0
                }
6421
6422
0
                case 0x0A:
6423
0
                {
6424
0
                    error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6425
0
                    return token_type::parse_error;
6426
0
                }
6427
6428
0
                case 0x0B:
6429
0
                {
6430
0
                    error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6431
0
                    return token_type::parse_error;
6432
0
                }
6433
6434
0
                case 0x0C:
6435
0
                {
6436
0
                    error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6437
0
                    return token_type::parse_error;
6438
0
                }
6439
6440
0
                case 0x0D:
6441
0
                {
6442
0
                    error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6443
0
                    return token_type::parse_error;
6444
0
                }
6445
6446
0
                case 0x0E:
6447
0
                {
6448
0
                    error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6449
0
                    return token_type::parse_error;
6450
0
                }
6451
6452
0
                case 0x0F:
6453
0
                {
6454
0
                    error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6455
0
                    return token_type::parse_error;
6456
0
                }
6457
6458
0
                case 0x10:
6459
0
                {
6460
0
                    error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6461
0
                    return token_type::parse_error;
6462
0
                }
6463
6464
0
                case 0x11:
6465
0
                {
6466
0
                    error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6467
0
                    return token_type::parse_error;
6468
0
                }
6469
6470
0
                case 0x12:
6471
0
                {
6472
0
                    error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6473
0
                    return token_type::parse_error;
6474
0
                }
6475
6476
0
                case 0x13:
6477
0
                {
6478
0
                    error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6479
0
                    return token_type::parse_error;
6480
0
                }
6481
6482
0
                case 0x14:
6483
0
                {
6484
0
                    error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6485
0
                    return token_type::parse_error;
6486
0
                }
6487
6488
0
                case 0x15:
6489
0
                {
6490
0
                    error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6491
0
                    return token_type::parse_error;
6492
0
                }
6493
6494
0
                case 0x16:
6495
0
                {
6496
0
                    error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6497
0
                    return token_type::parse_error;
6498
0
                }
6499
6500
0
                case 0x17:
6501
0
                {
6502
0
                    error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6503
0
                    return token_type::parse_error;
6504
0
                }
6505
6506
0
                case 0x18:
6507
0
                {
6508
0
                    error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6509
0
                    return token_type::parse_error;
6510
0
                }
6511
6512
0
                case 0x19:
6513
0
                {
6514
0
                    error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6515
0
                    return token_type::parse_error;
6516
0
                }
6517
6518
0
                case 0x1A:
6519
0
                {
6520
0
                    error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6521
0
                    return token_type::parse_error;
6522
0
                }
6523
6524
0
                case 0x1B:
6525
0
                {
6526
0
                    error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6527
0
                    return token_type::parse_error;
6528
0
                }
6529
6530
0
                case 0x1C:
6531
0
                {
6532
0
                    error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6533
0
                    return token_type::parse_error;
6534
0
                }
6535
6536
0
                case 0x1D:
6537
0
                {
6538
0
                    error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6539
0
                    return token_type::parse_error;
6540
0
                }
6541
6542
0
                case 0x1E:
6543
0
                {
6544
0
                    error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6545
0
                    return token_type::parse_error;
6546
0
                }
6547
6548
0
                case 0x1F:
6549
0
                {
6550
0
                    error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6551
0
                    return token_type::parse_error;
6552
0
                }
6553
6554
                // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6555
0
                case 0x20:
6556
0
                case 0x21:
6557
0
                case 0x23:
6558
0
                case 0x24:
6559
0
                case 0x25:
6560
0
                case 0x26:
6561
0
                case 0x27:
6562
0
                case 0x28:
6563
0
                case 0x29:
6564
0
                case 0x2A:
6565
0
                case 0x2B:
6566
0
                case 0x2C:
6567
0
                case 0x2D:
6568
0
                case 0x2E:
6569
0
                case 0x2F:
6570
0
                case 0x30:
6571
0
                case 0x31:
6572
0
                case 0x32:
6573
0
                case 0x33:
6574
0
                case 0x34:
6575
0
                case 0x35:
6576
0
                case 0x36:
6577
0
                case 0x37:
6578
0
                case 0x38:
6579
0
                case 0x39:
6580
0
                case 0x3A:
6581
0
                case 0x3B:
6582
0
                case 0x3C:
6583
0
                case 0x3D:
6584
0
                case 0x3E:
6585
0
                case 0x3F:
6586
0
                case 0x40:
6587
0
                case 0x41:
6588
0
                case 0x42:
6589
0
                case 0x43:
6590
0
                case 0x44:
6591
0
                case 0x45:
6592
0
                case 0x46:
6593
0
                case 0x47:
6594
0
                case 0x48:
6595
0
                case 0x49:
6596
0
                case 0x4A:
6597
0
                case 0x4B:
6598
0
                case 0x4C:
6599
0
                case 0x4D:
6600
0
                case 0x4E:
6601
0
                case 0x4F:
6602
0
                case 0x50:
6603
0
                case 0x51:
6604
0
                case 0x52:
6605
0
                case 0x53:
6606
0
                case 0x54:
6607
0
                case 0x55:
6608
0
                case 0x56:
6609
0
                case 0x57:
6610
0
                case 0x58:
6611
0
                case 0x59:
6612
0
                case 0x5A:
6613
0
                case 0x5B:
6614
0
                case 0x5D:
6615
0
                case 0x5E:
6616
0
                case 0x5F:
6617
0
                case 0x60:
6618
0
                case 0x61:
6619
0
                case 0x62:
6620
0
                case 0x63:
6621
0
                case 0x64:
6622
0
                case 0x65:
6623
0
                case 0x66:
6624
0
                case 0x67:
6625
0
                case 0x68:
6626
0
                case 0x69:
6627
0
                case 0x6A:
6628
0
                case 0x6B:
6629
0
                case 0x6C:
6630
0
                case 0x6D:
6631
0
                case 0x6E:
6632
0
                case 0x6F:
6633
0
                case 0x70:
6634
0
                case 0x71:
6635
0
                case 0x72:
6636
0
                case 0x73:
6637
0
                case 0x74:
6638
0
                case 0x75:
6639
0
                case 0x76:
6640
0
                case 0x77:
6641
0
                case 0x78:
6642
0
                case 0x79:
6643
0
                case 0x7A:
6644
0
                case 0x7B:
6645
0
                case 0x7C:
6646
0
                case 0x7D:
6647
0
                case 0x7E:
6648
0
                case 0x7F:
6649
0
                {
6650
0
                    add(current);
6651
0
                    break;
6652
0
                }
6653
6654
                // U+0080..U+07FF: bytes C2..DF 80..BF
6655
0
                case 0xC2:
6656
0
                case 0xC3:
6657
0
                case 0xC4:
6658
0
                case 0xC5:
6659
0
                case 0xC6:
6660
0
                case 0xC7:
6661
0
                case 0xC8:
6662
0
                case 0xC9:
6663
0
                case 0xCA:
6664
0
                case 0xCB:
6665
0
                case 0xCC:
6666
0
                case 0xCD:
6667
0
                case 0xCE:
6668
0
                case 0xCF:
6669
0
                case 0xD0:
6670
0
                case 0xD1:
6671
0
                case 0xD2:
6672
0
                case 0xD3:
6673
0
                case 0xD4:
6674
0
                case 0xD5:
6675
0
                case 0xD6:
6676
0
                case 0xD7:
6677
0
                case 0xD8:
6678
0
                case 0xD9:
6679
0
                case 0xDA:
6680
0
                case 0xDB:
6681
0
                case 0xDC:
6682
0
                case 0xDD:
6683
0
                case 0xDE:
6684
0
                case 0xDF:
6685
0
                {
6686
0
                    if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
6687
0
                    {
6688
0
                        return token_type::parse_error;
6689
0
                    }
6690
0
                    break;
6691
0
                }
6692
6693
                // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6694
0
                case 0xE0:
6695
0
                {
6696
0
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6697
0
                    {
6698
0
                        return token_type::parse_error;
6699
0
                    }
6700
0
                    break;
6701
0
                }
6702
6703
                // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6704
                // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6705
0
                case 0xE1:
6706
0
                case 0xE2:
6707
0
                case 0xE3:
6708
0
                case 0xE4:
6709
0
                case 0xE5:
6710
0
                case 0xE6:
6711
0
                case 0xE7:
6712
0
                case 0xE8:
6713
0
                case 0xE9:
6714
0
                case 0xEA:
6715
0
                case 0xEB:
6716
0
                case 0xEC:
6717
0
                case 0xEE:
6718
0
                case 0xEF:
6719
0
                {
6720
0
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6721
0
                    {
6722
0
                        return token_type::parse_error;
6723
0
                    }
6724
0
                    break;
6725
0
                }
6726
6727
                // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6728
0
                case 0xED:
6729
0
                {
6730
0
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6731
0
                    {
6732
0
                        return token_type::parse_error;
6733
0
                    }
6734
0
                    break;
6735
0
                }
6736
6737
                // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6738
0
                case 0xF0:
6739
0
                {
6740
0
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6741
0
                    {
6742
0
                        return token_type::parse_error;
6743
0
                    }
6744
0
                    break;
6745
0
                }
6746
6747
                // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6748
0
                case 0xF1:
6749
0
                case 0xF2:
6750
0
                case 0xF3:
6751
0
                {
6752
0
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6753
0
                    {
6754
0
                        return token_type::parse_error;
6755
0
                    }
6756
0
                    break;
6757
0
                }
6758
6759
                // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6760
0
                case 0xF4:
6761
0
                {
6762
0
                    if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6763
0
                    {
6764
0
                        return token_type::parse_error;
6765
0
                    }
6766
0
                    break;
6767
0
                }
6768
6769
                // remaining bytes (80..C1 and F5..FF) are ill-formed
6770
0
                default:
6771
0
                {
6772
0
                    error_message = "invalid string: ill-formed UTF-8 byte";
6773
0
                    return token_type::parse_error;
6774
0
                }
6775
0
            }
6776
0
        }
6777
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::scan_string()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::scan_string()
6778
6779
    /*!
6780
     * @brief scan a comment
6781
     * @return whether comment could be scanned successfully
6782
     */
6783
    bool scan_comment()
6784
0
    {
6785
0
        switch (get())
6786
0
        {
6787
            // single-line comments skip input until a newline or EOF is read
6788
0
            case '/':
6789
0
            {
6790
0
                while (true)
6791
0
                {
6792
0
                    switch (get())
6793
0
                    {
6794
0
                        case '\n':
6795
0
                        case '\r':
6796
0
                        case std::char_traits<char_type>::eof():
6797
0
                        case '\0':
6798
0
                            return true;
6799
6800
0
                        default:
6801
0
                            break;
6802
0
                    }
6803
0
                }
6804
0
            }
6805
6806
            // multi-line comments skip input until */ is read
6807
0
            case '*':
6808
0
            {
6809
0
                while (true)
6810
0
                {
6811
0
                    switch (get())
6812
0
                    {
6813
0
                        case std::char_traits<char_type>::eof():
6814
0
                        case '\0':
6815
0
                        {
6816
0
                            error_message = "invalid comment; missing closing '*/'";
6817
0
                            return false;
6818
0
                        }
6819
6820
0
                        case '*':
6821
0
                        {
6822
0
                            switch (get())
6823
0
                            {
6824
0
                                case '/':
6825
0
                                    return true;
6826
6827
0
                                default:
6828
0
                                {
6829
0
                                    unget();
6830
0
                                    continue;
6831
0
                                }
6832
0
                            }
6833
0
                        }
6834
6835
0
                        default:
6836
0
                            continue;
6837
0
                    }
6838
0
                }
6839
0
            }
6840
6841
            // unexpected character after reading '/'
6842
0
            default:
6843
0
            {
6844
0
                error_message = "invalid comment; expecting '/' or '*' after '/'";
6845
0
                return false;
6846
0
            }
6847
0
        }
6848
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::scan_comment()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::scan_comment()
6849
6850
    JSON_HEDLEY_NON_NULL(2)
6851
    static void strtof(float& f, const char* str, char** endptr) noexcept
6852
    {
6853
        f = std::strtof(str, endptr);
6854
    }
6855
6856
    JSON_HEDLEY_NON_NULL(2)
6857
    static void strtof(double& f, const char* str, char** endptr) noexcept
6858
0
    {
6859
0
        f = std::strtod(str, endptr);
6860
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::strtof(double&, char const*, char**)
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::strtof(double&, char const*, char**)
6861
6862
    JSON_HEDLEY_NON_NULL(2)
6863
    static void strtof(long double& f, const char* str, char** endptr) noexcept
6864
    {
6865
        f = std::strtold(str, endptr);
6866
    }
6867
6868
    /*!
6869
    @brief scan a number literal
6870
6871
    This function scans a string according to Sect. 6 of RFC 7159.
6872
6873
    The function is realized with a deterministic finite state machine derived
6874
    from the grammar described in RFC 7159. Starting in state "init", the
6875
    input is read and used to determined the next state. Only state "done"
6876
    accepts the number. State "error" is a trap state to model errors. In the
6877
    table below, "anything" means any character but the ones listed before.
6878
6879
    state    | 0        | 1-9      | e E      | +       | -       | .        | anything
6880
    ---------|----------|----------|----------|---------|---------|----------|-----------
6881
    init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
6882
    minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
6883
    zero     | done     | done     | exponent | done    | done    | decimal1 | done
6884
    any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
6885
    decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
6886
    decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
6887
    exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
6888
    sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
6889
    any2     | any2     | any2     | done     | done    | done    | done     | done
6890
6891
    The state machine is realized with one label per state (prefixed with
6892
    "scan_number_") and `goto` statements between them. The state machine
6893
    contains cycles, but any cycle can be left when EOF is read. Therefore,
6894
    the function is guaranteed to terminate.
6895
6896
    During scanning, the read bytes are stored in token_buffer. This string is
6897
    then converted to a signed integer, an unsigned integer, or a
6898
    floating-point number.
6899
6900
    @return token_type::value_unsigned, token_type::value_integer, or
6901
            token_type::value_float if number could be successfully scanned,
6902
            token_type::parse_error otherwise
6903
6904
    @note The scanner is independent of the current locale. Internally, the
6905
          locale's decimal point is used instead of `.` to work with the
6906
          locale-dependent converters.
6907
    */
6908
    token_type scan_number()  // lgtm [cpp/use-of-goto]
6909
0
    {
6910
        // reset token_buffer to store the number's bytes
6911
0
        reset();
6912
6913
        // the type of the parsed number; initially set to unsigned; will be
6914
        // changed if minus sign, decimal point or exponent is read
6915
0
        token_type number_type = token_type::value_unsigned;
6916
6917
        // state (init): we just found out we need to scan a number
6918
0
        switch (current)
6919
0
        {
6920
0
            case '-':
6921
0
            {
6922
0
                add(current);
6923
0
                goto scan_number_minus;
6924
0
            }
6925
6926
0
            case '0':
6927
0
            {
6928
0
                add(current);
6929
0
                goto scan_number_zero;
6930
0
            }
6931
6932
0
            case '1':
6933
0
            case '2':
6934
0
            case '3':
6935
0
            case '4':
6936
0
            case '5':
6937
0
            case '6':
6938
0
            case '7':
6939
0
            case '8':
6940
0
            case '9':
6941
0
            {
6942
0
                add(current);
6943
0
                goto scan_number_any1;
6944
0
            }
6945
6946
            // all other characters are rejected outside scan_number()
6947
0
            default:            // LCOV_EXCL_LINE
6948
0
                JSON_ASSERT(false);  // LCOV_EXCL_LINE
6949
0
        }
6950
6951
0
scan_number_minus:
6952
        // state: we just parsed a leading minus sign
6953
0
        number_type = token_type::value_integer;
6954
0
        switch (get())
6955
0
        {
6956
0
            case '0':
6957
0
            {
6958
0
                add(current);
6959
0
                goto scan_number_zero;
6960
0
            }
6961
6962
0
            case '1':
6963
0
            case '2':
6964
0
            case '3':
6965
0
            case '4':
6966
0
            case '5':
6967
0
            case '6':
6968
0
            case '7':
6969
0
            case '8':
6970
0
            case '9':
6971
0
            {
6972
0
                add(current);
6973
0
                goto scan_number_any1;
6974
0
            }
6975
6976
0
            default:
6977
0
            {
6978
0
                error_message = "invalid number; expected digit after '-'";
6979
0
                return token_type::parse_error;
6980
0
            }
6981
0
        }
6982
6983
0
scan_number_zero:
6984
        // state: we just parse a zero (maybe with a leading minus sign)
6985
0
        switch (get())
6986
0
        {
6987
0
            case '.':
6988
0
            {
6989
0
                add(decimal_point_char);
6990
0
                goto scan_number_decimal1;
6991
0
            }
6992
6993
0
            case 'e':
6994
0
            case 'E':
6995
0
            {
6996
0
                add(current);
6997
0
                goto scan_number_exponent;
6998
0
            }
6999
7000
0
            default:
7001
0
                goto scan_number_done;
7002
0
        }
7003
7004
0
scan_number_any1:
7005
        // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7006
0
        switch (get())
7007
0
        {
7008
0
            case '0':
7009
0
            case '1':
7010
0
            case '2':
7011
0
            case '3':
7012
0
            case '4':
7013
0
            case '5':
7014
0
            case '6':
7015
0
            case '7':
7016
0
            case '8':
7017
0
            case '9':
7018
0
            {
7019
0
                add(current);
7020
0
                goto scan_number_any1;
7021
0
            }
7022
7023
0
            case '.':
7024
0
            {
7025
0
                add(decimal_point_char);
7026
0
                goto scan_number_decimal1;
7027
0
            }
7028
7029
0
            case 'e':
7030
0
            case 'E':
7031
0
            {
7032
0
                add(current);
7033
0
                goto scan_number_exponent;
7034
0
            }
7035
7036
0
            default:
7037
0
                goto scan_number_done;
7038
0
        }
7039
7040
0
scan_number_decimal1:
7041
        // state: we just parsed a decimal point
7042
0
        number_type = token_type::value_float;
7043
0
        switch (get())
7044
0
        {
7045
0
            case '0':
7046
0
            case '1':
7047
0
            case '2':
7048
0
            case '3':
7049
0
            case '4':
7050
0
            case '5':
7051
0
            case '6':
7052
0
            case '7':
7053
0
            case '8':
7054
0
            case '9':
7055
0
            {
7056
0
                add(current);
7057
0
                goto scan_number_decimal2;
7058
0
            }
7059
7060
0
            default:
7061
0
            {
7062
0
                error_message = "invalid number; expected digit after '.'";
7063
0
                return token_type::parse_error;
7064
0
            }
7065
0
        }
7066
7067
0
scan_number_decimal2:
7068
        // we just parsed at least one number after a decimal point
7069
0
        switch (get())
7070
0
        {
7071
0
            case '0':
7072
0
            case '1':
7073
0
            case '2':
7074
0
            case '3':
7075
0
            case '4':
7076
0
            case '5':
7077
0
            case '6':
7078
0
            case '7':
7079
0
            case '8':
7080
0
            case '9':
7081
0
            {
7082
0
                add(current);
7083
0
                goto scan_number_decimal2;
7084
0
            }
7085
7086
0
            case 'e':
7087
0
            case 'E':
7088
0
            {
7089
0
                add(current);
7090
0
                goto scan_number_exponent;
7091
0
            }
7092
7093
0
            default:
7094
0
                goto scan_number_done;
7095
0
        }
7096
7097
0
scan_number_exponent:
7098
        // we just parsed an exponent
7099
0
        number_type = token_type::value_float;
7100
0
        switch (get())
7101
0
        {
7102
0
            case '+':
7103
0
            case '-':
7104
0
            {
7105
0
                add(current);
7106
0
                goto scan_number_sign;
7107
0
            }
7108
7109
0
            case '0':
7110
0
            case '1':
7111
0
            case '2':
7112
0
            case '3':
7113
0
            case '4':
7114
0
            case '5':
7115
0
            case '6':
7116
0
            case '7':
7117
0
            case '8':
7118
0
            case '9':
7119
0
            {
7120
0
                add(current);
7121
0
                goto scan_number_any2;
7122
0
            }
7123
7124
0
            default:
7125
0
            {
7126
0
                error_message =
7127
0
                    "invalid number; expected '+', '-', or digit after exponent";
7128
0
                return token_type::parse_error;
7129
0
            }
7130
0
        }
7131
7132
0
scan_number_sign:
7133
        // we just parsed an exponent sign
7134
0
        switch (get())
7135
0
        {
7136
0
            case '0':
7137
0
            case '1':
7138
0
            case '2':
7139
0
            case '3':
7140
0
            case '4':
7141
0
            case '5':
7142
0
            case '6':
7143
0
            case '7':
7144
0
            case '8':
7145
0
            case '9':
7146
0
            {
7147
0
                add(current);
7148
0
                goto scan_number_any2;
7149
0
            }
7150
7151
0
            default:
7152
0
            {
7153
0
                error_message = "invalid number; expected digit after exponent sign";
7154
0
                return token_type::parse_error;
7155
0
            }
7156
0
        }
7157
7158
0
scan_number_any2:
7159
        // we just parsed a number after the exponent or exponent sign
7160
0
        switch (get())
7161
0
        {
7162
0
            case '0':
7163
0
            case '1':
7164
0
            case '2':
7165
0
            case '3':
7166
0
            case '4':
7167
0
            case '5':
7168
0
            case '6':
7169
0
            case '7':
7170
0
            case '8':
7171
0
            case '9':
7172
0
            {
7173
0
                add(current);
7174
0
                goto scan_number_any2;
7175
0
            }
7176
7177
0
            default:
7178
0
                goto scan_number_done;
7179
0
        }
7180
7181
0
scan_number_done:
7182
        // unget the character after the number (we only read it to know that
7183
        // we are done scanning a number)
7184
0
        unget();
7185
7186
0
        char* endptr = nullptr;
7187
0
        errno = 0;
7188
7189
        // try to parse integers first and fall back to floats
7190
0
        if (number_type == token_type::value_unsigned)
7191
0
        {
7192
0
            const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7193
7194
            // we checked the number format before
7195
0
            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7196
7197
0
            if (errno == 0)
7198
0
            {
7199
0
                value_unsigned = static_cast<number_unsigned_t>(x);
7200
0
                if (value_unsigned == x)
7201
0
                {
7202
0
                    return token_type::value_unsigned;
7203
0
                }
7204
0
            }
7205
0
        }
7206
0
        else if (number_type == token_type::value_integer)
7207
0
        {
7208
0
            const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7209
7210
            // we checked the number format before
7211
0
            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7212
7213
0
            if (errno == 0)
7214
0
            {
7215
0
                value_integer = static_cast<number_integer_t>(x);
7216
0
                if (value_integer == x)
7217
0
                {
7218
0
                    return token_type::value_integer;
7219
0
                }
7220
0
            }
7221
0
        }
7222
7223
        // this code is reached if we parse a floating-point number or if an
7224
        // integer conversion above failed
7225
0
        strtof(value_float, token_buffer.data(), &endptr);
7226
7227
        // we checked the number format before
7228
0
        JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7229
7230
0
        return token_type::value_float;
7231
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::scan_number()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::scan_number()
7232
7233
    /*!
7234
    @param[in] literal_text  the literal text to expect
7235
    @param[in] length        the length of the passed literal text
7236
    @param[in] return_type   the token type to return on success
7237
    */
7238
    JSON_HEDLEY_NON_NULL(2)
7239
    token_type scan_literal(const char_type* literal_text, const std::size_t length,
7240
                            token_type return_type)
7241
0
    {
7242
0
        JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7243
0
        for (std::size_t i = 1; i < length; ++i)
7244
0
        {
7245
0
            if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7246
0
            {
7247
0
                error_message = "invalid literal";
7248
0
                return token_type::parse_error;
7249
0
            }
7250
0
        }
7251
0
        return return_type;
7252
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::scan_literal(char const*, unsigned long, nlohmann::detail::lexer_base<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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> > > >::token_type)
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::scan_literal(char const*, unsigned long, nlohmann::detail::lexer_base<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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> > > >::token_type)
7253
7254
    /////////////////////
7255
    // input management
7256
    /////////////////////
7257
7258
    /// reset token_buffer; current character is beginning of token
7259
    void reset() noexcept
7260
0
    {
7261
0
        token_buffer.clear();
7262
0
        token_string.clear();
7263
0
        token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7264
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::reset()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::reset()
7265
7266
    /*
7267
    @brief get next character from the input
7268
7269
    This function provides the interface to the used input adapter. It does
7270
    not throw in case the input reached EOF, but returns a
7271
    `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
7272
    for use in error messages.
7273
7274
    @return character read from the input
7275
    */
7276
    char_int_type get()
7277
0
    {
7278
0
        ++position.chars_read_total;
7279
0
        ++position.chars_read_current_line;
7280
7281
0
        if (next_unget)
7282
0
        {
7283
            // just reset the next_unget variable and work with current
7284
0
            next_unget = false;
7285
0
        }
7286
0
        else
7287
0
        {
7288
0
            current = ia.get_character();
7289
0
        }
7290
7291
0
        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7292
0
        {
7293
0
            token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7294
0
        }
7295
7296
0
        if (current == '\n')
7297
0
        {
7298
0
            ++position.lines_read;
7299
0
            position.chars_read_current_line = 0;
7300
0
        }
7301
7302
0
        return current;
7303
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get()
7304
7305
    /*!
7306
    @brief unget current character (read it again on next get)
7307
7308
    We implement unget by setting variable next_unget to true. The input is not
7309
    changed - we just simulate ungetting by modifying chars_read_total,
7310
    chars_read_current_line, and token_string. The next call to get() will
7311
    behave as if the unget character is read again.
7312
    */
7313
    void unget()
7314
0
    {
7315
0
        next_unget = true;
7316
7317
0
        --position.chars_read_total;
7318
7319
        // in case we "unget" a newline, we have to also decrement the lines_read
7320
0
        if (position.chars_read_current_line == 0)
7321
0
        {
7322
0
            if (position.lines_read > 0)
7323
0
            {
7324
0
                --position.lines_read;
7325
0
            }
7326
0
        }
7327
0
        else
7328
0
        {
7329
0
            --position.chars_read_current_line;
7330
0
        }
7331
7332
0
        if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7333
0
        {
7334
0
            JSON_ASSERT(!token_string.empty());
7335
0
            token_string.pop_back();
7336
0
        }
7337
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::unget()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::unget()
7338
7339
    /// add a character to token_buffer
7340
    void add(char_int_type c)
7341
0
    {
7342
0
        token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7343
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::add(int)
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::add(int)
7344
7345
  public:
7346
    /////////////////////
7347
    // value getters
7348
    /////////////////////
7349
7350
    /// return integer value
7351
    constexpr number_integer_t get_number_integer() const noexcept
7352
0
    {
7353
0
        return value_integer;
7354
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_number_integer() const
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_number_integer() const
7355
7356
    /// return unsigned integer value
7357
    constexpr number_unsigned_t get_number_unsigned() const noexcept
7358
0
    {
7359
0
        return value_unsigned;
7360
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_number_unsigned() const
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_number_unsigned() const
7361
7362
    /// return floating-point value
7363
    constexpr number_float_t get_number_float() const noexcept
7364
0
    {
7365
0
        return value_float;
7366
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_number_float() const
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_number_float() const
7367
7368
    /// return current string value (implicitly resets the token; useful only once)
7369
    string_t& get_string()
7370
0
    {
7371
0
        return token_buffer;
7372
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_string()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_string()
7373
7374
    /////////////////////
7375
    // diagnostics
7376
    /////////////////////
7377
7378
    /// return position of last read token
7379
    constexpr position_t get_position() const noexcept
7380
0
    {
7381
0
        return position;
7382
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_position() const
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_position() const
7383
7384
    /// return the last read token (for errors only).  Will never contain EOF
7385
    /// (an arbitrary value that is not a valid char value, often -1), because
7386
    /// 255 may legitimately occur.  May contain NUL, which should be escaped.
7387
    std::string get_token_string() const
7388
0
    {
7389
        // escape control characters
7390
0
        std::string result;
7391
0
        for (const auto c : token_string)
7392
0
        {
7393
0
            if (static_cast<unsigned char>(c) <= '\x1F')
7394
0
            {
7395
                // escape control characters
7396
0
                std::array<char, 9> cs{{}};
7397
0
                (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
7398
0
                result += cs.data();
7399
0
            }
7400
0
            else
7401
0
            {
7402
                // add character as is
7403
0
                result.push_back(static_cast<std::string::value_type>(c));
7404
0
            }
7405
0
        }
7406
7407
0
        return result;
7408
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_token_string() const
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_token_string() const
7409
7410
    /// return syntax error message
7411
    JSON_HEDLEY_RETURNS_NON_NULL
7412
    constexpr const char* get_error_message() const noexcept
7413
0
    {
7414
0
        return error_message;
7415
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::get_error_message() const
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::get_error_message() const
7416
7417
    /////////////////////
7418
    // actual scanner
7419
    /////////////////////
7420
7421
    /*!
7422
    @brief skip the UTF-8 byte order mark
7423
    @return true iff there is no BOM or the correct BOM has been skipped
7424
    */
7425
    bool skip_bom()
7426
0
    {
7427
0
        if (get() == 0xEF)
7428
0
        {
7429
            // check if we completely parse the BOM
7430
0
            return get() == 0xBB && get() == 0xBF;
7431
0
        }
7432
7433
        // the first character is not the beginning of the BOM; unget it to
7434
        // process is later
7435
0
        unget();
7436
0
        return true;
7437
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::skip_bom()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::skip_bom()
7438
7439
    void skip_whitespace()
7440
0
    {
7441
0
        do
7442
0
        {
7443
0
            get();
7444
0
        }
7445
0
        while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7446
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::skip_whitespace()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::skip_whitespace()
7447
7448
    token_type scan()
7449
0
    {
7450
        // initially, skip the BOM
7451
0
        if (position.chars_read_total == 0 && !skip_bom())
7452
0
        {
7453
0
            error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7454
0
            return token_type::parse_error;
7455
0
        }
7456
7457
        // read next character and ignore whitespace
7458
0
        skip_whitespace();
7459
7460
        // ignore comments
7461
0
        while (ignore_comments && current == '/')
7462
0
        {
7463
0
            if (!scan_comment())
7464
0
            {
7465
0
                return token_type::parse_error;
7466
0
            }
7467
7468
            // skip following whitespace
7469
0
            skip_whitespace();
7470
0
        }
7471
7472
0
        switch (current)
7473
0
        {
7474
            // structural characters
7475
0
            case '[':
7476
0
                return token_type::begin_array;
7477
0
            case ']':
7478
0
                return token_type::end_array;
7479
0
            case '{':
7480
0
                return token_type::begin_object;
7481
0
            case '}':
7482
0
                return token_type::end_object;
7483
0
            case ':':
7484
0
                return token_type::name_separator;
7485
0
            case ',':
7486
0
                return token_type::value_separator;
7487
7488
            // literals
7489
0
            case 't':
7490
0
            {
7491
0
                std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
7492
0
                return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7493
0
            }
7494
0
            case 'f':
7495
0
            {
7496
0
                std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
7497
0
                return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7498
0
            }
7499
0
            case 'n':
7500
0
            {
7501
0
                std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
7502
0
                return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7503
0
            }
7504
7505
            // string
7506
0
            case '\"':
7507
0
                return scan_string();
7508
7509
            // number
7510
0
            case '-':
7511
0
            case '0':
7512
0
            case '1':
7513
0
            case '2':
7514
0
            case '3':
7515
0
            case '4':
7516
0
            case '5':
7517
0
            case '6':
7518
0
            case '7':
7519
0
            case '8':
7520
0
            case '9':
7521
0
                return scan_number();
7522
7523
            // end of input (the null byte is needed when parsing from
7524
            // string literals)
7525
0
            case '\0':
7526
0
            case std::char_traits<char_type>::eof():
7527
0
                return token_type::end_of_input;
7528
7529
            // error
7530
0
            default:
7531
0
                error_message = "invalid literal";
7532
0
                return token_type::parse_error;
7533
0
        }
7534
0
    }
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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*> >::scan()
Unexecuted instantiation: nlohmann::detail::lexer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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::input_stream_adapter>::scan()
7535
7536
  private:
7537
    /// input adapter
7538
    InputAdapterType ia;
7539
7540
    /// whether comments should be ignored (true) or signaled as errors (false)
7541
    const bool ignore_comments = false;
7542
7543
    /// the current character
7544
    char_int_type current = std::char_traits<char_type>::eof();
7545
7546
    /// whether the next get() call should just return current
7547
    bool next_unget = false;
7548
7549
    /// the start position of the current token
7550
    position_t position {};
7551
7552
    /// raw input token string (for error messages)
7553
    std::vector<char_type> token_string {};
7554
7555
    /// buffer for variable-length tokens (numbers, strings)
7556
    string_t token_buffer {};
7557
7558
    /// a description of occurred lexer errors
7559
    const char* error_message = "";
7560
7561
    // number values
7562
    number_integer_t value_integer = 0;
7563
    number_unsigned_t value_unsigned = 0;
7564
    number_float_t value_float = 0;
7565
7566
    /// the decimal point
7567
    const char_int_type decimal_point_char = '.';
7568
};
7569
}  // namespace detail
7570
}  // namespace nlohmann
7571
7572
// #include <nlohmann/detail/macro_scope.hpp>
7573
7574
// #include <nlohmann/detail/meta/is_sax.hpp>
7575
7576
7577
#include <cstdint> // size_t
7578
#include <utility> // declval
7579
#include <string> // string
7580
7581
// #include <nlohmann/detail/meta/detected.hpp>
7582
7583
// #include <nlohmann/detail/meta/type_traits.hpp>
7584
7585
7586
namespace nlohmann
7587
{
7588
namespace detail
7589
{
7590
template<typename T>
7591
using null_function_t = decltype(std::declval<T&>().null());
7592
7593
template<typename T>
7594
using boolean_function_t =
7595
    decltype(std::declval<T&>().boolean(std::declval<bool>()));
7596
7597
template<typename T, typename Integer>
7598
using number_integer_function_t =
7599
    decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
7600
7601
template<typename T, typename Unsigned>
7602
using number_unsigned_function_t =
7603
    decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
7604
7605
template<typename T, typename Float, typename String>
7606
using number_float_function_t = decltype(std::declval<T&>().number_float(
7607
                                    std::declval<Float>(), std::declval<const String&>()));
7608
7609
template<typename T, typename String>
7610
using string_function_t =
7611
    decltype(std::declval<T&>().string(std::declval<String&>()));
7612
7613
template<typename T, typename Binary>
7614
using binary_function_t =
7615
    decltype(std::declval<T&>().binary(std::declval<Binary&>()));
7616
7617
template<typename T>
7618
using start_object_function_t =
7619
    decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
7620
7621
template<typename T, typename String>
7622
using key_function_t =
7623
    decltype(std::declval<T&>().key(std::declval<String&>()));
7624
7625
template<typename T>
7626
using end_object_function_t = decltype(std::declval<T&>().end_object());
7627
7628
template<typename T>
7629
using start_array_function_t =
7630
    decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
7631
7632
template<typename T>
7633
using end_array_function_t = decltype(std::declval<T&>().end_array());
7634
7635
template<typename T, typename Exception>
7636
using parse_error_function_t = decltype(std::declval<T&>().parse_error(
7637
        std::declval<std::size_t>(), std::declval<const std::string&>(),
7638
        std::declval<const Exception&>()));
7639
7640
template<typename SAX, typename BasicJsonType>
7641
struct is_sax
7642
{
7643
  private:
7644
    static_assert(is_basic_json<BasicJsonType>::value,
7645
                  "BasicJsonType must be of type basic_json<...>");
7646
7647
    using number_integer_t = typename BasicJsonType::number_integer_t;
7648
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7649
    using number_float_t = typename BasicJsonType::number_float_t;
7650
    using string_t = typename BasicJsonType::string_t;
7651
    using binary_t = typename BasicJsonType::binary_t;
7652
    using exception_t = typename BasicJsonType::exception;
7653
7654
  public:
7655
    static constexpr bool value =
7656
        is_detected_exact<bool, null_function_t, SAX>::value &&
7657
        is_detected_exact<bool, boolean_function_t, SAX>::value &&
7658
        is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
7659
        is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
7660
        is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
7661
        is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
7662
        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
7663
        is_detected_exact<bool, start_object_function_t, SAX>::value &&
7664
        is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
7665
        is_detected_exact<bool, end_object_function_t, SAX>::value &&
7666
        is_detected_exact<bool, start_array_function_t, SAX>::value &&
7667
        is_detected_exact<bool, end_array_function_t, SAX>::value &&
7668
        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
7669
};
7670
7671
template<typename SAX, typename BasicJsonType>
7672
struct is_sax_static_asserts
7673
{
7674
  private:
7675
    static_assert(is_basic_json<BasicJsonType>::value,
7676
                  "BasicJsonType must be of type basic_json<...>");
7677
7678
    using number_integer_t = typename BasicJsonType::number_integer_t;
7679
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7680
    using number_float_t = typename BasicJsonType::number_float_t;
7681
    using string_t = typename BasicJsonType::string_t;
7682
    using binary_t = typename BasicJsonType::binary_t;
7683
    using exception_t = typename BasicJsonType::exception;
7684
7685
  public:
7686
    static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
7687
                  "Missing/invalid function: bool null()");
7688
    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7689
                  "Missing/invalid function: bool boolean(bool)");
7690
    static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7691
                  "Missing/invalid function: bool boolean(bool)");
7692
    static_assert(
7693
        is_detected_exact<bool, number_integer_function_t, SAX,
7694
        number_integer_t>::value,
7695
        "Missing/invalid function: bool number_integer(number_integer_t)");
7696
    static_assert(
7697
        is_detected_exact<bool, number_unsigned_function_t, SAX,
7698
        number_unsigned_t>::value,
7699
        "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
7700
    static_assert(is_detected_exact<bool, number_float_function_t, SAX,
7701
                  number_float_t, string_t>::value,
7702
                  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
7703
    static_assert(
7704
        is_detected_exact<bool, string_function_t, SAX, string_t>::value,
7705
        "Missing/invalid function: bool string(string_t&)");
7706
    static_assert(
7707
        is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
7708
        "Missing/invalid function: bool binary(binary_t&)");
7709
    static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
7710
                  "Missing/invalid function: bool start_object(std::size_t)");
7711
    static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
7712
                  "Missing/invalid function: bool key(string_t&)");
7713
    static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
7714
                  "Missing/invalid function: bool end_object()");
7715
    static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
7716
                  "Missing/invalid function: bool start_array(std::size_t)");
7717
    static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
7718
                  "Missing/invalid function: bool end_array()");
7719
    static_assert(
7720
        is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
7721
        "Missing/invalid function: bool parse_error(std::size_t, const "
7722
        "std::string&, const exception&)");
7723
};
7724
}  // namespace detail
7725
}  // namespace nlohmann
7726
7727
// #include <nlohmann/detail/value_t.hpp>
7728
7729
7730
namespace nlohmann
7731
{
7732
namespace detail
7733
{
7734
7735
/// how to treat CBOR tags
7736
enum class cbor_tag_handler_t
7737
{
7738
    error,  ///< throw a parse_error exception in case of a tag
7739
    ignore   ///< ignore tags
7740
};
7741
7742
/*!
7743
@brief determine system byte order
7744
7745
@return true if and only if system's byte order is little endian
7746
7747
@note from https://stackoverflow.com/a/1001328/266378
7748
*/
7749
static inline bool little_endianess(int num = 1) noexcept
7750
0
{
7751
0
    return *reinterpret_cast<char*>(&num) == 1;
7752
0
}
Unexecuted instantiation: RTPSParticipantImpl.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: BuiltinProtocols.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: PDPServer.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: PDPServerListener.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: DServerEvent.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: SystemInfo.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: StatefulWriter.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: SharedBackupFunctions.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: EDPServer.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: EDPServerListeners.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: DiscoveryDataBase.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: DiscoveryParticipantInfo.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: DiscoveryParticipantsAckStatus.cpp:nlohmann::detail::little_endianess(int)
Unexecuted instantiation: DiscoverySharedInfo.cpp:nlohmann::detail::little_endianess(int)
7753
7754
7755
///////////////////
7756
// binary reader //
7757
///////////////////
7758
7759
/*!
7760
@brief deserialization of CBOR, MessagePack, and UBJSON values
7761
*/
7762
template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
7763
class binary_reader
7764
{
7765
    using number_integer_t = typename BasicJsonType::number_integer_t;
7766
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7767
    using number_float_t = typename BasicJsonType::number_float_t;
7768
    using string_t = typename BasicJsonType::string_t;
7769
    using binary_t = typename BasicJsonType::binary_t;
7770
    using json_sax_t = SAX;
7771
    using char_type = typename InputAdapterType::char_type;
7772
    using char_int_type = typename std::char_traits<char_type>::int_type;
7773
7774
  public:
7775
    /*!
7776
    @brief create a binary reader
7777
7778
    @param[in] adapter  input adapter to read from
7779
    */
7780
    explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
7781
    {
7782
        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7783
    }
7784
7785
    // make class move-only
7786
    binary_reader(const binary_reader&) = delete;
7787
    binary_reader(binary_reader&&) = default;
7788
    binary_reader& operator=(const binary_reader&) = delete;
7789
    binary_reader& operator=(binary_reader&&) = default;
7790
    ~binary_reader() = default;
7791
7792
    /*!
7793
    @param[in] format  the binary format to parse
7794
    @param[in] sax_    a SAX event processor
7795
    @param[in] strict  whether to expect the input to be consumed completed
7796
    @param[in] tag_handler  how to treat CBOR tags
7797
7798
    @return
7799
    */
7800
    JSON_HEDLEY_NON_NULL(3)
7801
    bool sax_parse(const input_format_t format,
7802
                   json_sax_t* sax_,
7803
                   const bool strict = true,
7804
                   const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7805
    {
7806
        sax = sax_;
7807
        bool result = false;
7808
7809
        switch (format)
7810
        {
7811
            case input_format_t::bson:
7812
                result = parse_bson_internal();
7813
                break;
7814
7815
            case input_format_t::cbor:
7816
                result = parse_cbor_internal(true, tag_handler);
7817
                break;
7818
7819
            case input_format_t::msgpack:
7820
                result = parse_msgpack_internal();
7821
                break;
7822
7823
            case input_format_t::ubjson:
7824
                result = parse_ubjson_internal();
7825
                break;
7826
7827
            default:            // LCOV_EXCL_LINE
7828
                JSON_ASSERT(false);  // LCOV_EXCL_LINE
7829
        }
7830
7831
        // strict mode: next byte must be EOF
7832
        if (result && strict)
7833
        {
7834
            if (format == input_format_t::ubjson)
7835
            {
7836
                get_ignore_noop();
7837
            }
7838
            else
7839
            {
7840
                get();
7841
            }
7842
7843
            if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
7844
            {
7845
                return sax->parse_error(chars_read, get_token_string(),
7846
                                        parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
7847
            }
7848
        }
7849
7850
        return result;
7851
    }
7852
7853
  private:
7854
    //////////
7855
    // BSON //
7856
    //////////
7857
7858
    /*!
7859
    @brief Reads in a BSON-object and passes it to the SAX-parser.
7860
    @return whether a valid BSON-value was passed to the SAX parser
7861
    */
7862
    bool parse_bson_internal()
7863
    {
7864
        std::int32_t document_size{};
7865
        get_number<std::int32_t, true>(input_format_t::bson, document_size);
7866
7867
        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
7868
        {
7869
            return false;
7870
        }
7871
7872
        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
7873
        {
7874
            return false;
7875
        }
7876
7877
        return sax->end_object();
7878
    }
7879
7880
    /*!
7881
    @brief Parses a C-style string from the BSON input.
7882
    @param[in, out] result  A reference to the string variable where the read
7883
                            string is to be stored.
7884
    @return `true` if the \x00-byte indicating the end of the string was
7885
             encountered before the EOF; false` indicates an unexpected EOF.
7886
    */
7887
    bool get_bson_cstr(string_t& result)
7888
    {
7889
        auto out = std::back_inserter(result);
7890
        while (true)
7891
        {
7892
            get();
7893
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
7894
            {
7895
                return false;
7896
            }
7897
            if (current == 0x00)
7898
            {
7899
                return true;
7900
            }
7901
            *out++ = static_cast<typename string_t::value_type>(current);
7902
        }
7903
    }
7904
7905
    /*!
7906
    @brief Parses a zero-terminated string of length @a len from the BSON
7907
           input.
7908
    @param[in] len  The length (including the zero-byte at the end) of the
7909
                    string to be read.
7910
    @param[in, out] result  A reference to the string variable where the read
7911
                            string is to be stored.
7912
    @tparam NumberType The type of the length @a len
7913
    @pre len >= 1
7914
    @return `true` if the string was successfully parsed
7915
    */
7916
    template<typename NumberType>
7917
    bool get_bson_string(const NumberType len, string_t& result)
7918
    {
7919
        if (JSON_HEDLEY_UNLIKELY(len < 1))
7920
        {
7921
            auto last_token = get_token_string();
7922
            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")));
7923
        }
7924
7925
        return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
7926
    }
7927
7928
    /*!
7929
    @brief Parses a byte array input of length @a len from the BSON input.
7930
    @param[in] len  The length of the byte array to be read.
7931
    @param[in, out] result  A reference to the binary variable where the read
7932
                            array is to be stored.
7933
    @tparam NumberType The type of the length @a len
7934
    @pre len >= 0
7935
    @return `true` if the byte array was successfully parsed
7936
    */
7937
    template<typename NumberType>
7938
    bool get_bson_binary(const NumberType len, binary_t& result)
7939
    {
7940
        if (JSON_HEDLEY_UNLIKELY(len < 0))
7941
        {
7942
            auto last_token = get_token_string();
7943
            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")));
7944
        }
7945
7946
        // All BSON binary values have a subtype
7947
        std::uint8_t subtype{};
7948
        get_number<std::uint8_t>(input_format_t::bson, subtype);
7949
        result.set_subtype(subtype);
7950
7951
        return get_binary(input_format_t::bson, len, result);
7952
    }
7953
7954
    /*!
7955
    @brief Read a BSON document element of the given @a element_type.
7956
    @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
7957
    @param[in] element_type_parse_position The position in the input stream,
7958
               where the `element_type` was read.
7959
    @warning Not all BSON element types are supported yet. An unsupported
7960
             @a element_type will give rise to a parse_error.114:
7961
             Unsupported BSON record type 0x...
7962
    @return whether a valid BSON-object/array was passed to the SAX parser
7963
    */
7964
    bool parse_bson_element_internal(const char_int_type element_type,
7965
                                     const std::size_t element_type_parse_position)
7966
    {
7967
        switch (element_type)
7968
        {
7969
            case 0x01: // double
7970
            {
7971
                double number{};
7972
                return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
7973
            }
7974
7975
            case 0x02: // string
7976
            {
7977
                std::int32_t len{};
7978
                string_t value;
7979
                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
7980
            }
7981
7982
            case 0x03: // object
7983
            {
7984
                return parse_bson_internal();
7985
            }
7986
7987
            case 0x04: // array
7988
            {
7989
                return parse_bson_array();
7990
            }
7991
7992
            case 0x05: // binary
7993
            {
7994
                std::int32_t len{};
7995
                binary_t value;
7996
                return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
7997
            }
7998
7999
            case 0x08: // boolean
8000
            {
8001
                return sax->boolean(get() != 0);
8002
            }
8003
8004
            case 0x0A: // null
8005
            {
8006
                return sax->null();
8007
            }
8008
8009
            case 0x10: // int32
8010
            {
8011
                std::int32_t value{};
8012
                return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8013
            }
8014
8015
            case 0x12: // int64
8016
            {
8017
                std::int64_t value{};
8018
                return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8019
            }
8020
8021
            default: // anything else not supported (yet)
8022
            {
8023
                std::array<char, 3> cr{{}};
8024
                (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
8025
                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())));
8026
            }
8027
        }
8028
    }
8029
8030
    /*!
8031
    @brief Read a BSON element list (as specified in the BSON-spec)
8032
8033
    The same binary layout is used for objects and arrays, hence it must be
8034
    indicated with the argument @a is_array which one is expected
8035
    (true --> array, false --> object).
8036
8037
    @param[in] is_array Determines if the element list being read is to be
8038
                        treated as an object (@a is_array == false), or as an
8039
                        array (@a is_array == true).
8040
    @return whether a valid BSON-object/array was passed to the SAX parser
8041
    */
8042
    bool parse_bson_element_list(const bool is_array)
8043
    {
8044
        string_t key;
8045
8046
        while (auto element_type = get())
8047
        {
8048
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8049
            {
8050
                return false;
8051
            }
8052
8053
            const std::size_t element_type_parse_position = chars_read;
8054
            if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8055
            {
8056
                return false;
8057
            }
8058
8059
            if (!is_array && !sax->key(key))
8060
            {
8061
                return false;
8062
            }
8063
8064
            if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8065
            {
8066
                return false;
8067
            }
8068
8069
            // get_bson_cstr only appends
8070
            key.clear();
8071
        }
8072
8073
        return true;
8074
    }
8075
8076
    /*!
8077
    @brief Reads an array from the BSON input and passes it to the SAX-parser.
8078
    @return whether a valid BSON-array was passed to the SAX parser
8079
    */
8080
    bool parse_bson_array()
8081
    {
8082
        std::int32_t document_size{};
8083
        get_number<std::int32_t, true>(input_format_t::bson, document_size);
8084
8085
        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8086
        {
8087
            return false;
8088
        }
8089
8090
        if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8091
        {
8092
            return false;
8093
        }
8094
8095
        return sax->end_array();
8096
    }
8097
8098
    //////////
8099
    // CBOR //
8100
    //////////
8101
8102
    /*!
8103
    @param[in] get_char  whether a new character should be retrieved from the
8104
                         input (true) or whether the last read character should
8105
                         be considered instead (false)
8106
    @param[in] tag_handler how CBOR tags should be treated
8107
8108
    @return whether a valid CBOR value was passed to the SAX parser
8109
    */
8110
    bool parse_cbor_internal(const bool get_char,
8111
                             const cbor_tag_handler_t tag_handler)
8112
    {
8113
        switch (get_char ? get() : current)
8114
        {
8115
            // EOF
8116
            case std::char_traits<char_type>::eof():
8117
                return unexpect_eof(input_format_t::cbor, "value");
8118
8119
            // Integer 0x00..0x17 (0..23)
8120
            case 0x00:
8121
            case 0x01:
8122
            case 0x02:
8123
            case 0x03:
8124
            case 0x04:
8125
            case 0x05:
8126
            case 0x06:
8127
            case 0x07:
8128
            case 0x08:
8129
            case 0x09:
8130
            case 0x0A:
8131
            case 0x0B:
8132
            case 0x0C:
8133
            case 0x0D:
8134
            case 0x0E:
8135
            case 0x0F:
8136
            case 0x10:
8137
            case 0x11:
8138
            case 0x12:
8139
            case 0x13:
8140
            case 0x14:
8141
            case 0x15:
8142
            case 0x16:
8143
            case 0x17:
8144
                return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8145
8146
            case 0x18: // Unsigned integer (one-byte uint8_t follows)
8147
            {
8148
                std::uint8_t number{};
8149
                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8150
            }
8151
8152
            case 0x19: // Unsigned integer (two-byte uint16_t follows)
8153
            {
8154
                std::uint16_t number{};
8155
                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8156
            }
8157
8158
            case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8159
            {
8160
                std::uint32_t number{};
8161
                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8162
            }
8163
8164
            case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8165
            {
8166
                std::uint64_t number{};
8167
                return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8168
            }
8169
8170
            // Negative integer -1-0x00..-1-0x17 (-1..-24)
8171
            case 0x20:
8172
            case 0x21:
8173
            case 0x22:
8174
            case 0x23:
8175
            case 0x24:
8176
            case 0x25:
8177
            case 0x26:
8178
            case 0x27:
8179
            case 0x28:
8180
            case 0x29:
8181
            case 0x2A:
8182
            case 0x2B:
8183
            case 0x2C:
8184
            case 0x2D:
8185
            case 0x2E:
8186
            case 0x2F:
8187
            case 0x30:
8188
            case 0x31:
8189
            case 0x32:
8190
            case 0x33:
8191
            case 0x34:
8192
            case 0x35:
8193
            case 0x36:
8194
            case 0x37:
8195
                return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8196
8197
            case 0x38: // Negative integer (one-byte uint8_t follows)
8198
            {
8199
                std::uint8_t number{};
8200
                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8201
            }
8202
8203
            case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8204
            {
8205
                std::uint16_t number{};
8206
                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8207
            }
8208
8209
            case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8210
            {
8211
                std::uint32_t number{};
8212
                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8213
            }
8214
8215
            case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8216
            {
8217
                std::uint64_t number{};
8218
                return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8219
                        - static_cast<number_integer_t>(number));
8220
            }
8221
8222
            // Binary data (0x00..0x17 bytes follow)
8223
            case 0x40:
8224
            case 0x41:
8225
            case 0x42:
8226
            case 0x43:
8227
            case 0x44:
8228
            case 0x45:
8229
            case 0x46:
8230
            case 0x47:
8231
            case 0x48:
8232
            case 0x49:
8233
            case 0x4A:
8234
            case 0x4B:
8235
            case 0x4C:
8236
            case 0x4D:
8237
            case 0x4E:
8238
            case 0x4F:
8239
            case 0x50:
8240
            case 0x51:
8241
            case 0x52:
8242
            case 0x53:
8243
            case 0x54:
8244
            case 0x55:
8245
            case 0x56:
8246
            case 0x57:
8247
            case 0x58: // Binary data (one-byte uint8_t for n follows)
8248
            case 0x59: // Binary data (two-byte uint16_t for n follow)
8249
            case 0x5A: // Binary data (four-byte uint32_t for n follow)
8250
            case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8251
            case 0x5F: // Binary data (indefinite length)
8252
            {
8253
                binary_t b;
8254
                return get_cbor_binary(b) && sax->binary(b);
8255
            }
8256
8257
            // UTF-8 string (0x00..0x17 bytes follow)
8258
            case 0x60:
8259
            case 0x61:
8260
            case 0x62:
8261
            case 0x63:
8262
            case 0x64:
8263
            case 0x65:
8264
            case 0x66:
8265
            case 0x67:
8266
            case 0x68:
8267
            case 0x69:
8268
            case 0x6A:
8269
            case 0x6B:
8270
            case 0x6C:
8271
            case 0x6D:
8272
            case 0x6E:
8273
            case 0x6F:
8274
            case 0x70:
8275
            case 0x71:
8276
            case 0x72:
8277
            case 0x73:
8278
            case 0x74:
8279
            case 0x75:
8280
            case 0x76:
8281
            case 0x77:
8282
            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8283
            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8284
            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8285
            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8286
            case 0x7F: // UTF-8 string (indefinite length)
8287
            {
8288
                string_t s;
8289
                return get_cbor_string(s) && sax->string(s);
8290
            }
8291
8292
            // array (0x00..0x17 data items follow)
8293
            case 0x80:
8294
            case 0x81:
8295
            case 0x82:
8296
            case 0x83:
8297
            case 0x84:
8298
            case 0x85:
8299
            case 0x86:
8300
            case 0x87:
8301
            case 0x88:
8302
            case 0x89:
8303
            case 0x8A:
8304
            case 0x8B:
8305
            case 0x8C:
8306
            case 0x8D:
8307
            case 0x8E:
8308
            case 0x8F:
8309
            case 0x90:
8310
            case 0x91:
8311
            case 0x92:
8312
            case 0x93:
8313
            case 0x94:
8314
            case 0x95:
8315
            case 0x96:
8316
            case 0x97:
8317
                return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8318
8319
            case 0x98: // array (one-byte uint8_t for n follows)
8320
            {
8321
                std::uint8_t len{};
8322
                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8323
            }
8324
8325
            case 0x99: // array (two-byte uint16_t for n follow)
8326
            {
8327
                std::uint16_t len{};
8328
                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8329
            }
8330
8331
            case 0x9A: // array (four-byte uint32_t for n follow)
8332
            {
8333
                std::uint32_t len{};
8334
                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8335
            }
8336
8337
            case 0x9B: // array (eight-byte uint64_t for n follow)
8338
            {
8339
                std::uint64_t len{};
8340
                return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8341
            }
8342
8343
            case 0x9F: // array (indefinite length)
8344
                return get_cbor_array(std::size_t(-1), tag_handler);
8345
8346
            // map (0x00..0x17 pairs of data items follow)
8347
            case 0xA0:
8348
            case 0xA1:
8349
            case 0xA2:
8350
            case 0xA3:
8351
            case 0xA4:
8352
            case 0xA5:
8353
            case 0xA6:
8354
            case 0xA7:
8355
            case 0xA8:
8356
            case 0xA9:
8357
            case 0xAA:
8358
            case 0xAB:
8359
            case 0xAC:
8360
            case 0xAD:
8361
            case 0xAE:
8362
            case 0xAF:
8363
            case 0xB0:
8364
            case 0xB1:
8365
            case 0xB2:
8366
            case 0xB3:
8367
            case 0xB4:
8368
            case 0xB5:
8369
            case 0xB6:
8370
            case 0xB7:
8371
                return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8372
8373
            case 0xB8: // map (one-byte uint8_t for n follows)
8374
            {
8375
                std::uint8_t len{};
8376
                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8377
            }
8378
8379
            case 0xB9: // map (two-byte uint16_t for n follow)
8380
            {
8381
                std::uint16_t len{};
8382
                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8383
            }
8384
8385
            case 0xBA: // map (four-byte uint32_t for n follow)
8386
            {
8387
                std::uint32_t len{};
8388
                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8389
            }
8390
8391
            case 0xBB: // map (eight-byte uint64_t for n follow)
8392
            {
8393
                std::uint64_t len{};
8394
                return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8395
            }
8396
8397
            case 0xBF: // map (indefinite length)
8398
                return get_cbor_object(std::size_t(-1), tag_handler);
8399
8400
            case 0xC6: // tagged item
8401
            case 0xC7:
8402
            case 0xC8:
8403
            case 0xC9:
8404
            case 0xCA:
8405
            case 0xCB:
8406
            case 0xCC:
8407
            case 0xCD:
8408
            case 0xCE:
8409
            case 0xCF:
8410
            case 0xD0:
8411
            case 0xD1:
8412
            case 0xD2:
8413
            case 0xD3:
8414
            case 0xD4:
8415
            case 0xD8: // tagged item (1 bytes follow)
8416
            case 0xD9: // tagged item (2 bytes follow)
8417
            case 0xDA: // tagged item (4 bytes follow)
8418
            case 0xDB: // tagged item (8 bytes follow)
8419
            {
8420
                switch (tag_handler)
8421
                {
8422
                    case cbor_tag_handler_t::error:
8423
                    {
8424
                        auto last_token = get_token_string();
8425
                        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")));
8426
                    }
8427
8428
                    case cbor_tag_handler_t::ignore:
8429
                    {
8430
                        switch (current)
8431
                        {
8432
                            case 0xD8:
8433
                            {
8434
                                std::uint8_t len{};
8435
                                get_number(input_format_t::cbor, len);
8436
                                break;
8437
                            }
8438
                            case 0xD9:
8439
                            {
8440
                                std::uint16_t len{};
8441
                                get_number(input_format_t::cbor, len);
8442
                                break;
8443
                            }
8444
                            case 0xDA:
8445
                            {
8446
                                std::uint32_t len{};
8447
                                get_number(input_format_t::cbor, len);
8448
                                break;
8449
                            }
8450
                            case 0xDB:
8451
                            {
8452
                                std::uint64_t len{};
8453
                                get_number(input_format_t::cbor, len);
8454
                                break;
8455
                            }
8456
                            default:
8457
                                break;
8458
                        }
8459
                        return parse_cbor_internal(true, tag_handler);
8460
                    }
8461
8462
                    default:                 // LCOV_EXCL_LINE
8463
                        JSON_ASSERT(false);  // LCOV_EXCL_LINE
8464
                        return false;        // LCOV_EXCL_LINE
8465
                }
8466
            }
8467
8468
            case 0xF4: // false
8469
                return sax->boolean(false);
8470
8471
            case 0xF5: // true
8472
                return sax->boolean(true);
8473
8474
            case 0xF6: // null
8475
                return sax->null();
8476
8477
            case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8478
            {
8479
                const auto byte1_raw = get();
8480
                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8481
                {
8482
                    return false;
8483
                }
8484
                const auto byte2_raw = get();
8485
                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8486
                {
8487
                    return false;
8488
                }
8489
8490
                const auto byte1 = static_cast<unsigned char>(byte1_raw);
8491
                const auto byte2 = static_cast<unsigned char>(byte2_raw);
8492
8493
                // code from RFC 7049, Appendix D, Figure 3:
8494
                // As half-precision floating-point numbers were only added
8495
                // to IEEE 754 in 2008, today's programming platforms often
8496
                // still only have limited support for them. It is very
8497
                // easy to include at least decoding support for them even
8498
                // without such support. An example of a small decoder for
8499
                // half-precision floating-point numbers in the C language
8500
                // is shown in Fig. 3.
8501
                const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8502
                const double val = [&half]
8503
                {
8504
                    const int exp = (half >> 10u) & 0x1Fu;
8505
                    const unsigned int mant = half & 0x3FFu;
8506
                    JSON_ASSERT(0 <= exp&& exp <= 32);
8507
                    JSON_ASSERT(mant <= 1024);
8508
                    switch (exp)
8509
                    {
8510
                        case 0:
8511
                            return std::ldexp(mant, -24);
8512
                        case 31:
8513
                            return (mant == 0)
8514
                            ? std::numeric_limits<double>::infinity()
8515
                            : std::numeric_limits<double>::quiet_NaN();
8516
                        default:
8517
                            return std::ldexp(mant + 1024, exp - 25);
8518
                    }
8519
                }();
8520
                return sax->number_float((half & 0x8000u) != 0
8521
                                         ? static_cast<number_float_t>(-val)
8522
                                         : static_cast<number_float_t>(val), "");
8523
            }
8524
8525
            case 0xFA: // Single-Precision Float (four-byte IEEE 754)
8526
            {
8527
                float number{};
8528
                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8529
            }
8530
8531
            case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
8532
            {
8533
                double number{};
8534
                return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8535
            }
8536
8537
            default: // anything else (0xFF is handled inside the other types)
8538
            {
8539
                auto last_token = get_token_string();
8540
                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")));
8541
            }
8542
        }
8543
    }
8544
8545
    /*!
8546
    @brief reads a CBOR string
8547
8548
    This function first reads starting bytes to determine the expected
8549
    string length and then copies this number of bytes into a string.
8550
    Additionally, CBOR's strings with indefinite lengths are supported.
8551
8552
    @param[out] result  created string
8553
8554
    @return whether string creation completed
8555
    */
8556
    bool get_cbor_string(string_t& result)
8557
    {
8558
        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
8559
        {
8560
            return false;
8561
        }
8562
8563
        switch (current)
8564
        {
8565
            // UTF-8 string (0x00..0x17 bytes follow)
8566
            case 0x60:
8567
            case 0x61:
8568
            case 0x62:
8569
            case 0x63:
8570
            case 0x64:
8571
            case 0x65:
8572
            case 0x66:
8573
            case 0x67:
8574
            case 0x68:
8575
            case 0x69:
8576
            case 0x6A:
8577
            case 0x6B:
8578
            case 0x6C:
8579
            case 0x6D:
8580
            case 0x6E:
8581
            case 0x6F:
8582
            case 0x70:
8583
            case 0x71:
8584
            case 0x72:
8585
            case 0x73:
8586
            case 0x74:
8587
            case 0x75:
8588
            case 0x76:
8589
            case 0x77:
8590
            {
8591
                return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8592
            }
8593
8594
            case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8595
            {
8596
                std::uint8_t len{};
8597
                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8598
            }
8599
8600
            case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8601
            {
8602
                std::uint16_t len{};
8603
                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8604
            }
8605
8606
            case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8607
            {
8608
                std::uint32_t len{};
8609
                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8610
            }
8611
8612
            case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8613
            {
8614
                std::uint64_t len{};
8615
                return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8616
            }
8617
8618
            case 0x7F: // UTF-8 string (indefinite length)
8619
            {
8620
                while (get() != 0xFF)
8621
                {
8622
                    string_t chunk;
8623
                    if (!get_cbor_string(chunk))
8624
                    {
8625
                        return false;
8626
                    }
8627
                    result.append(chunk);
8628
                }
8629
                return true;
8630
            }
8631
8632
            default:
8633
            {
8634
                auto last_token = get_token_string();
8635
                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")));
8636
            }
8637
        }
8638
    }
8639
8640
    /*!
8641
    @brief reads a CBOR byte array
8642
8643
    This function first reads starting bytes to determine the expected
8644
    byte array length and then copies this number of bytes into the byte array.
8645
    Additionally, CBOR's byte arrays with indefinite lengths are supported.
8646
8647
    @param[out] result  created byte array
8648
8649
    @return whether byte array creation completed
8650
    */
8651
    bool get_cbor_binary(binary_t& result)
8652
    {
8653
        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
8654
        {
8655
            return false;
8656
        }
8657
8658
        switch (current)
8659
        {
8660
            // Binary data (0x00..0x17 bytes follow)
8661
            case 0x40:
8662
            case 0x41:
8663
            case 0x42:
8664
            case 0x43:
8665
            case 0x44:
8666
            case 0x45:
8667
            case 0x46:
8668
            case 0x47:
8669
            case 0x48:
8670
            case 0x49:
8671
            case 0x4A:
8672
            case 0x4B:
8673
            case 0x4C:
8674
            case 0x4D:
8675
            case 0x4E:
8676
            case 0x4F:
8677
            case 0x50:
8678
            case 0x51:
8679
            case 0x52:
8680
            case 0x53:
8681
            case 0x54:
8682
            case 0x55:
8683
            case 0x56:
8684
            case 0x57:
8685
            {
8686
                return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8687
            }
8688
8689
            case 0x58: // Binary data (one-byte uint8_t for n follows)
8690
            {
8691
                std::uint8_t len{};
8692
                return get_number(input_format_t::cbor, len) &&
8693
                       get_binary(input_format_t::cbor, len, result);
8694
            }
8695
8696
            case 0x59: // Binary data (two-byte uint16_t for n follow)
8697
            {
8698
                std::uint16_t len{};
8699
                return get_number(input_format_t::cbor, len) &&
8700
                       get_binary(input_format_t::cbor, len, result);
8701
            }
8702
8703
            case 0x5A: // Binary data (four-byte uint32_t for n follow)
8704
            {
8705
                std::uint32_t len{};
8706
                return get_number(input_format_t::cbor, len) &&
8707
                       get_binary(input_format_t::cbor, len, result);
8708
            }
8709
8710
            case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8711
            {
8712
                std::uint64_t len{};
8713
                return get_number(input_format_t::cbor, len) &&
8714
                       get_binary(input_format_t::cbor, len, result);
8715
            }
8716
8717
            case 0x5F: // Binary data (indefinite length)
8718
            {
8719
                while (get() != 0xFF)
8720
                {
8721
                    binary_t chunk;
8722
                    if (!get_cbor_binary(chunk))
8723
                    {
8724
                        return false;
8725
                    }
8726
                    result.insert(result.end(), chunk.begin(), chunk.end());
8727
                }
8728
                return true;
8729
            }
8730
8731
            default:
8732
            {
8733
                auto last_token = get_token_string();
8734
                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")));
8735
            }
8736
        }
8737
    }
8738
8739
    /*!
8740
    @param[in] len  the length of the array or std::size_t(-1) for an
8741
                    array of indefinite size
8742
    @param[in] tag_handler how CBOR tags should be treated
8743
    @return whether array creation completed
8744
    */
8745
    bool get_cbor_array(const std::size_t len,
8746
                        const cbor_tag_handler_t tag_handler)
8747
    {
8748
        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
8749
        {
8750
            return false;
8751
        }
8752
8753
        if (len != std::size_t(-1))
8754
        {
8755
            for (std::size_t i = 0; i < len; ++i)
8756
            {
8757
                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8758
                {
8759
                    return false;
8760
                }
8761
            }
8762
        }
8763
        else
8764
        {
8765
            while (get() != 0xFF)
8766
            {
8767
                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
8768
                {
8769
                    return false;
8770
                }
8771
            }
8772
        }
8773
8774
        return sax->end_array();
8775
    }
8776
8777
    /*!
8778
    @param[in] len  the length of the object or std::size_t(-1) for an
8779
                    object of indefinite size
8780
    @param[in] tag_handler how CBOR tags should be treated
8781
    @return whether object creation completed
8782
    */
8783
    bool get_cbor_object(const std::size_t len,
8784
                         const cbor_tag_handler_t tag_handler)
8785
    {
8786
        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
8787
        {
8788
            return false;
8789
        }
8790
8791
        string_t key;
8792
        if (len != std::size_t(-1))
8793
        {
8794
            for (std::size_t i = 0; i < len; ++i)
8795
            {
8796
                get();
8797
                if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8798
                {
8799
                    return false;
8800
                }
8801
8802
                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8803
                {
8804
                    return false;
8805
                }
8806
                key.clear();
8807
            }
8808
        }
8809
        else
8810
        {
8811
            while (get() != 0xFF)
8812
            {
8813
                if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8814
                {
8815
                    return false;
8816
                }
8817
8818
                if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8819
                {
8820
                    return false;
8821
                }
8822
                key.clear();
8823
            }
8824
        }
8825
8826
        return sax->end_object();
8827
    }
8828
8829
    /////////////
8830
    // MsgPack //
8831
    /////////////
8832
8833
    /*!
8834
    @return whether a valid MessagePack value was passed to the SAX parser
8835
    */
8836
    bool parse_msgpack_internal()
8837
    {
8838
        switch (get())
8839
        {
8840
            // EOF
8841
            case std::char_traits<char_type>::eof():
8842
                return unexpect_eof(input_format_t::msgpack, "value");
8843
8844
            // positive fixint
8845
            case 0x00:
8846
            case 0x01:
8847
            case 0x02:
8848
            case 0x03:
8849
            case 0x04:
8850
            case 0x05:
8851
            case 0x06:
8852
            case 0x07:
8853
            case 0x08:
8854
            case 0x09:
8855
            case 0x0A:
8856
            case 0x0B:
8857
            case 0x0C:
8858
            case 0x0D:
8859
            case 0x0E:
8860
            case 0x0F:
8861
            case 0x10:
8862
            case 0x11:
8863
            case 0x12:
8864
            case 0x13:
8865
            case 0x14:
8866
            case 0x15:
8867
            case 0x16:
8868
            case 0x17:
8869
            case 0x18:
8870
            case 0x19:
8871
            case 0x1A:
8872
            case 0x1B:
8873
            case 0x1C:
8874
            case 0x1D:
8875
            case 0x1E:
8876
            case 0x1F:
8877
            case 0x20:
8878
            case 0x21:
8879
            case 0x22:
8880
            case 0x23:
8881
            case 0x24:
8882
            case 0x25:
8883
            case 0x26:
8884
            case 0x27:
8885
            case 0x28:
8886
            case 0x29:
8887
            case 0x2A:
8888
            case 0x2B:
8889
            case 0x2C:
8890
            case 0x2D:
8891
            case 0x2E:
8892
            case 0x2F:
8893
            case 0x30:
8894
            case 0x31:
8895
            case 0x32:
8896
            case 0x33:
8897
            case 0x34:
8898
            case 0x35:
8899
            case 0x36:
8900
            case 0x37:
8901
            case 0x38:
8902
            case 0x39:
8903
            case 0x3A:
8904
            case 0x3B:
8905
            case 0x3C:
8906
            case 0x3D:
8907
            case 0x3E:
8908
            case 0x3F:
8909
            case 0x40:
8910
            case 0x41:
8911
            case 0x42:
8912
            case 0x43:
8913
            case 0x44:
8914
            case 0x45:
8915
            case 0x46:
8916
            case 0x47:
8917
            case 0x48:
8918
            case 0x49:
8919
            case 0x4A:
8920
            case 0x4B:
8921
            case 0x4C:
8922
            case 0x4D:
8923
            case 0x4E:
8924
            case 0x4F:
8925
            case 0x50:
8926
            case 0x51:
8927
            case 0x52:
8928
            case 0x53:
8929
            case 0x54:
8930
            case 0x55:
8931
            case 0x56:
8932
            case 0x57:
8933
            case 0x58:
8934
            case 0x59:
8935
            case 0x5A:
8936
            case 0x5B:
8937
            case 0x5C:
8938
            case 0x5D:
8939
            case 0x5E:
8940
            case 0x5F:
8941
            case 0x60:
8942
            case 0x61:
8943
            case 0x62:
8944
            case 0x63:
8945
            case 0x64:
8946
            case 0x65:
8947
            case 0x66:
8948
            case 0x67:
8949
            case 0x68:
8950
            case 0x69:
8951
            case 0x6A:
8952
            case 0x6B:
8953
            case 0x6C:
8954
            case 0x6D:
8955
            case 0x6E:
8956
            case 0x6F:
8957
            case 0x70:
8958
            case 0x71:
8959
            case 0x72:
8960
            case 0x73:
8961
            case 0x74:
8962
            case 0x75:
8963
            case 0x76:
8964
            case 0x77:
8965
            case 0x78:
8966
            case 0x79:
8967
            case 0x7A:
8968
            case 0x7B:
8969
            case 0x7C:
8970
            case 0x7D:
8971
            case 0x7E:
8972
            case 0x7F:
8973
                return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8974
8975
            // fixmap
8976
            case 0x80:
8977
            case 0x81:
8978
            case 0x82:
8979
            case 0x83:
8980
            case 0x84:
8981
            case 0x85:
8982
            case 0x86:
8983
            case 0x87:
8984
            case 0x88:
8985
            case 0x89:
8986
            case 0x8A:
8987
            case 0x8B:
8988
            case 0x8C:
8989
            case 0x8D:
8990
            case 0x8E:
8991
            case 0x8F:
8992
                return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8993
8994
            // fixarray
8995
            case 0x90:
8996
            case 0x91:
8997
            case 0x92:
8998
            case 0x93:
8999
            case 0x94:
9000
            case 0x95:
9001
            case 0x96:
9002
            case 0x97:
9003
            case 0x98:
9004
            case 0x99:
9005
            case 0x9A:
9006
            case 0x9B:
9007
            case 0x9C:
9008
            case 0x9D:
9009
            case 0x9E:
9010
            case 0x9F:
9011
                return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9012
9013
            // fixstr
9014
            case 0xA0:
9015
            case 0xA1:
9016
            case 0xA2:
9017
            case 0xA3:
9018
            case 0xA4:
9019
            case 0xA5:
9020
            case 0xA6:
9021
            case 0xA7:
9022
            case 0xA8:
9023
            case 0xA9:
9024
            case 0xAA:
9025
            case 0xAB:
9026
            case 0xAC:
9027
            case 0xAD:
9028
            case 0xAE:
9029
            case 0xAF:
9030
            case 0xB0:
9031
            case 0xB1:
9032
            case 0xB2:
9033
            case 0xB3:
9034
            case 0xB4:
9035
            case 0xB5:
9036
            case 0xB6:
9037
            case 0xB7:
9038
            case 0xB8:
9039
            case 0xB9:
9040
            case 0xBA:
9041
            case 0xBB:
9042
            case 0xBC:
9043
            case 0xBD:
9044
            case 0xBE:
9045
            case 0xBF:
9046
            case 0xD9: // str 8
9047
            case 0xDA: // str 16
9048
            case 0xDB: // str 32
9049
            {
9050
                string_t s;
9051
                return get_msgpack_string(s) && sax->string(s);
9052
            }
9053
9054
            case 0xC0: // nil
9055
                return sax->null();
9056
9057
            case 0xC2: // false
9058
                return sax->boolean(false);
9059
9060
            case 0xC3: // true
9061
                return sax->boolean(true);
9062
9063
            case 0xC4: // bin 8
9064
            case 0xC5: // bin 16
9065
            case 0xC6: // bin 32
9066
            case 0xC7: // ext 8
9067
            case 0xC8: // ext 16
9068
            case 0xC9: // ext 32
9069
            case 0xD4: // fixext 1
9070
            case 0xD5: // fixext 2
9071
            case 0xD6: // fixext 4
9072
            case 0xD7: // fixext 8
9073
            case 0xD8: // fixext 16
9074
            {
9075
                binary_t b;
9076
                return get_msgpack_binary(b) && sax->binary(b);
9077
            }
9078
9079
            case 0xCA: // float 32
9080
            {
9081
                float number{};
9082
                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9083
            }
9084
9085
            case 0xCB: // float 64
9086
            {
9087
                double number{};
9088
                return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9089
            }
9090
9091
            case 0xCC: // uint 8
9092
            {
9093
                std::uint8_t number{};
9094
                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9095
            }
9096
9097
            case 0xCD: // uint 16
9098
            {
9099
                std::uint16_t number{};
9100
                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9101
            }
9102
9103
            case 0xCE: // uint 32
9104
            {
9105
                std::uint32_t number{};
9106
                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9107
            }
9108
9109
            case 0xCF: // uint 64
9110
            {
9111
                std::uint64_t number{};
9112
                return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9113
            }
9114
9115
            case 0xD0: // int 8
9116
            {
9117
                std::int8_t number{};
9118
                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9119
            }
9120
9121
            case 0xD1: // int 16
9122
            {
9123
                std::int16_t number{};
9124
                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9125
            }
9126
9127
            case 0xD2: // int 32
9128
            {
9129
                std::int32_t number{};
9130
                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9131
            }
9132
9133
            case 0xD3: // int 64
9134
            {
9135
                std::int64_t number{};
9136
                return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9137
            }
9138
9139
            case 0xDC: // array 16
9140
            {
9141
                std::uint16_t len{};
9142
                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9143
            }
9144
9145
            case 0xDD: // array 32
9146
            {
9147
                std::uint32_t len{};
9148
                return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9149
            }
9150
9151
            case 0xDE: // map 16
9152
            {
9153
                std::uint16_t len{};
9154
                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9155
            }
9156
9157
            case 0xDF: // map 32
9158
            {
9159
                std::uint32_t len{};
9160
                return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9161
            }
9162
9163
            // negative fixint
9164
            case 0xE0:
9165
            case 0xE1:
9166
            case 0xE2:
9167
            case 0xE3:
9168
            case 0xE4:
9169
            case 0xE5:
9170
            case 0xE6:
9171
            case 0xE7:
9172
            case 0xE8:
9173
            case 0xE9:
9174
            case 0xEA:
9175
            case 0xEB:
9176
            case 0xEC:
9177
            case 0xED:
9178
            case 0xEE:
9179
            case 0xEF:
9180
            case 0xF0:
9181
            case 0xF1:
9182
            case 0xF2:
9183
            case 0xF3:
9184
            case 0xF4:
9185
            case 0xF5:
9186
            case 0xF6:
9187
            case 0xF7:
9188
            case 0xF8:
9189
            case 0xF9:
9190
            case 0xFA:
9191
            case 0xFB:
9192
            case 0xFC:
9193
            case 0xFD:
9194
            case 0xFE:
9195
            case 0xFF:
9196
                return sax->number_integer(static_cast<std::int8_t>(current));
9197
9198
            default: // anything else
9199
            {
9200
                auto last_token = get_token_string();
9201
                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")));
9202
            }
9203
        }
9204
    }
9205
9206
    /*!
9207
    @brief reads a MessagePack string
9208
9209
    This function first reads starting bytes to determine the expected
9210
    string length and then copies this number of bytes into a string.
9211
9212
    @param[out] result  created string
9213
9214
    @return whether string creation completed
9215
    */
9216
    bool get_msgpack_string(string_t& result)
9217
    {
9218
        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9219
        {
9220
            return false;
9221
        }
9222
9223
        switch (current)
9224
        {
9225
            // fixstr
9226
            case 0xA0:
9227
            case 0xA1:
9228
            case 0xA2:
9229
            case 0xA3:
9230
            case 0xA4:
9231
            case 0xA5:
9232
            case 0xA6:
9233
            case 0xA7:
9234
            case 0xA8:
9235
            case 0xA9:
9236
            case 0xAA:
9237
            case 0xAB:
9238
            case 0xAC:
9239
            case 0xAD:
9240
            case 0xAE:
9241
            case 0xAF:
9242
            case 0xB0:
9243
            case 0xB1:
9244
            case 0xB2:
9245
            case 0xB3:
9246
            case 0xB4:
9247
            case 0xB5:
9248
            case 0xB6:
9249
            case 0xB7:
9250
            case 0xB8:
9251
            case 0xB9:
9252
            case 0xBA:
9253
            case 0xBB:
9254
            case 0xBC:
9255
            case 0xBD:
9256
            case 0xBE:
9257
            case 0xBF:
9258
            {
9259
                return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9260
            }
9261
9262
            case 0xD9: // str 8
9263
            {
9264
                std::uint8_t len{};
9265
                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9266
            }
9267
9268
            case 0xDA: // str 16
9269
            {
9270
                std::uint16_t len{};
9271
                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9272
            }
9273
9274
            case 0xDB: // str 32
9275
            {
9276
                std::uint32_t len{};
9277
                return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9278
            }
9279
9280
            default:
9281
            {
9282
                auto last_token = get_token_string();
9283
                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")));
9284
            }
9285
        }
9286
    }
9287
9288
    /*!
9289
    @brief reads a MessagePack byte array
9290
9291
    This function first reads starting bytes to determine the expected
9292
    byte array length and then copies this number of bytes into a byte array.
9293
9294
    @param[out] result  created byte array
9295
9296
    @return whether byte array creation completed
9297
    */
9298
    bool get_msgpack_binary(binary_t& result)
9299
    {
9300
        // helper function to set the subtype
9301
        auto assign_and_return_true = [&result](std::int8_t subtype)
9302
        {
9303
            result.set_subtype(static_cast<std::uint8_t>(subtype));
9304
            return true;
9305
        };
9306
9307
        switch (current)
9308
        {
9309
            case 0xC4: // bin 8
9310
            {
9311
                std::uint8_t len{};
9312
                return get_number(input_format_t::msgpack, len) &&
9313
                       get_binary(input_format_t::msgpack, len, result);
9314
            }
9315
9316
            case 0xC5: // bin 16
9317
            {
9318
                std::uint16_t len{};
9319
                return get_number(input_format_t::msgpack, len) &&
9320
                       get_binary(input_format_t::msgpack, len, result);
9321
            }
9322
9323
            case 0xC6: // bin 32
9324
            {
9325
                std::uint32_t len{};
9326
                return get_number(input_format_t::msgpack, len) &&
9327
                       get_binary(input_format_t::msgpack, len, result);
9328
            }
9329
9330
            case 0xC7: // ext 8
9331
            {
9332
                std::uint8_t len{};
9333
                std::int8_t subtype{};
9334
                return get_number(input_format_t::msgpack, len) &&
9335
                       get_number(input_format_t::msgpack, subtype) &&
9336
                       get_binary(input_format_t::msgpack, len, result) &&
9337
                       assign_and_return_true(subtype);
9338
            }
9339
9340
            case 0xC8: // ext 16
9341
            {
9342
                std::uint16_t len{};
9343
                std::int8_t subtype{};
9344
                return get_number(input_format_t::msgpack, len) &&
9345
                       get_number(input_format_t::msgpack, subtype) &&
9346
                       get_binary(input_format_t::msgpack, len, result) &&
9347
                       assign_and_return_true(subtype);
9348
            }
9349
9350
            case 0xC9: // ext 32
9351
            {
9352
                std::uint32_t len{};
9353
                std::int8_t subtype{};
9354
                return get_number(input_format_t::msgpack, len) &&
9355
                       get_number(input_format_t::msgpack, subtype) &&
9356
                       get_binary(input_format_t::msgpack, len, result) &&
9357
                       assign_and_return_true(subtype);
9358
            }
9359
9360
            case 0xD4: // fixext 1
9361
            {
9362
                std::int8_t subtype{};
9363
                return get_number(input_format_t::msgpack, subtype) &&
9364
                       get_binary(input_format_t::msgpack, 1, result) &&
9365
                       assign_and_return_true(subtype);
9366
            }
9367
9368
            case 0xD5: // fixext 2
9369
            {
9370
                std::int8_t subtype{};
9371
                return get_number(input_format_t::msgpack, subtype) &&
9372
                       get_binary(input_format_t::msgpack, 2, result) &&
9373
                       assign_and_return_true(subtype);
9374
            }
9375
9376
            case 0xD6: // fixext 4
9377
            {
9378
                std::int8_t subtype{};
9379
                return get_number(input_format_t::msgpack, subtype) &&
9380
                       get_binary(input_format_t::msgpack, 4, result) &&
9381
                       assign_and_return_true(subtype);
9382
            }
9383
9384
            case 0xD7: // fixext 8
9385
            {
9386
                std::int8_t subtype{};
9387
                return get_number(input_format_t::msgpack, subtype) &&
9388
                       get_binary(input_format_t::msgpack, 8, result) &&
9389
                       assign_and_return_true(subtype);
9390
            }
9391
9392
            case 0xD8: // fixext 16
9393
            {
9394
                std::int8_t subtype{};
9395
                return get_number(input_format_t::msgpack, subtype) &&
9396
                       get_binary(input_format_t::msgpack, 16, result) &&
9397
                       assign_and_return_true(subtype);
9398
            }
9399
9400
            default:           // LCOV_EXCL_LINE
9401
                return false;  // LCOV_EXCL_LINE
9402
        }
9403
    }
9404
9405
    /*!
9406
    @param[in] len  the length of the array
9407
    @return whether array creation completed
9408
    */
9409
    bool get_msgpack_array(const std::size_t len)
9410
    {
9411
        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9412
        {
9413
            return false;
9414
        }
9415
9416
        for (std::size_t i = 0; i < len; ++i)
9417
        {
9418
            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9419
            {
9420
                return false;
9421
            }
9422
        }
9423
9424
        return sax->end_array();
9425
    }
9426
9427
    /*!
9428
    @param[in] len  the length of the object
9429
    @return whether object creation completed
9430
    */
9431
    bool get_msgpack_object(const std::size_t len)
9432
    {
9433
        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9434
        {
9435
            return false;
9436
        }
9437
9438
        string_t key;
9439
        for (std::size_t i = 0; i < len; ++i)
9440
        {
9441
            get();
9442
            if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
9443
            {
9444
                return false;
9445
            }
9446
9447
            if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9448
            {
9449
                return false;
9450
            }
9451
            key.clear();
9452
        }
9453
9454
        return sax->end_object();
9455
    }
9456
9457
    ////////////
9458
    // UBJSON //
9459
    ////////////
9460
9461
    /*!
9462
    @param[in] get_char  whether a new character should be retrieved from the
9463
                         input (true, default) or whether the last read
9464
                         character should be considered instead
9465
9466
    @return whether a valid UBJSON value was passed to the SAX parser
9467
    */
9468
    bool parse_ubjson_internal(const bool get_char = true)
9469
    {
9470
        return get_ubjson_value(get_char ? get_ignore_noop() : current);
9471
    }
9472
9473
    /*!
9474
    @brief reads a UBJSON string
9475
9476
    This function is either called after reading the 'S' byte explicitly
9477
    indicating a string, or in case of an object key where the 'S' byte can be
9478
    left out.
9479
9480
    @param[out] result   created string
9481
    @param[in] get_char  whether a new character should be retrieved from the
9482
                         input (true, default) or whether the last read
9483
                         character should be considered instead
9484
9485
    @return whether string creation completed
9486
    */
9487
    bool get_ubjson_string(string_t& result, const bool get_char = true)
9488
    {
9489
        if (get_char)
9490
        {
9491
            get();  // TODO(niels): may we ignore N here?
9492
        }
9493
9494
        if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9495
        {
9496
            return false;
9497
        }
9498
9499
        switch (current)
9500
        {
9501
            case 'U':
9502
            {
9503
                std::uint8_t len{};
9504
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9505
            }
9506
9507
            case 'i':
9508
            {
9509
                std::int8_t len{};
9510
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9511
            }
9512
9513
            case 'I':
9514
            {
9515
                std::int16_t len{};
9516
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9517
            }
9518
9519
            case 'l':
9520
            {
9521
                std::int32_t len{};
9522
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9523
            }
9524
9525
            case 'L':
9526
            {
9527
                std::int64_t len{};
9528
                return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9529
            }
9530
9531
            default:
9532
                auto last_token = get_token_string();
9533
                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")));
9534
        }
9535
    }
9536
9537
    /*!
9538
    @param[out] result  determined size
9539
    @return whether size determination completed
9540
    */
9541
    bool get_ubjson_size_value(std::size_t& result)
9542
    {
9543
        switch (get_ignore_noop())
9544
        {
9545
            case 'U':
9546
            {
9547
                std::uint8_t number{};
9548
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9549
                {
9550
                    return false;
9551
                }
9552
                result = static_cast<std::size_t>(number);
9553
                return true;
9554
            }
9555
9556
            case 'i':
9557
            {
9558
                std::int8_t number{};
9559
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9560
                {
9561
                    return false;
9562
                }
9563
                result = static_cast<std::size_t>(number);
9564
                return true;
9565
            }
9566
9567
            case 'I':
9568
            {
9569
                std::int16_t number{};
9570
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9571
                {
9572
                    return false;
9573
                }
9574
                result = static_cast<std::size_t>(number);
9575
                return true;
9576
            }
9577
9578
            case 'l':
9579
            {
9580
                std::int32_t number{};
9581
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9582
                {
9583
                    return false;
9584
                }
9585
                result = static_cast<std::size_t>(number);
9586
                return true;
9587
            }
9588
9589
            case 'L':
9590
            {
9591
                std::int64_t number{};
9592
                if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9593
                {
9594
                    return false;
9595
                }
9596
                result = static_cast<std::size_t>(number);
9597
                return true;
9598
            }
9599
9600
            default:
9601
            {
9602
                auto last_token = get_token_string();
9603
                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")));
9604
            }
9605
        }
9606
    }
9607
9608
    /*!
9609
    @brief determine the type and size for a container
9610
9611
    In the optimized UBJSON format, a type and a size can be provided to allow
9612
    for a more compact representation.
9613
9614
    @param[out] result  pair of the size and the type
9615
9616
    @return whether pair creation completed
9617
    */
9618
    bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
9619
    {
9620
        result.first = string_t::npos; // size
9621
        result.second = 0; // type
9622
9623
        get_ignore_noop();
9624
9625
        if (current == '$')
9626
        {
9627
            result.second = get();  // must not ignore 'N', because 'N' maybe the type
9628
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
9629
            {
9630
                return false;
9631
            }
9632
9633
            get_ignore_noop();
9634
            if (JSON_HEDLEY_UNLIKELY(current != '#'))
9635
            {
9636
                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9637
                {
9638
                    return false;
9639
                }
9640
                auto last_token = get_token_string();
9641
                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")));
9642
            }
9643
9644
            return get_ubjson_size_value(result.first);
9645
        }
9646
9647
        if (current == '#')
9648
        {
9649
            return get_ubjson_size_value(result.first);
9650
        }
9651
9652
        return true;
9653
    }
9654
9655
    /*!
9656
    @param prefix  the previously read or set type prefix
9657
    @return whether value creation completed
9658
    */
9659
    bool get_ubjson_value(const char_int_type prefix)
9660
    {
9661
        switch (prefix)
9662
        {
9663
            case std::char_traits<char_type>::eof():  // EOF
9664
                return unexpect_eof(input_format_t::ubjson, "value");
9665
9666
            case 'T':  // true
9667
                return sax->boolean(true);
9668
            case 'F':  // false
9669
                return sax->boolean(false);
9670
9671
            case 'Z':  // null
9672
                return sax->null();
9673
9674
            case 'U':
9675
            {
9676
                std::uint8_t number{};
9677
                return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
9678
            }
9679
9680
            case 'i':
9681
            {
9682
                std::int8_t number{};
9683
                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9684
            }
9685
9686
            case 'I':
9687
            {
9688
                std::int16_t number{};
9689
                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9690
            }
9691
9692
            case 'l':
9693
            {
9694
                std::int32_t number{};
9695
                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9696
            }
9697
9698
            case 'L':
9699
            {
9700
                std::int64_t number{};
9701
                return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9702
            }
9703
9704
            case 'd':
9705
            {
9706
                float number{};
9707
                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9708
            }
9709
9710
            case 'D':
9711
            {
9712
                double number{};
9713
                return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9714
            }
9715
9716
            case 'H':
9717
            {
9718
                return get_ubjson_high_precision_number();
9719
            }
9720
9721
            case 'C':  // char
9722
            {
9723
                get();
9724
                if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
9725
                {
9726
                    return false;
9727
                }
9728
                if (JSON_HEDLEY_UNLIKELY(current > 127))
9729
                {
9730
                    auto last_token = get_token_string();
9731
                    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")));
9732
                }
9733
                string_t s(1, static_cast<typename string_t::value_type>(current));
9734
                return sax->string(s);
9735
            }
9736
9737
            case 'S':  // string
9738
            {
9739
                string_t s;
9740
                return get_ubjson_string(s) && sax->string(s);
9741
            }
9742
9743
            case '[':  // array
9744
                return get_ubjson_array();
9745
9746
            case '{':  // object
9747
                return get_ubjson_object();
9748
9749
            default: // anything else
9750
            {
9751
                auto last_token = get_token_string();
9752
                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")));
9753
            }
9754
        }
9755
    }
9756
9757
    /*!
9758
    @return whether array creation completed
9759
    */
9760
    bool get_ubjson_array()
9761
    {
9762
        std::pair<std::size_t, char_int_type> size_and_type;
9763
        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9764
        {
9765
            return false;
9766
        }
9767
9768
        if (size_and_type.first != string_t::npos)
9769
        {
9770
            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
9771
            {
9772
                return false;
9773
            }
9774
9775
            if (size_and_type.second != 0)
9776
            {
9777
                if (size_and_type.second != 'N')
9778
                {
9779
                    for (std::size_t i = 0; i < size_and_type.first; ++i)
9780
                    {
9781
                        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9782
                        {
9783
                            return false;
9784
                        }
9785
                    }
9786
                }
9787
            }
9788
            else
9789
            {
9790
                for (std::size_t i = 0; i < size_and_type.first; ++i)
9791
                {
9792
                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9793
                    {
9794
                        return false;
9795
                    }
9796
                }
9797
            }
9798
        }
9799
        else
9800
        {
9801
            if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
9802
            {
9803
                return false;
9804
            }
9805
9806
            while (current != ']')
9807
            {
9808
                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
9809
                {
9810
                    return false;
9811
                }
9812
                get_ignore_noop();
9813
            }
9814
        }
9815
9816
        return sax->end_array();
9817
    }
9818
9819
    /*!
9820
    @return whether object creation completed
9821
    */
9822
    bool get_ubjson_object()
9823
    {
9824
        std::pair<std::size_t, char_int_type> size_and_type;
9825
        if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9826
        {
9827
            return false;
9828
        }
9829
9830
        string_t key;
9831
        if (size_and_type.first != string_t::npos)
9832
        {
9833
            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
9834
            {
9835
                return false;
9836
            }
9837
9838
            if (size_and_type.second != 0)
9839
            {
9840
                for (std::size_t i = 0; i < size_and_type.first; ++i)
9841
                {
9842
                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9843
                    {
9844
                        return false;
9845
                    }
9846
                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9847
                    {
9848
                        return false;
9849
                    }
9850
                    key.clear();
9851
                }
9852
            }
9853
            else
9854
            {
9855
                for (std::size_t i = 0; i < size_and_type.first; ++i)
9856
                {
9857
                    if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9858
                    {
9859
                        return false;
9860
                    }
9861
                    if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9862
                    {
9863
                        return false;
9864
                    }
9865
                    key.clear();
9866
                }
9867
            }
9868
        }
9869
        else
9870
        {
9871
            if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
9872
            {
9873
                return false;
9874
            }
9875
9876
            while (current != '}')
9877
            {
9878
                if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
9879
                {
9880
                    return false;
9881
                }
9882
                if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9883
                {
9884
                    return false;
9885
                }
9886
                get_ignore_noop();
9887
                key.clear();
9888
            }
9889
        }
9890
9891
        return sax->end_object();
9892
    }
9893
9894
    // Note, no reader for UBJSON binary types is implemented because they do
9895
    // not exist
9896
9897
    bool get_ubjson_high_precision_number()
9898
    {
9899
        // get size of following number string
9900
        std::size_t size{};
9901
        auto res = get_ubjson_size_value(size);
9902
        if (JSON_HEDLEY_UNLIKELY(!res))
9903
        {
9904
            return res;
9905
        }
9906
9907
        // get number string
9908
        std::vector<char> number_vector;
9909
        for (std::size_t i = 0; i < size; ++i)
9910
        {
9911
            get();
9912
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
9913
            {
9914
                return false;
9915
            }
9916
            number_vector.push_back(static_cast<char>(current));
9917
        }
9918
9919
        // parse number string
9920
        auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
9921
        auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);
9922
        const auto result_number = number_lexer.scan();
9923
        const auto number_string = number_lexer.get_token_string();
9924
        const auto result_remainder = number_lexer.scan();
9925
9926
        using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
9927
9928
        if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
9929
        {
9930
            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")));
9931
        }
9932
9933
        switch (result_number)
9934
        {
9935
            case token_type::value_integer:
9936
                return sax->number_integer(number_lexer.get_number_integer());
9937
            case token_type::value_unsigned:
9938
                return sax->number_unsigned(number_lexer.get_number_unsigned());
9939
            case token_type::value_float:
9940
                return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
9941
            default:
9942
                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")));
9943
        }
9944
    }
9945
9946
    ///////////////////////
9947
    // Utility functions //
9948
    ///////////////////////
9949
9950
    /*!
9951
    @brief get next character from the input
9952
9953
    This function provides the interface to the used input adapter. It does
9954
    not throw in case the input reached EOF, but returns a -'ve valued
9955
    `std::char_traits<char_type>::eof()` in that case.
9956
9957
    @return character read from the input
9958
    */
9959
    char_int_type get()
9960
    {
9961
        ++chars_read;
9962
        return current = ia.get_character();
9963
    }
9964
9965
    /*!
9966
    @return character read from the input after ignoring all 'N' entries
9967
    */
9968
    char_int_type get_ignore_noop()
9969
    {
9970
        do
9971
        {
9972
            get();
9973
        }
9974
        while (current == 'N');
9975
9976
        return current;
9977
    }
9978
9979
    /*
9980
    @brief read a number from the input
9981
9982
    @tparam NumberType the type of the number
9983
    @param[in] format   the current format (for diagnostics)
9984
    @param[out] result  number of type @a NumberType
9985
9986
    @return whether conversion completed
9987
9988
    @note This function needs to respect the system's endianess, because
9989
          bytes in CBOR, MessagePack, and UBJSON are stored in network order
9990
          (big endian) and therefore need reordering on little endian systems.
9991
    */
9992
    template<typename NumberType, bool InputIsLittleEndian = false>
9993
    bool get_number(const input_format_t format, NumberType& result)
9994
    {
9995
        // step 1: read input into array with system's byte order
9996
        std::array<std::uint8_t, sizeof(NumberType)> vec;
9997
        for (std::size_t i = 0; i < sizeof(NumberType); ++i)
9998
        {
9999
            get();
10000
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10001
            {
10002
                return false;
10003
            }
10004
10005
            // reverse byte order prior to conversion if necessary
10006
            if (is_little_endian != InputIsLittleEndian)
10007
            {
10008
                vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10009
            }
10010
            else
10011
            {
10012
                vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10013
            }
10014
        }
10015
10016
        // step 2: convert array into number of type T and return
10017
        std::memcpy(&result, vec.data(), sizeof(NumberType));
10018
        return true;
10019
    }
10020
10021
    /*!
10022
    @brief create a string by reading characters from the input
10023
10024
    @tparam NumberType the type of the number
10025
    @param[in] format the current format (for diagnostics)
10026
    @param[in] len number of characters to read
10027
    @param[out] result string created by reading @a len bytes
10028
10029
    @return whether string creation completed
10030
10031
    @note We can not reserve @a len bytes for the result, because @a len
10032
          may be too large. Usually, @ref unexpect_eof() detects the end of
10033
          the input before we run out of string memory.
10034
    */
10035
    template<typename NumberType>
10036
    bool get_string(const input_format_t format,
10037
                    const NumberType len,
10038
                    string_t& result)
10039
    {
10040
        bool success = true;
10041
        for (NumberType i = 0; i < len; i++)
10042
        {
10043
            get();
10044
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10045
            {
10046
                success = false;
10047
                break;
10048
            }
10049
            result.push_back(static_cast<typename string_t::value_type>(current));
10050
        };
10051
        return success;
10052
    }
10053
10054
    /*!
10055
    @brief create a byte array by reading bytes from the input
10056
10057
    @tparam NumberType the type of the number
10058
    @param[in] format the current format (for diagnostics)
10059
    @param[in] len number of bytes to read
10060
    @param[out] result byte array created by reading @a len bytes
10061
10062
    @return whether byte array creation completed
10063
10064
    @note We can not reserve @a len bytes for the result, because @a len
10065
          may be too large. Usually, @ref unexpect_eof() detects the end of
10066
          the input before we run out of memory.
10067
    */
10068
    template<typename NumberType>
10069
    bool get_binary(const input_format_t format,
10070
                    const NumberType len,
10071
                    binary_t& result)
10072
    {
10073
        bool success = true;
10074
        for (NumberType i = 0; i < len; i++)
10075
        {
10076
            get();
10077
            if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10078
            {
10079
                success = false;
10080
                break;
10081
            }
10082
            result.push_back(static_cast<std::uint8_t>(current));
10083
        }
10084
        return success;
10085
    }
10086
10087
    /*!
10088
    @param[in] format   the current format (for diagnostics)
10089
    @param[in] context  further context information (for diagnostics)
10090
    @return whether the last read character is not EOF
10091
    */
10092
    JSON_HEDLEY_NON_NULL(3)
10093
    bool unexpect_eof(const input_format_t format, const char* context) const
10094
    {
10095
        if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10096
        {
10097
            return sax->parse_error(chars_read, "<end of file>",
10098
                                    parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
10099
        }
10100
        return true;
10101
    }
10102
10103
    /*!
10104
    @return a string representation of the last read byte
10105
    */
10106
    std::string get_token_string() const
10107
    {
10108
        std::array<char, 3> cr{{}};
10109
        (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
10110
        return std::string{cr.data()};
10111
    }
10112
10113
    /*!
10114
    @param[in] format   the current format
10115
    @param[in] detail   a detailed error message
10116
    @param[in] context  further context information
10117
    @return a message string to use in the parse_error exceptions
10118
    */
10119
    std::string exception_message(const input_format_t format,
10120
                                  const std::string& detail,
10121
                                  const std::string& context) const
10122
    {
10123
        std::string error_msg = "syntax error while parsing ";
10124
10125
        switch (format)
10126
        {
10127
            case input_format_t::cbor:
10128
                error_msg += "CBOR";
10129
                break;
10130
10131
            case input_format_t::msgpack:
10132
                error_msg += "MessagePack";
10133
                break;
10134
10135
            case input_format_t::ubjson:
10136
                error_msg += "UBJSON";
10137
                break;
10138
10139
            case input_format_t::bson:
10140
                error_msg += "BSON";
10141
                break;
10142
10143
            default:            // LCOV_EXCL_LINE
10144
                JSON_ASSERT(false);  // LCOV_EXCL_LINE
10145
        }
10146
10147
        return error_msg + " " + context + ": " + detail;
10148
    }
10149
10150
  private:
10151
    /// input adapter
10152
    InputAdapterType ia;
10153
10154
    /// the current character
10155
    char_int_type current = std::char_traits<char_type>::eof();
10156
10157
    /// the number of characters read
10158
    std::size_t chars_read = 0;
10159
10160
    /// whether we can assume little endianess
10161
    const bool is_little_endian = little_endianess();
10162
10163
    /// the SAX parser
10164
    json_sax_t* sax = nullptr;
10165
};
10166
}  // namespace detail
10167
}  // namespace nlohmann
10168
10169
// #include <nlohmann/detail/input/input_adapters.hpp>
10170
10171
// #include <nlohmann/detail/input/lexer.hpp>
10172
10173
// #include <nlohmann/detail/input/parser.hpp>
10174
10175
10176
#include <cmath> // isfinite
10177
#include <cstdint> // uint8_t
10178
#include <functional> // function
10179
#include <string> // string
10180
#include <utility> // move
10181
#include <vector> // vector
10182
10183
// #include <nlohmann/detail/exceptions.hpp>
10184
10185
// #include <nlohmann/detail/input/input_adapters.hpp>
10186
10187
// #include <nlohmann/detail/input/json_sax.hpp>
10188
10189
// #include <nlohmann/detail/input/lexer.hpp>
10190
10191
// #include <nlohmann/detail/macro_scope.hpp>
10192
10193
// #include <nlohmann/detail/meta/is_sax.hpp>
10194
10195
// #include <nlohmann/detail/value_t.hpp>
10196
10197
10198
namespace nlohmann
10199
{
10200
namespace detail
10201
{
10202
////////////
10203
// parser //
10204
////////////
10205
10206
enum class parse_event_t : uint8_t
10207
{
10208
    /// the parser read `{` and started to process a JSON object
10209
    object_start,
10210
    /// the parser read `}` and finished processing a JSON object
10211
    object_end,
10212
    /// the parser read `[` and started to process a JSON array
10213
    array_start,
10214
    /// the parser read `]` and finished processing a JSON array
10215
    array_end,
10216
    /// the parser read a key of a value in an object
10217
    key,
10218
    /// the parser finished reading a JSON value
10219
    value
10220
};
10221
10222
template<typename BasicJsonType>
10223
using parser_callback_t =
10224
    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
10225
10226
/*!
10227
@brief syntax analysis
10228
10229
This class implements a recursive descent parser.
10230
*/
10231
template<typename BasicJsonType, typename InputAdapterType>
10232
class parser
10233
{
10234
    using number_integer_t = typename BasicJsonType::number_integer_t;
10235
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10236
    using number_float_t = typename BasicJsonType::number_float_t;
10237
    using string_t = typename BasicJsonType::string_t;
10238
    using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10239
    using token_type = typename lexer_t::token_type;
10240
10241
  public:
10242
    /// a parser reading from an input adapter
10243
    explicit parser(InputAdapterType&& adapter,
10244
                    const parser_callback_t<BasicJsonType> cb = nullptr,
10245
                    const bool allow_exceptions_ = true,
10246
                    const bool skip_comments = false)
10247
        : callback(cb)
10248
        , m_lexer(std::move(adapter), skip_comments)
10249
        , allow_exceptions(allow_exceptions_)
10250
0
    {
10251
        // read first token
10252
0
        get_token();
10253
0
    }
10254
10255
    /*!
10256
    @brief public parser interface
10257
10258
    @param[in] strict      whether to expect the last token to be EOF
10259
    @param[in,out] result  parsed JSON value
10260
10261
    @throw parse_error.101 in case of an unexpected token
10262
    @throw parse_error.102 if to_unicode fails or surrogate error
10263
    @throw parse_error.103 if to_unicode fails
10264
    */
10265
    void parse(const bool strict, BasicJsonType& result)
10266
0
    {
10267
0
        if (callback)
10268
0
        {
10269
0
            json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10270
0
            sax_parse_internal(&sdp);
10271
0
            result.assert_invariant();
10272
10273
            // in strict mode, input must be completely read
10274
0
            if (strict && (get_token() != token_type::end_of_input))
10275
0
            {
10276
0
                sdp.parse_error(m_lexer.get_position(),
10277
0
                                m_lexer.get_token_string(),
10278
0
                                parse_error::create(101, m_lexer.get_position(),
10279
0
                                                    exception_message(token_type::end_of_input, "value")));
10280
0
            }
10281
10282
            // in case of an error, return discarded value
10283
0
            if (sdp.is_errored())
10284
0
            {
10285
0
                result = value_t::discarded;
10286
0
                return;
10287
0
            }
10288
10289
            // set top-level value to null if it was discarded by the callback
10290
            // function
10291
0
            if (result.is_discarded())
10292
0
            {
10293
0
                result = nullptr;
10294
0
            }
10295
0
        }
10296
0
        else
10297
0
        {
10298
0
            json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10299
0
            sax_parse_internal(&sdp);
10300
0
            result.assert_invariant();
10301
10302
            // in strict mode, input must be completely read
10303
0
            if (strict && (get_token() != token_type::end_of_input))
10304
0
            {
10305
0
                sdp.parse_error(m_lexer.get_position(),
10306
0
                                m_lexer.get_token_string(),
10307
0
                                parse_error::create(101, m_lexer.get_position(),
10308
0
                                                    exception_message(token_type::end_of_input, "value")));
10309
0
            }
10310
10311
            // in case of an error, return discarded value
10312
0
            if (sdp.is_errored())
10313
0
            {
10314
0
                result = value_t::discarded;
10315
0
                return;
10316
0
            }
10317
0
        }
10318
0
    }
Unexecuted instantiation: 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*> >::parse(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> > >&)
Unexecuted instantiation: 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::input_stream_adapter>::parse(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> > >&)
10319
10320
    /*!
10321
    @brief public accept interface
10322
10323
    @param[in] strict  whether to expect the last token to be EOF
10324
    @return whether the input is a proper JSON text
10325
    */
10326
    bool accept(const bool strict = true)
10327
    {
10328
        json_sax_acceptor<BasicJsonType> sax_acceptor;
10329
        return sax_parse(&sax_acceptor, strict);
10330
    }
10331
10332
    template<typename SAX>
10333
    JSON_HEDLEY_NON_NULL(2)
10334
    bool sax_parse(SAX* sax, const bool strict = true)
10335
    {
10336
        (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10337
        const bool result = sax_parse_internal(sax);
10338
10339
        // strict mode: next byte must be EOF
10340
        if (result && strict && (get_token() != token_type::end_of_input))
10341
        {
10342
            return sax->parse_error(m_lexer.get_position(),
10343
                                    m_lexer.get_token_string(),
10344
                                    parse_error::create(101, m_lexer.get_position(),
10345
                                            exception_message(token_type::end_of_input, "value")));
10346
        }
10347
10348
        return result;
10349
    }
10350
10351
  private:
10352
    template<typename SAX>
10353
    JSON_HEDLEY_NON_NULL(2)
10354
    bool sax_parse_internal(SAX* sax)
10355
0
    {
10356
        // stack to remember the hierarchy of structured values we are parsing
10357
        // true = array; false = object
10358
0
        std::vector<bool> states;
10359
        // value to avoid a goto (see comment where set to true)
10360
0
        bool skip_to_state_evaluation = false;
10361
10362
0
        while (true)
10363
0
        {
10364
0
            if (!skip_to_state_evaluation)
10365
0
            {
10366
                // invariant: get_token() was called before each iteration
10367
0
                switch (last_token)
10368
0
                {
10369
0
                    case token_type::begin_object:
10370
0
                    {
10371
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10372
0
                        {
10373
0
                            return false;
10374
0
                        }
10375
10376
                        // closing } -> we are done
10377
0
                        if (get_token() == token_type::end_object)
10378
0
                        {
10379
0
                            if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10380
0
                            {
10381
0
                                return false;
10382
0
                            }
10383
0
                            break;
10384
0
                        }
10385
10386
                        // parse key
10387
0
                        if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10388
0
                        {
10389
0
                            return sax->parse_error(m_lexer.get_position(),
10390
0
                                                    m_lexer.get_token_string(),
10391
0
                                                    parse_error::create(101, m_lexer.get_position(),
10392
0
                                                            exception_message(token_type::value_string, "object key")));
10393
0
                        }
10394
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10395
0
                        {
10396
0
                            return false;
10397
0
                        }
10398
10399
                        // parse separator (:)
10400
0
                        if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10401
0
                        {
10402
0
                            return sax->parse_error(m_lexer.get_position(),
10403
0
                                                    m_lexer.get_token_string(),
10404
0
                                                    parse_error::create(101, m_lexer.get_position(),
10405
0
                                                            exception_message(token_type::name_separator, "object separator")));
10406
0
                        }
10407
10408
                        // remember we are now inside an object
10409
0
                        states.push_back(false);
10410
10411
                        // parse values
10412
0
                        get_token();
10413
0
                        continue;
10414
0
                    }
10415
10416
0
                    case token_type::begin_array:
10417
0
                    {
10418
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10419
0
                        {
10420
0
                            return false;
10421
0
                        }
10422
10423
                        // closing ] -> we are done
10424
0
                        if (get_token() == token_type::end_array)
10425
0
                        {
10426
0
                            if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10427
0
                            {
10428
0
                                return false;
10429
0
                            }
10430
0
                            break;
10431
0
                        }
10432
10433
                        // remember we are now inside an array
10434
0
                        states.push_back(true);
10435
10436
                        // parse values (no need to call get_token)
10437
0
                        continue;
10438
0
                    }
10439
10440
0
                    case token_type::value_float:
10441
0
                    {
10442
0
                        const auto res = m_lexer.get_number_float();
10443
10444
0
                        if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10445
0
                        {
10446
0
                            return sax->parse_error(m_lexer.get_position(),
10447
0
                                                    m_lexer.get_token_string(),
10448
0
                                                    out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
10449
0
                        }
10450
10451
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10452
0
                        {
10453
0
                            return false;
10454
0
                        }
10455
10456
0
                        break;
10457
0
                    }
10458
10459
0
                    case token_type::literal_false:
10460
0
                    {
10461
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10462
0
                        {
10463
0
                            return false;
10464
0
                        }
10465
0
                        break;
10466
0
                    }
10467
10468
0
                    case token_type::literal_null:
10469
0
                    {
10470
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10471
0
                        {
10472
0
                            return false;
10473
0
                        }
10474
0
                        break;
10475
0
                    }
10476
10477
0
                    case token_type::literal_true:
10478
0
                    {
10479
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10480
0
                        {
10481
0
                            return false;
10482
0
                        }
10483
0
                        break;
10484
0
                    }
10485
10486
0
                    case token_type::value_integer:
10487
0
                    {
10488
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10489
0
                        {
10490
0
                            return false;
10491
0
                        }
10492
0
                        break;
10493
0
                    }
10494
10495
0
                    case token_type::value_string:
10496
0
                    {
10497
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10498
0
                        {
10499
0
                            return false;
10500
0
                        }
10501
0
                        break;
10502
0
                    }
10503
10504
0
                    case token_type::value_unsigned:
10505
0
                    {
10506
0
                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10507
0
                        {
10508
0
                            return false;
10509
0
                        }
10510
0
                        break;
10511
0
                    }
10512
10513
0
                    case token_type::parse_error:
10514
0
                    {
10515
                        // using "uninitialized" to avoid "expected" message
10516
0
                        return sax->parse_error(m_lexer.get_position(),
10517
0
                                                m_lexer.get_token_string(),
10518
0
                                                parse_error::create(101, m_lexer.get_position(),
10519
0
                                                        exception_message(token_type::uninitialized, "value")));
10520
0
                    }
10521
10522
0
                    default: // the last token was unexpected
10523
0
                    {
10524
0
                        return sax->parse_error(m_lexer.get_position(),
10525
0
                                                m_lexer.get_token_string(),
10526
0
                                                parse_error::create(101, m_lexer.get_position(),
10527
0
                                                        exception_message(token_type::literal_or_value, "value")));
10528
0
                    }
10529
0
                }
10530
0
            }
10531
0
            else
10532
0
            {
10533
0
                skip_to_state_evaluation = false;
10534
0
            }
10535
10536
            // we reached this line after we successfully parsed a value
10537
0
            if (states.empty())
10538
0
            {
10539
                // empty stack: we reached the end of the hierarchy: done
10540
0
                return true;
10541
0
            }
10542
10543
0
            if (states.back())  // array
10544
0
            {
10545
                // comma -> next value
10546
0
                if (get_token() == token_type::value_separator)
10547
0
                {
10548
                    // parse a new value
10549
0
                    get_token();
10550
0
                    continue;
10551
0
                }
10552
10553
                // closing ]
10554
0
                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
10555
0
                {
10556
0
                    if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10557
0
                    {
10558
0
                        return false;
10559
0
                    }
10560
10561
                    // We are done with this array. Before we can parse a
10562
                    // new value, we need to evaluate the new state first.
10563
                    // By setting skip_to_state_evaluation to false, we
10564
                    // are effectively jumping to the beginning of this if.
10565
0
                    JSON_ASSERT(!states.empty());
10566
0
                    states.pop_back();
10567
0
                    skip_to_state_evaluation = true;
10568
0
                    continue;
10569
0
                }
10570
10571
0
                return sax->parse_error(m_lexer.get_position(),
10572
0
                                        m_lexer.get_token_string(),
10573
0
                                        parse_error::create(101, m_lexer.get_position(),
10574
0
                                                exception_message(token_type::end_array, "array")));
10575
0
            }
10576
0
            else  // object
10577
0
            {
10578
                // comma -> next value
10579
0
                if (get_token() == token_type::value_separator)
10580
0
                {
10581
                    // parse key
10582
0
                    if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10583
0
                    {
10584
0
                        return sax->parse_error(m_lexer.get_position(),
10585
0
                                                m_lexer.get_token_string(),
10586
0
                                                parse_error::create(101, m_lexer.get_position(),
10587
0
                                                        exception_message(token_type::value_string, "object key")));
10588
0
                    }
10589
10590
0
                    if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10591
0
                    {
10592
0
                        return false;
10593
0
                    }
10594
10595
                    // parse separator (:)
10596
0
                    if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10597
0
                    {
10598
0
                        return sax->parse_error(m_lexer.get_position(),
10599
0
                                                m_lexer.get_token_string(),
10600
0
                                                parse_error::create(101, m_lexer.get_position(),
10601
0
                                                        exception_message(token_type::name_separator, "object separator")));
10602
0
                    }
10603
10604
                    // parse values
10605
0
                    get_token();
10606
0
                    continue;
10607
0
                }
10608
10609
                // closing }
10610
0
                if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10611
0
                {
10612
0
                    if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10613
0
                    {
10614
0
                        return false;
10615
0
                    }
10616
10617
                    // We are done with this object. Before we can parse a
10618
                    // new value, we need to evaluate the new state first.
10619
                    // By setting skip_to_state_evaluation to false, we
10620
                    // are effectively jumping to the beginning of this if.
10621
0
                    JSON_ASSERT(!states.empty());
10622
0
                    states.pop_back();
10623
0
                    skip_to_state_evaluation = true;
10624
0
                    continue;
10625
0
                }
10626
10627
0
                return sax->parse_error(m_lexer.get_position(),
10628
0
                                        m_lexer.get_token_string(),
10629
0
                                        parse_error::create(101, m_lexer.get_position(),
10630
0
                                                exception_message(token_type::end_object, "object")));
10631
0
            }
10632
0
        }
10633
0
    }
Unexecuted instantiation: bool nlohmann::detail::parser<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, 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> > > >*)
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_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> > > >*)
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::input_stream_adapter>::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> > > >*)
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::input_stream_adapter>::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> > > >*)
10634
10635
    /// get next token from lexer
10636
    token_type get_token()
10637
0
    {
10638
0
        return last_token = m_lexer.scan();
10639
0
    }
Unexecuted instantiation: 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*> >::get_token()
Unexecuted instantiation: 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::input_stream_adapter>::get_token()
10640
10641
    std::string exception_message(const token_type expected, const std::string& context)
10642
0
    {
10643
0
        std::string error_msg = "syntax error ";
10644
10645
0
        if (!context.empty())
10646
0
        {
10647
0
            error_msg += "while parsing " + context + " ";
10648
0
        }
10649
10650
0
        error_msg += "- ";
10651
10652
0
        if (last_token == token_type::parse_error)
10653
0
        {
10654
0
            error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10655
0
                         m_lexer.get_token_string() + "'";
10656
0
        }
10657
0
        else
10658
0
        {
10659
0
            error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10660
0
        }
10661
10662
0
        if (expected != token_type::uninitialized)
10663
0
        {
10664
0
            error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10665
0
        }
10666
10667
0
        return error_msg;
10668
0
    }
Unexecuted instantiation: 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*> >::exception_message(nlohmann::detail::lexer_base<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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> > > >::token_type, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: 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::input_stream_adapter>::exception_message(nlohmann::detail::lexer_base<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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> > > >::token_type, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
10669
10670
  private:
10671
    /// callback function
10672
    const parser_callback_t<BasicJsonType> callback = nullptr;
10673
    /// the type of the last read token
10674
    token_type last_token = token_type::uninitialized;
10675
    /// the lexer
10676
    lexer_t m_lexer;
10677
    /// whether to throw exceptions in case of errors
10678
    const bool allow_exceptions = true;
10679
};
10680
}  // namespace detail
10681
}  // namespace nlohmann
10682
10683
// #include <nlohmann/detail/iterators/internal_iterator.hpp>
10684
10685
10686
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10687
10688
10689
#include <cstddef> // ptrdiff_t
10690
#include <limits>  // numeric_limits
10691
10692
namespace nlohmann
10693
{
10694
namespace detail
10695
{
10696
/*
10697
@brief an iterator for primitive JSON types
10698
10699
This class models an iterator for primitive JSON types (boolean, number,
10700
string). It's only purpose is to allow the iterator/const_iterator classes
10701
to "iterate" over primitive values. Internally, the iterator is modeled by
10702
a `difference_type` variable. Value begin_value (`0`) models the begin,
10703
end_value (`1`) models past the end.
10704
*/
10705
class primitive_iterator_t
10706
{
10707
  private:
10708
    using difference_type = std::ptrdiff_t;
10709
    static constexpr difference_type begin_value = 0;
10710
    static constexpr difference_type end_value = begin_value + 1;
10711
10712
  JSON_PRIVATE_UNLESS_TESTED:
10713
    /// iterator as signed integer type
10714
    difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10715
10716
  public:
10717
    constexpr difference_type get_value() const noexcept
10718
0
    {
10719
0
        return m_it;
10720
0
    }
10721
10722
    /// set iterator to a defined beginning
10723
    void set_begin() noexcept
10724
0
    {
10725
0
        m_it = begin_value;
10726
0
    }
10727
10728
    /// set iterator to a defined past the end
10729
    void set_end() noexcept
10730
0
    {
10731
0
        m_it = end_value;
10732
0
    }
10733
10734
    /// return whether the iterator can be dereferenced
10735
    constexpr bool is_begin() const noexcept
10736
0
    {
10737
0
        return m_it == begin_value;
10738
0
    }
10739
10740
    /// return whether the iterator is at end
10741
    constexpr bool is_end() const noexcept
10742
0
    {
10743
0
        return m_it == end_value;
10744
0
    }
10745
10746
    friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10747
0
    {
10748
0
        return lhs.m_it == rhs.m_it;
10749
0
    }
10750
10751
    friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10752
0
    {
10753
0
        return lhs.m_it < rhs.m_it;
10754
0
    }
10755
10756
    primitive_iterator_t operator+(difference_type n) noexcept
10757
0
    {
10758
0
        auto result = *this;
10759
0
        result += n;
10760
0
        return result;
10761
0
    }
10762
10763
    friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10764
0
    {
10765
0
        return lhs.m_it - rhs.m_it;
10766
0
    }
10767
10768
    primitive_iterator_t& operator++() noexcept
10769
0
    {
10770
0
        ++m_it;
10771
0
        return *this;
10772
0
    }
10773
10774
    primitive_iterator_t const operator++(int) noexcept
10775
0
    {
10776
0
        auto result = *this;
10777
0
        ++m_it;
10778
0
        return result;
10779
0
    }
10780
10781
    primitive_iterator_t& operator--() noexcept
10782
0
    {
10783
0
        --m_it;
10784
0
        return *this;
10785
0
    }
10786
10787
    primitive_iterator_t const operator--(int) noexcept
10788
0
    {
10789
0
        auto result = *this;
10790
0
        --m_it;
10791
0
        return result;
10792
0
    }
10793
10794
    primitive_iterator_t& operator+=(difference_type n) noexcept
10795
0
    {
10796
0
        m_it += n;
10797
0
        return *this;
10798
0
    }
10799
10800
    primitive_iterator_t& operator-=(difference_type n) noexcept
10801
0
    {
10802
0
        m_it -= n;
10803
0
        return *this;
10804
0
    }
10805
};
10806
}  // namespace detail
10807
}  // namespace nlohmann
10808
10809
10810
namespace nlohmann
10811
{
10812
namespace detail
10813
{
10814
/*!
10815
@brief an iterator value
10816
10817
@note This structure could easily be a union, but MSVC currently does not allow
10818
unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
10819
*/
10820
template<typename BasicJsonType> struct internal_iterator
10821
{
10822
    /// iterator for JSON objects
10823
    typename BasicJsonType::object_t::iterator object_iterator {};
10824
    /// iterator for JSON arrays
10825
    typename BasicJsonType::array_t::iterator array_iterator {};
10826
    /// generic iterator for all other types
10827
    primitive_iterator_t primitive_iterator {};
10828
};
10829
}  // namespace detail
10830
}  // namespace nlohmann
10831
10832
// #include <nlohmann/detail/iterators/iter_impl.hpp>
10833
10834
10835
#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10836
#include <type_traits> // conditional, is_const, remove_const
10837
10838
// #include <nlohmann/detail/exceptions.hpp>
10839
10840
// #include <nlohmann/detail/iterators/internal_iterator.hpp>
10841
10842
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10843
10844
// #include <nlohmann/detail/macro_scope.hpp>
10845
10846
// #include <nlohmann/detail/meta/cpp_future.hpp>
10847
10848
// #include <nlohmann/detail/meta/type_traits.hpp>
10849
10850
// #include <nlohmann/detail/value_t.hpp>
10851
10852
10853
namespace nlohmann
10854
{
10855
namespace detail
10856
{
10857
// forward declare, to be able to friend it later on
10858
template<typename IteratorType> class iteration_proxy;
10859
template<typename IteratorType> class iteration_proxy_value;
10860
10861
/*!
10862
@brief a template for a bidirectional iterator for the @ref basic_json class
10863
This class implements a both iterators (iterator and const_iterator) for the
10864
@ref basic_json class.
10865
@note An iterator is called *initialized* when a pointer to a JSON value has
10866
      been set (e.g., by a constructor or a copy assignment). If the iterator is
10867
      default-constructed, it is *uninitialized* and most methods are undefined.
10868
      **The library uses assertions to detect calls on uninitialized iterators.**
10869
@requirement The class satisfies the following concept requirements:
10870
-
10871
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
10872
  The iterator that can be moved can be moved in both directions (i.e.
10873
  incremented and decremented).
10874
@since version 1.0.0, simplified in version 2.0.9, change to bidirectional
10875
       iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
10876
*/
10877
template<typename BasicJsonType>
10878
class iter_impl
10879
{
10880
    /// allow basic_json to access private members
10881
    friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10882
    friend BasicJsonType;
10883
    friend iteration_proxy<iter_impl>;
10884
    friend iteration_proxy_value<iter_impl>;
10885
10886
    using object_t = typename BasicJsonType::object_t;
10887
    using array_t = typename BasicJsonType::array_t;
10888
    // make sure BasicJsonType is basic_json or const basic_json
10889
    static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10890
                  "iter_impl only accepts (const) basic_json");
10891
10892
  public:
10893
10894
    /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
10895
    /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
10896
    /// A user-defined iterator should provide publicly accessible typedefs named
10897
    /// iterator_category, value_type, difference_type, pointer, and reference.
10898
    /// Note that value_type is required to be non-const, even for constant iterators.
10899
    using iterator_category = std::bidirectional_iterator_tag;
10900
10901
    /// the type of the values when the iterator is dereferenced
10902
    using value_type = typename BasicJsonType::value_type;
10903
    /// a type to represent differences between iterators
10904
    using difference_type = typename BasicJsonType::difference_type;
10905
    /// defines a pointer to the type iterated over (value_type)
10906
    using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10907
          typename BasicJsonType::const_pointer,
10908
          typename BasicJsonType::pointer>::type;
10909
    /// defines a reference to the type iterated over (value_type)
10910
    using reference =
10911
        typename std::conditional<std::is_const<BasicJsonType>::value,
10912
        typename BasicJsonType::const_reference,
10913
        typename BasicJsonType::reference>::type;
10914
10915
    /// default constructor
10916
    iter_impl() = default;
10917
10918
    /*!
10919
    @brief constructor for a given JSON instance
10920
    @param[in] object  pointer to a JSON object for this iterator
10921
    @pre object != nullptr
10922
    @post The iterator is initialized; i.e. `m_object != nullptr`.
10923
    */
10924
    explicit iter_impl(pointer object) noexcept : m_object(object)
10925
0
    {
10926
0
        JSON_ASSERT(m_object != nullptr);
10927
10928
0
        switch (m_object->m_type)
10929
0
        {
10930
0
            case value_t::object:
10931
0
            {
10932
0
                m_it.object_iterator = typename object_t::iterator();
10933
0
                break;
10934
0
            }
10935
10936
0
            case value_t::array:
10937
0
            {
10938
0
                m_it.array_iterator = typename array_t::iterator();
10939
0
                break;
10940
0
            }
10941
10942
0
            default:
10943
0
            {
10944
0
                m_it.primitive_iterator = primitive_iterator_t();
10945
0
                break;
10946
0
            }
10947
0
        }
10948
0
    }
10949
10950
    /*!
10951
    @note The conventional copy constructor and copy assignment are implicitly
10952
          defined. Combined with the following converting constructor and
10953
          assignment, they support: (1) copy from iterator to iterator, (2)
10954
          copy from const iterator to const iterator, and (3) conversion from
10955
          iterator to const iterator. However conversion from const iterator
10956
          to iterator is not defined.
10957
    */
10958
10959
    /*!
10960
    @brief const copy constructor
10961
    @param[in] other const iterator to copy from
10962
    @note This copy constructor had to be defined explicitly to circumvent a bug
10963
          occurring on msvc v19.0 compiler (VS 2015) debug build. For more
10964
          information refer to: https://github.com/nlohmann/json/issues/1608
10965
    */
10966
    iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10967
        : m_object(other.m_object), m_it(other.m_it)
10968
    {}
10969
10970
    /*!
10971
    @brief converting assignment
10972
    @param[in] other const iterator to copy from
10973
    @return const/non-const iterator
10974
    @note It is not checked whether @a other is initialized.
10975
    */
10976
    iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10977
    {
10978
        m_object = other.m_object;
10979
        m_it = other.m_it;
10980
        return *this;
10981
    }
10982
10983
    /*!
10984
    @brief converting constructor
10985
    @param[in] other  non-const iterator to copy from
10986
    @note It is not checked whether @a other is initialized.
10987
    */
10988
    iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10989
        : m_object(other.m_object), m_it(other.m_it)
10990
0
    {}
10991
10992
    /*!
10993
    @brief converting assignment
10994
    @param[in] other  non-const iterator to copy from
10995
    @return const/non-const iterator
10996
    @note It is not checked whether @a other is initialized.
10997
    */
10998
    iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10999
    {
11000
        m_object = other.m_object;
11001
        m_it = other.m_it;
11002
        return *this;
11003
    }
11004
11005
  JSON_PRIVATE_UNLESS_TESTED:
11006
    /*!
11007
    @brief set the iterator to the first value
11008
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11009
    */
11010
    void set_begin() noexcept
11011
0
    {
11012
0
        JSON_ASSERT(m_object != nullptr);
11013
11014
0
        switch (m_object->m_type)
11015
0
        {
11016
0
            case value_t::object:
11017
0
            {
11018
0
                m_it.object_iterator = m_object->m_value.object->begin();
11019
0
                break;
11020
0
            }
11021
11022
0
            case value_t::array:
11023
0
            {
11024
0
                m_it.array_iterator = m_object->m_value.array->begin();
11025
0
                break;
11026
0
            }
11027
11028
0
            case value_t::null:
11029
0
            {
11030
                // set to end so begin()==end() is true: null is empty
11031
0
                m_it.primitive_iterator.set_end();
11032
0
                break;
11033
0
            }
11034
11035
0
            default:
11036
0
            {
11037
0
                m_it.primitive_iterator.set_begin();
11038
0
                break;
11039
0
            }
11040
0
        }
11041
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::set_begin()
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::set_begin()
11042
11043
    /*!
11044
    @brief set the iterator past the last value
11045
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11046
    */
11047
    void set_end() noexcept
11048
0
    {
11049
0
        JSON_ASSERT(m_object != nullptr);
11050
11051
0
        switch (m_object->m_type)
11052
0
        {
11053
0
            case value_t::object:
11054
0
            {
11055
0
                m_it.object_iterator = m_object->m_value.object->end();
11056
0
                break;
11057
0
            }
11058
11059
0
            case value_t::array:
11060
0
            {
11061
0
                m_it.array_iterator = m_object->m_value.array->end();
11062
0
                break;
11063
0
            }
11064
11065
0
            default:
11066
0
            {
11067
0
                m_it.primitive_iterator.set_end();
11068
0
                break;
11069
0
            }
11070
0
        }
11071
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::set_end()
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::set_end()
11072
11073
  public:
11074
    /*!
11075
    @brief return a reference to the value pointed to by the iterator
11076
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11077
    */
11078
    reference operator*() const
11079
0
    {
11080
0
        JSON_ASSERT(m_object != nullptr);
11081
11082
0
        switch (m_object->m_type)
11083
0
        {
11084
0
            case value_t::object:
11085
0
            {
11086
0
                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11087
0
                return m_it.object_iterator->second;
11088
0
            }
11089
11090
0
            case value_t::array:
11091
0
            {
11092
0
                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11093
0
                return *m_it.array_iterator;
11094
0
            }
11095
11096
0
            case value_t::null:
11097
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11098
11099
0
            default:
11100
0
            {
11101
0
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11102
0
                {
11103
0
                    return *m_object;
11104
0
                }
11105
11106
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11107
0
            }
11108
0
        }
11109
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::operator*() const
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::operator*() const
11110
11111
    /*!
11112
    @brief dereference the iterator
11113
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11114
    */
11115
    pointer operator->() const
11116
0
    {
11117
0
        JSON_ASSERT(m_object != nullptr);
11118
11119
0
        switch (m_object->m_type)
11120
0
        {
11121
0
            case value_t::object:
11122
0
            {
11123
0
                JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11124
0
                return &(m_it.object_iterator->second);
11125
0
            }
11126
11127
0
            case value_t::array:
11128
0
            {
11129
0
                JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11130
0
                return &*m_it.array_iterator;
11131
0
            }
11132
11133
0
            default:
11134
0
            {
11135
0
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11136
0
                {
11137
0
                    return m_object;
11138
0
                }
11139
11140
0
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11141
0
            }
11142
0
        }
11143
0
    }
11144
11145
    /*!
11146
    @brief post-increment (it++)
11147
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11148
    */
11149
    iter_impl const operator++(int)
11150
    {
11151
        auto result = *this;
11152
        ++(*this);
11153
        return result;
11154
    }
11155
11156
    /*!
11157
    @brief pre-increment (++it)
11158
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11159
    */
11160
    iter_impl& operator++()
11161
0
    {
11162
0
        JSON_ASSERT(m_object != nullptr);
11163
11164
0
        switch (m_object->m_type)
11165
0
        {
11166
0
            case value_t::object:
11167
0
            {
11168
0
                std::advance(m_it.object_iterator, 1);
11169
0
                break;
11170
0
            }
11171
11172
0
            case value_t::array:
11173
0
            {
11174
0
                std::advance(m_it.array_iterator, 1);
11175
0
                break;
11176
0
            }
11177
11178
0
            default:
11179
0
            {
11180
0
                ++m_it.primitive_iterator;
11181
0
                break;
11182
0
            }
11183
0
        }
11184
11185
0
        return *this;
11186
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::operator++()
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::operator++()
11187
11188
    /*!
11189
    @brief post-decrement (it--)
11190
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11191
    */
11192
    iter_impl const operator--(int)
11193
    {
11194
        auto result = *this;
11195
        --(*this);
11196
        return result;
11197
    }
11198
11199
    /*!
11200
    @brief pre-decrement (--it)
11201
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11202
    */
11203
    iter_impl& operator--()
11204
    {
11205
        JSON_ASSERT(m_object != nullptr);
11206
11207
        switch (m_object->m_type)
11208
        {
11209
            case value_t::object:
11210
            {
11211
                std::advance(m_it.object_iterator, -1);
11212
                break;
11213
            }
11214
11215
            case value_t::array:
11216
            {
11217
                std::advance(m_it.array_iterator, -1);
11218
                break;
11219
            }
11220
11221
            default:
11222
            {
11223
                --m_it.primitive_iterator;
11224
                break;
11225
            }
11226
        }
11227
11228
        return *this;
11229
    }
11230
11231
    /*!
11232
    @brief  comparison: equal
11233
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11234
    */
11235
    bool operator==(const iter_impl& other) const
11236
0
    {
11237
        // if objects are not the same, the comparison is undefined
11238
0
        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11239
0
        {
11240
0
            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11241
0
        }
11242
11243
0
        JSON_ASSERT(m_object != nullptr);
11244
11245
0
        switch (m_object->m_type)
11246
0
        {
11247
0
            case value_t::object:
11248
0
                return (m_it.object_iterator == other.m_it.object_iterator);
11249
11250
0
            case value_t::array:
11251
0
                return (m_it.array_iterator == other.m_it.array_iterator);
11252
11253
0
            default:
11254
0
                return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11255
0
        }
11256
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, 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> const&) const
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, 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&) const
11257
11258
    /*!
11259
    @brief  comparison: not equal
11260
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11261
    */
11262
    bool operator!=(const iter_impl& other) const
11263
0
    {
11264
0
        return !operator==(other);
11265
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, 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> const&) const
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, 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&) const
11266
11267
    /*!
11268
    @brief  comparison: smaller
11269
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11270
    */
11271
    bool operator<(const iter_impl& other) const
11272
    {
11273
        // if objects are not the same, the comparison is undefined
11274
        if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11275
        {
11276
            JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11277
        }
11278
11279
        JSON_ASSERT(m_object != nullptr);
11280
11281
        switch (m_object->m_type)
11282
        {
11283
            case value_t::object:
11284
                JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
11285
11286
            case value_t::array:
11287
                return (m_it.array_iterator < other.m_it.array_iterator);
11288
11289
            default:
11290
                return (m_it.primitive_iterator < other.m_it.primitive_iterator);
11291
        }
11292
    }
11293
11294
    /*!
11295
    @brief  comparison: less than or equal
11296
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11297
    */
11298
    bool operator<=(const iter_impl& other) const
11299
    {
11300
        return !other.operator < (*this);
11301
    }
11302
11303
    /*!
11304
    @brief  comparison: greater than
11305
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11306
    */
11307
    bool operator>(const iter_impl& other) const
11308
    {
11309
        return !operator<=(other);
11310
    }
11311
11312
    /*!
11313
    @brief  comparison: greater than or equal
11314
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11315
    */
11316
    bool operator>=(const iter_impl& other) const
11317
    {
11318
        return !operator<(other);
11319
    }
11320
11321
    /*!
11322
    @brief  add to iterator
11323
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11324
    */
11325
    iter_impl& operator+=(difference_type i)
11326
    {
11327
        JSON_ASSERT(m_object != nullptr);
11328
11329
        switch (m_object->m_type)
11330
        {
11331
            case value_t::object:
11332
                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11333
11334
            case value_t::array:
11335
            {
11336
                std::advance(m_it.array_iterator, i);
11337
                break;
11338
            }
11339
11340
            default:
11341
            {
11342
                m_it.primitive_iterator += i;
11343
                break;
11344
            }
11345
        }
11346
11347
        return *this;
11348
    }
11349
11350
    /*!
11351
    @brief  subtract from iterator
11352
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11353
    */
11354
    iter_impl& operator-=(difference_type i)
11355
    {
11356
        return operator+=(-i);
11357
    }
11358
11359
    /*!
11360
    @brief  add to iterator
11361
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11362
    */
11363
    iter_impl operator+(difference_type i) const
11364
    {
11365
        auto result = *this;
11366
        result += i;
11367
        return result;
11368
    }
11369
11370
    /*!
11371
    @brief  addition of distance and iterator
11372
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11373
    */
11374
    friend iter_impl operator+(difference_type i, const iter_impl& it)
11375
    {
11376
        auto result = it;
11377
        result += i;
11378
        return result;
11379
    }
11380
11381
    /*!
11382
    @brief  subtract from iterator
11383
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11384
    */
11385
    iter_impl operator-(difference_type i) const
11386
    {
11387
        auto result = *this;
11388
        result -= i;
11389
        return result;
11390
    }
11391
11392
    /*!
11393
    @brief  return difference
11394
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11395
    */
11396
    difference_type operator-(const iter_impl& other) const
11397
    {
11398
        JSON_ASSERT(m_object != nullptr);
11399
11400
        switch (m_object->m_type)
11401
        {
11402
            case value_t::object:
11403
                JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11404
11405
            case value_t::array:
11406
                return m_it.array_iterator - other.m_it.array_iterator;
11407
11408
            default:
11409
                return m_it.primitive_iterator - other.m_it.primitive_iterator;
11410
        }
11411
    }
11412
11413
    /*!
11414
    @brief  access to successor
11415
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11416
    */
11417
    reference operator[](difference_type n) const
11418
    {
11419
        JSON_ASSERT(m_object != nullptr);
11420
11421
        switch (m_object->m_type)
11422
        {
11423
            case value_t::object:
11424
                JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
11425
11426
            case value_t::array:
11427
                return *std::next(m_it.array_iterator, n);
11428
11429
            case value_t::null:
11430
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11431
11432
            default:
11433
            {
11434
                if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
11435
                {
11436
                    return *m_object;
11437
                }
11438
11439
                JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11440
            }
11441
        }
11442
    }
11443
11444
    /*!
11445
    @brief  return the key of an object iterator
11446
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11447
    */
11448
    const typename object_t::key_type& key() const
11449
0
    {
11450
0
        JSON_ASSERT(m_object != nullptr);
11451
11452
0
        if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11453
0
        {
11454
0
            return m_it.object_iterator->first;
11455
0
        }
11456
11457
0
        JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
11458
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::key() const
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::key() const
11459
11460
    /*!
11461
    @brief  return the value of an iterator
11462
    @pre The iterator is initialized; i.e. `m_object != nullptr`.
11463
    */
11464
    reference value() const
11465
0
    {
11466
0
        return operator*();
11467
0
    }
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > const>::value() const
Unexecuted instantiation: nlohmann::detail::iter_impl<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::value() const
11468
11469
  JSON_PRIVATE_UNLESS_TESTED:
11470
    /// associated JSON instance
11471
    pointer m_object = nullptr;
11472
    /// the actual iterator of the associated instance
11473
    internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
11474
};
11475
} // namespace detail
11476
} // namespace nlohmann
11477
11478
// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11479
11480
// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11481
11482
11483
#include <cstddef> // ptrdiff_t
11484
#include <iterator> // reverse_iterator
11485
#include <utility> // declval
11486
11487
namespace nlohmann
11488
{
11489
namespace detail
11490
{
11491
//////////////////////
11492
// reverse_iterator //
11493
//////////////////////
11494
11495
/*!
11496
@brief a template for a reverse iterator class
11497
11498
@tparam Base the base iterator type to reverse. Valid types are @ref
11499
iterator (to create @ref reverse_iterator) and @ref const_iterator (to
11500
create @ref const_reverse_iterator).
11501
11502
@requirement The class satisfies the following concept requirements:
11503
-
11504
[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
11505
  The iterator that can be moved can be moved in both directions (i.e.
11506
  incremented and decremented).
11507
- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
11508
  It is possible to write to the pointed-to element (only if @a Base is
11509
  @ref iterator).
11510
11511
@since version 1.0.0
11512
*/
11513
template<typename Base>
11514
class json_reverse_iterator : public std::reverse_iterator<Base>
11515
{
11516
  public:
11517
    using difference_type = std::ptrdiff_t;
11518
    /// shortcut to the reverse iterator adapter
11519
    using base_iterator = std::reverse_iterator<Base>;
11520
    /// the reference type for the pointed-to element
11521
    using reference = typename Base::reference;
11522
11523
    /// create reverse iterator from iterator
11524
    explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
11525
        : base_iterator(it) {}
11526
11527
    /// create reverse iterator from base class
11528
    explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
11529
11530
    /// post-increment (it++)
11531
    json_reverse_iterator const operator++(int)
11532
    {
11533
        return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
11534
    }
11535
11536
    /// pre-increment (++it)
11537
    json_reverse_iterator& operator++()
11538
    {
11539
        return static_cast<json_reverse_iterator&>(base_iterator::operator++());
11540
    }
11541
11542
    /// post-decrement (it--)
11543
    json_reverse_iterator const operator--(int)
11544
    {
11545
        return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
11546
    }
11547
11548
    /// pre-decrement (--it)
11549
    json_reverse_iterator& operator--()
11550
    {
11551
        return static_cast<json_reverse_iterator&>(base_iterator::operator--());
11552
    }
11553
11554
    /// add to iterator
11555
    json_reverse_iterator& operator+=(difference_type i)
11556
    {
11557
        return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
11558
    }
11559
11560
    /// add to iterator
11561
    json_reverse_iterator operator+(difference_type i) const
11562
    {
11563
        return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11564
    }
11565
11566
    /// subtract from iterator
11567
    json_reverse_iterator operator-(difference_type i) const
11568
    {
11569
        return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11570
    }
11571
11572
    /// return difference
11573
    difference_type operator-(const json_reverse_iterator& other) const
11574
    {
11575
        return base_iterator(*this) - base_iterator(other);
11576
    }
11577
11578
    /// access to successor
11579
    reference operator[](difference_type n) const
11580
    {
11581
        return *(this->operator+(n));
11582
    }
11583
11584
    /// return the key of an object iterator
11585
    auto key() const -> decltype(std::declval<Base>().key())
11586
    {
11587
        auto it = --this->base();
11588
        return it.key();
11589
    }
11590
11591
    /// return the value of an iterator
11592
    reference value() const
11593
    {
11594
        auto it = --this->base();
11595
        return it.operator * ();
11596
    }
11597
};
11598
}  // namespace detail
11599
}  // namespace nlohmann
11600
11601
// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11602
11603
// #include <nlohmann/detail/json_pointer.hpp>
11604
11605
11606
#include <algorithm> // all_of
11607
#include <cctype> // isdigit
11608
#include <limits> // max
11609
#include <numeric> // accumulate
11610
#include <string> // string
11611
#include <utility> // move
11612
#include <vector> // vector
11613
11614
// #include <nlohmann/detail/exceptions.hpp>
11615
11616
// #include <nlohmann/detail/macro_scope.hpp>
11617
11618
// #include <nlohmann/detail/value_t.hpp>
11619
11620
11621
namespace nlohmann
11622
{
11623
template<typename BasicJsonType>
11624
class json_pointer
11625
{
11626
    // allow basic_json to access private members
11627
    NLOHMANN_BASIC_JSON_TPL_DECLARATION
11628
    friend class basic_json;
11629
11630
  public:
11631
    /*!
11632
    @brief create JSON pointer
11633
11634
    Create a JSON pointer according to the syntax described in
11635
    [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
11636
11637
    @param[in] s  string representing the JSON pointer; if omitted, the empty
11638
                  string is assumed which references the whole JSON value
11639
11640
    @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
11641
                           not begin with a slash (`/`); see example below
11642
11643
    @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
11644
    not followed by `0` (representing `~`) or `1` (representing `/`); see
11645
    example below
11646
11647
    @liveexample{The example shows the construction several valid JSON pointers
11648
    as well as the exceptional behavior.,json_pointer}
11649
11650
    @since version 2.0.0
11651
    */
11652
    explicit json_pointer(const std::string& s = "")
11653
        : reference_tokens(split(s))
11654
    {}
11655
11656
    /*!
11657
    @brief return a string representation of the JSON pointer
11658
11659
    @invariant For each JSON pointer `ptr`, it holds:
11660
    @code {.cpp}
11661
    ptr == json_pointer(ptr.to_string());
11662
    @endcode
11663
11664
    @return a string representation of the JSON pointer
11665
11666
    @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
11667
11668
    @since version 2.0.0
11669
    */
11670
    std::string to_string() const
11671
    {
11672
        return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11673
                               std::string{},
11674
                               [](const std::string & a, const std::string & b)
11675
        {
11676
            return a + "/" + escape(b);
11677
        });
11678
    }
11679
11680
    /// @copydoc to_string()
11681
    operator std::string() const
11682
    {
11683
        return to_string();
11684
    }
11685
11686
    /*!
11687
    @brief append another JSON pointer at the end of this JSON pointer
11688
11689
    @param[in] ptr  JSON pointer to append
11690
    @return JSON pointer with @a ptr appended
11691
11692
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11693
11694
    @complexity Linear in the length of @a ptr.
11695
11696
    @sa @ref operator/=(std::string) to append a reference token
11697
    @sa @ref operator/=(std::size_t) to append an array index
11698
    @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
11699
11700
    @since version 3.6.0
11701
    */
11702
    json_pointer& operator/=(const json_pointer& ptr)
11703
    {
11704
        reference_tokens.insert(reference_tokens.end(),
11705
                                ptr.reference_tokens.begin(),
11706
                                ptr.reference_tokens.end());
11707
        return *this;
11708
    }
11709
11710
    /*!
11711
    @brief append an unescaped reference token at the end of this JSON pointer
11712
11713
    @param[in] token  reference token to append
11714
    @return JSON pointer with @a token appended without escaping @a token
11715
11716
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11717
11718
    @complexity Amortized constant.
11719
11720
    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11721
    @sa @ref operator/=(std::size_t) to append an array index
11722
    @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
11723
11724
    @since version 3.6.0
11725
    */
11726
    json_pointer& operator/=(std::string token)
11727
    {
11728
        push_back(std::move(token));
11729
        return *this;
11730
    }
11731
11732
    /*!
11733
    @brief append an array index at the end of this JSON pointer
11734
11735
    @param[in] array_idx  array index to append
11736
    @return JSON pointer with @a array_idx appended
11737
11738
    @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11739
11740
    @complexity Amortized constant.
11741
11742
    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11743
    @sa @ref operator/=(std::string) to append a reference token
11744
    @sa @ref operator/(const json_pointer&, std::string) for a binary operator
11745
11746
    @since version 3.6.0
11747
    */
11748
    json_pointer& operator/=(std::size_t array_idx)
11749
    {
11750
        return *this /= std::to_string(array_idx);
11751
    }
11752
11753
    /*!
11754
    @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
11755
11756
    @param[in] lhs  JSON pointer
11757
    @param[in] rhs  JSON pointer
11758
    @return a new JSON pointer with @a rhs appended to @a lhs
11759
11760
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11761
11762
    @complexity Linear in the length of @a lhs and @a rhs.
11763
11764
    @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11765
11766
    @since version 3.6.0
11767
    */
11768
    friend json_pointer operator/(const json_pointer& lhs,
11769
                                  const json_pointer& rhs)
11770
    {
11771
        return json_pointer(lhs) /= rhs;
11772
    }
11773
11774
    /*!
11775
    @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
11776
11777
    @param[in] ptr  JSON pointer
11778
    @param[in] token  reference token
11779
    @return a new JSON pointer with unescaped @a token appended to @a ptr
11780
11781
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11782
11783
    @complexity Linear in the length of @a ptr.
11784
11785
    @sa @ref operator/=(std::string) to append a reference token
11786
11787
    @since version 3.6.0
11788
    */
11789
    friend json_pointer operator/(const json_pointer& ptr, std::string token)
11790
    {
11791
        return json_pointer(ptr) /= std::move(token);
11792
    }
11793
11794
    /*!
11795
    @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
11796
11797
    @param[in] ptr  JSON pointer
11798
    @param[in] array_idx  array index
11799
    @return a new JSON pointer with @a array_idx appended to @a ptr
11800
11801
    @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11802
11803
    @complexity Linear in the length of @a ptr.
11804
11805
    @sa @ref operator/=(std::size_t) to append an array index
11806
11807
    @since version 3.6.0
11808
    */
11809
    friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11810
    {
11811
        return json_pointer(ptr) /= array_idx;
11812
    }
11813
11814
    /*!
11815
    @brief returns the parent of this JSON pointer
11816
11817
    @return parent of this JSON pointer; in case this JSON pointer is the root,
11818
            the root itself is returned
11819
11820
    @complexity Linear in the length of the JSON pointer.
11821
11822
    @liveexample{The example shows the result of `parent_pointer` for different
11823
    JSON Pointers.,json_pointer__parent_pointer}
11824
11825
    @since version 3.6.0
11826
    */
11827
    json_pointer parent_pointer() const
11828
    {
11829
        if (empty())
11830
        {
11831
            return *this;
11832
        }
11833
11834
        json_pointer res = *this;
11835
        res.pop_back();
11836
        return res;
11837
    }
11838
11839
    /*!
11840
    @brief remove last reference token
11841
11842
    @pre not `empty()`
11843
11844
    @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
11845
11846
    @complexity Constant.
11847
11848
    @throw out_of_range.405 if JSON pointer has no parent
11849
11850
    @since version 3.6.0
11851
    */
11852
    void pop_back()
11853
    {
11854
        if (JSON_HEDLEY_UNLIKELY(empty()))
11855
        {
11856
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11857
        }
11858
11859
        reference_tokens.pop_back();
11860
    }
11861
11862
    /*!
11863
    @brief return last reference token
11864
11865
    @pre not `empty()`
11866
    @return last reference token
11867
11868
    @liveexample{The example shows the usage of `back`.,json_pointer__back}
11869
11870
    @complexity Constant.
11871
11872
    @throw out_of_range.405 if JSON pointer has no parent
11873
11874
    @since version 3.6.0
11875
    */
11876
    const std::string& back() const
11877
    {
11878
        if (JSON_HEDLEY_UNLIKELY(empty()))
11879
        {
11880
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11881
        }
11882
11883
        return reference_tokens.back();
11884
    }
11885
11886
    /*!
11887
    @brief append an unescaped token at the end of the reference pointer
11888
11889
    @param[in] token  token to add
11890
11891
    @complexity Amortized constant.
11892
11893
    @liveexample{The example shows the result of `push_back` for different
11894
    JSON Pointers.,json_pointer__push_back}
11895
11896
    @since version 3.6.0
11897
    */
11898
    void push_back(const std::string& token)
11899
    {
11900
        reference_tokens.push_back(token);
11901
    }
11902
11903
    /// @copydoc push_back(const std::string&)
11904
    void push_back(std::string&& token)
11905
    {
11906
        reference_tokens.push_back(std::move(token));
11907
    }
11908
11909
    /*!
11910
    @brief return whether pointer points to the root document
11911
11912
    @return true iff the JSON pointer points to the root document
11913
11914
    @complexity Constant.
11915
11916
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
11917
11918
    @liveexample{The example shows the result of `empty` for different JSON
11919
    Pointers.,json_pointer__empty}
11920
11921
    @since version 3.6.0
11922
    */
11923
    bool empty() const noexcept
11924
    {
11925
        return reference_tokens.empty();
11926
    }
11927
11928
  private:
11929
    /*!
11930
    @param[in] s  reference token to be converted into an array index
11931
11932
    @return integer representation of @a s
11933
11934
    @throw parse_error.106  if an array index begins with '0'
11935
    @throw parse_error.109  if an array index begins not with a digit
11936
    @throw out_of_range.404 if string @a s could not be converted to an integer
11937
    @throw out_of_range.410 if an array index exceeds size_type
11938
    */
11939
    static typename BasicJsonType::size_type array_index(const std::string& s)
11940
    {
11941
        using size_type = typename BasicJsonType::size_type;
11942
11943
        // error condition (cf. RFC 6901, Sect. 4)
11944
        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
11945
        {
11946
            JSON_THROW(detail::parse_error::create(106, 0,
11947
                                                   "array index '" + s +
11948
                                                   "' must not begin with '0'"));
11949
        }
11950
11951
        // error condition (cf. RFC 6901, Sect. 4)
11952
        if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
11953
        {
11954
            JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11955
        }
11956
11957
        std::size_t processed_chars = 0;
11958
        unsigned long long res = 0;
11959
        JSON_TRY
11960
        {
11961
            res = std::stoull(s, &processed_chars);
11962
        }
11963
        JSON_CATCH(std::out_of_range&)
11964
        {
11965
            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11966
        }
11967
11968
        // check if the string was completely read
11969
        if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11970
        {
11971
            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11972
        }
11973
11974
        // only triggered on special platforms (like 32bit), see also
11975
        // https://github.com/nlohmann/json/pull/2203
11976
        if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
11977
        {
11978
            JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
11979
        }
11980
11981
        return static_cast<size_type>(res);
11982
    }
11983
11984
  JSON_PRIVATE_UNLESS_TESTED:
11985
    json_pointer top() const
11986
    {
11987
        if (JSON_HEDLEY_UNLIKELY(empty()))
11988
        {
11989
            JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11990
        }
11991
11992
        json_pointer result = *this;
11993
        result.reference_tokens = {reference_tokens[0]};
11994
        return result;
11995
    }
11996
11997
  private:
11998
    /*!
11999
    @brief create and return a reference to the pointed to value
12000
12001
    @complexity Linear in the number of reference tokens.
12002
12003
    @throw parse_error.109 if array index is not a number
12004
    @throw type_error.313 if value cannot be unflattened
12005
    */
12006
    BasicJsonType& get_and_create(BasicJsonType& j) const
12007
    {
12008
        auto result = &j;
12009
12010
        // in case no reference tokens exist, return a reference to the JSON value
12011
        // j which will be overwritten by a primitive value
12012
        for (const auto& reference_token : reference_tokens)
12013
        {
12014
            switch (result->type())
12015
            {
12016
                case detail::value_t::null:
12017
                {
12018
                    if (reference_token == "0")
12019
                    {
12020
                        // start a new array if reference token is 0
12021
                        result = &result->operator[](0);
12022
                    }
12023
                    else
12024
                    {
12025
                        // start a new object otherwise
12026
                        result = &result->operator[](reference_token);
12027
                    }
12028
                    break;
12029
                }
12030
12031
                case detail::value_t::object:
12032
                {
12033
                    // create an entry in the object
12034
                    result = &result->operator[](reference_token);
12035
                    break;
12036
                }
12037
12038
                case detail::value_t::array:
12039
                {
12040
                    // create an entry in the array
12041
                    result = &result->operator[](array_index(reference_token));
12042
                    break;
12043
                }
12044
12045
                /*
12046
                The following code is only reached if there exists a reference
12047
                token _and_ the current value is primitive. In this case, we have
12048
                an error situation, because primitive values may only occur as
12049
                single value; that is, with an empty list of reference tokens.
12050
                */
12051
                default:
12052
                    JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
12053
            }
12054
        }
12055
12056
        return *result;
12057
    }
12058
12059
    /*!
12060
    @brief return a reference to the pointed to value
12061
12062
    @note This version does not throw if a value is not present, but tries to
12063
          create nested values instead. For instance, calling this function
12064
          with pointer `"/this/that"` on a null value is equivalent to calling
12065
          `operator[]("this").operator[]("that")` on that value, effectively
12066
          changing the null value to an object.
12067
12068
    @param[in] ptr  a JSON value
12069
12070
    @return reference to the JSON value pointed to by the JSON pointer
12071
12072
    @complexity Linear in the length of the JSON pointer.
12073
12074
    @throw parse_error.106   if an array index begins with '0'
12075
    @throw parse_error.109   if an array index was not a number
12076
    @throw out_of_range.404  if the JSON pointer can not be resolved
12077
    */
12078
    BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12079
    {
12080
        for (const auto& reference_token : reference_tokens)
12081
        {
12082
            // convert null values to arrays or objects before continuing
12083
            if (ptr->is_null())
12084
            {
12085
                // check if reference token is a number
12086
                const bool nums =
12087
                    std::all_of(reference_token.begin(), reference_token.end(),
12088
                                [](const unsigned char x)
12089
                {
12090
                    return std::isdigit(x);
12091
                });
12092
12093
                // change value to array for numbers or "-" or to object otherwise
12094
                *ptr = (nums || reference_token == "-")
12095
                       ? detail::value_t::array
12096
                       : detail::value_t::object;
12097
            }
12098
12099
            switch (ptr->type())
12100
            {
12101
                case detail::value_t::object:
12102
                {
12103
                    // use unchecked object access
12104
                    ptr = &ptr->operator[](reference_token);
12105
                    break;
12106
                }
12107
12108
                case detail::value_t::array:
12109
                {
12110
                    if (reference_token == "-")
12111
                    {
12112
                        // explicitly treat "-" as index beyond the end
12113
                        ptr = &ptr->operator[](ptr->m_value.array->size());
12114
                    }
12115
                    else
12116
                    {
12117
                        // convert array index to number; unchecked access
12118
                        ptr = &ptr->operator[](array_index(reference_token));
12119
                    }
12120
                    break;
12121
                }
12122
12123
                default:
12124
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12125
            }
12126
        }
12127
12128
        return *ptr;
12129
    }
12130
12131
    /*!
12132
    @throw parse_error.106   if an array index begins with '0'
12133
    @throw parse_error.109   if an array index was not a number
12134
    @throw out_of_range.402  if the array index '-' is used
12135
    @throw out_of_range.404  if the JSON pointer can not be resolved
12136
    */
12137
    BasicJsonType& get_checked(BasicJsonType* ptr) const
12138
    {
12139
        for (const auto& reference_token : reference_tokens)
12140
        {
12141
            switch (ptr->type())
12142
            {
12143
                case detail::value_t::object:
12144
                {
12145
                    // note: at performs range check
12146
                    ptr = &ptr->at(reference_token);
12147
                    break;
12148
                }
12149
12150
                case detail::value_t::array:
12151
                {
12152
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12153
                    {
12154
                        // "-" always fails the range check
12155
                        JSON_THROW(detail::out_of_range::create(402,
12156
                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12157
                                                                ") is out of range"));
12158
                    }
12159
12160
                    // note: at performs range check
12161
                    ptr = &ptr->at(array_index(reference_token));
12162
                    break;
12163
                }
12164
12165
                default:
12166
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12167
            }
12168
        }
12169
12170
        return *ptr;
12171
    }
12172
12173
    /*!
12174
    @brief return a const reference to the pointed to value
12175
12176
    @param[in] ptr  a JSON value
12177
12178
    @return const reference to the JSON value pointed to by the JSON
12179
    pointer
12180
12181
    @throw parse_error.106   if an array index begins with '0'
12182
    @throw parse_error.109   if an array index was not a number
12183
    @throw out_of_range.402  if the array index '-' is used
12184
    @throw out_of_range.404  if the JSON pointer can not be resolved
12185
    */
12186
    const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12187
    {
12188
        for (const auto& reference_token : reference_tokens)
12189
        {
12190
            switch (ptr->type())
12191
            {
12192
                case detail::value_t::object:
12193
                {
12194
                    // use unchecked object access
12195
                    ptr = &ptr->operator[](reference_token);
12196
                    break;
12197
                }
12198
12199
                case detail::value_t::array:
12200
                {
12201
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12202
                    {
12203
                        // "-" cannot be used for const access
12204
                        JSON_THROW(detail::out_of_range::create(402,
12205
                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12206
                                                                ") is out of range"));
12207
                    }
12208
12209
                    // use unchecked array access
12210
                    ptr = &ptr->operator[](array_index(reference_token));
12211
                    break;
12212
                }
12213
12214
                default:
12215
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12216
            }
12217
        }
12218
12219
        return *ptr;
12220
    }
12221
12222
    /*!
12223
    @throw parse_error.106   if an array index begins with '0'
12224
    @throw parse_error.109   if an array index was not a number
12225
    @throw out_of_range.402  if the array index '-' is used
12226
    @throw out_of_range.404  if the JSON pointer can not be resolved
12227
    */
12228
    const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12229
    {
12230
        for (const auto& reference_token : reference_tokens)
12231
        {
12232
            switch (ptr->type())
12233
            {
12234
                case detail::value_t::object:
12235
                {
12236
                    // note: at performs range check
12237
                    ptr = &ptr->at(reference_token);
12238
                    break;
12239
                }
12240
12241
                case detail::value_t::array:
12242
                {
12243
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12244
                    {
12245
                        // "-" always fails the range check
12246
                        JSON_THROW(detail::out_of_range::create(402,
12247
                                                                "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12248
                                                                ") is out of range"));
12249
                    }
12250
12251
                    // note: at performs range check
12252
                    ptr = &ptr->at(array_index(reference_token));
12253
                    break;
12254
                }
12255
12256
                default:
12257
                    JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12258
            }
12259
        }
12260
12261
        return *ptr;
12262
    }
12263
12264
    /*!
12265
    @throw parse_error.106   if an array index begins with '0'
12266
    @throw parse_error.109   if an array index was not a number
12267
    */
12268
    bool contains(const BasicJsonType* ptr) const
12269
    {
12270
        for (const auto& reference_token : reference_tokens)
12271
        {
12272
            switch (ptr->type())
12273
            {
12274
                case detail::value_t::object:
12275
                {
12276
                    if (!ptr->contains(reference_token))
12277
                    {
12278
                        // we did not find the key in the object
12279
                        return false;
12280
                    }
12281
12282
                    ptr = &ptr->operator[](reference_token);
12283
                    break;
12284
                }
12285
12286
                case detail::value_t::array:
12287
                {
12288
                    if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12289
                    {
12290
                        // "-" always fails the range check
12291
                        return false;
12292
                    }
12293
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12294
                    {
12295
                        // invalid char
12296
                        return false;
12297
                    }
12298
                    if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12299
                    {
12300
                        if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12301
                        {
12302
                            // first char should be between '1' and '9'
12303
                            return false;
12304
                        }
12305
                        for (std::size_t i = 1; i < reference_token.size(); i++)
12306
                        {
12307
                            if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12308
                            {
12309
                                // other char should be between '0' and '9'
12310
                                return false;
12311
                            }
12312
                        }
12313
                    }
12314
12315
                    const auto idx = array_index(reference_token);
12316
                    if (idx >= ptr->size())
12317
                    {
12318
                        // index out of range
12319
                        return false;
12320
                    }
12321
12322
                    ptr = &ptr->operator[](idx);
12323
                    break;
12324
                }
12325
12326
                default:
12327
                {
12328
                    // we do not expect primitive values if there is still a
12329
                    // reference token to process
12330
                    return false;
12331
                }
12332
            }
12333
        }
12334
12335
        // no reference token left means we found a primitive value
12336
        return true;
12337
    }
12338
12339
    /*!
12340
    @brief split the string input to reference tokens
12341
12342
    @note This function is only called by the json_pointer constructor.
12343
          All exceptions below are documented there.
12344
12345
    @throw parse_error.107  if the pointer is not empty or begins with '/'
12346
    @throw parse_error.108  if character '~' is not followed by '0' or '1'
12347
    */
12348
    static std::vector<std::string> split(const std::string& reference_string)
12349
0
    {
12350
0
        std::vector<std::string> result;
12351
0
12352
0
        // special case: empty reference string -> no reference tokens
12353
0
        if (reference_string.empty())
12354
0
        {
12355
0
            return result;
12356
0
        }
12357
0
12358
0
        // check if nonempty reference string begins with slash
12359
0
        if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12360
0
        {
12361
0
            JSON_THROW(detail::parse_error::create(107, 1,
12362
0
                                                   "JSON pointer must be empty or begin with '/' - was: '" +
12363
0
                                                   reference_string + "'"));
12364
0
        }
12365
0
12366
0
        // extract the reference tokens:
12367
0
        // - slash: position of the last read slash (or end of string)
12368
0
        // - start: position after the previous slash
12369
0
        for (
12370
0
            // search for the first slash after the first character
12371
0
            std::size_t slash = reference_string.find_first_of('/', 1),
12372
0
            // set the beginning of the first reference token
12373
0
            start = 1;
12374
0
            // we can stop if start == 0 (if slash == std::string::npos)
12375
0
            start != 0;
12376
0
            // set the beginning of the next reference token
12377
0
            // (will eventually be 0 if slash == std::string::npos)
12378
0
            start = (slash == std::string::npos) ? 0 : slash + 1,
12379
0
            // find next slash
12380
0
            slash = reference_string.find_first_of('/', start))
12381
0
        {
12382
0
            // use the text between the beginning of the reference token
12383
0
            // (start) and the last slash (slash).
12384
0
            auto reference_token = reference_string.substr(start, slash - start);
12385
0
12386
0
            // check reference tokens are properly escaped
12387
0
            for (std::size_t pos = reference_token.find_first_of('~');
12388
0
                    pos != std::string::npos;
12389
0
                    pos = reference_token.find_first_of('~', pos + 1))
12390
0
            {
12391
0
                JSON_ASSERT(reference_token[pos] == '~');
12392
0
12393
0
                // ~ must be followed by 0 or 1
12394
0
                if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12395
0
                                         (reference_token[pos + 1] != '0' &&
12396
0
                                          reference_token[pos + 1] != '1')))
12397
0
                {
12398
0
                    JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
12399
0
                }
12400
0
            }
12401
0
12402
0
            // finally, store the reference token
12403
0
            unescape(reference_token);
12404
0
            result.push_back(reference_token);
12405
0
        }
12406
0
12407
0
        return result;
12408
0
    }
12409
12410
    /*!
12411
    @brief replace all occurrences of a substring by another string
12412
12413
    @param[in,out] s  the string to manipulate; changed so that all
12414
                   occurrences of @a f are replaced with @a t
12415
    @param[in]     f  the substring to replace with @a t
12416
    @param[in]     t  the string to replace @a f
12417
12418
    @pre The search string @a f must not be empty. **This precondition is
12419
    enforced with an assertion.**
12420
12421
    @since version 2.0.0
12422
    */
12423
    static void replace_substring(std::string& s, const std::string& f,
12424
                                  const std::string& t)
12425
0
    {
12426
0
        JSON_ASSERT(!f.empty());
12427
0
        for (auto pos = s.find(f);                // find first occurrence of f
12428
0
                pos != std::string::npos;         // make sure f was found
12429
0
                s.replace(pos, f.size(), t),      // replace with t, and
12430
0
                pos = s.find(f, pos + t.size()))  // find next occurrence of f
12431
0
        {}
12432
0
    }
12433
12434
  JSON_PRIVATE_UNLESS_TESTED:
12435
    /// escape "~" to "~0" and "/" to "~1"
12436
    static std::string escape(std::string s)
12437
    {
12438
        replace_substring(s, "~", "~0");
12439
        replace_substring(s, "/", "~1");
12440
        return s;
12441
    }
12442
12443
    /// unescape "~1" to tilde and "~0" to slash (order is important!)
12444
    static void unescape(std::string& s)
12445
0
    {
12446
0
        replace_substring(s, "~1", "/");
12447
0
        replace_substring(s, "~0", "~");
12448
0
    }
12449
12450
  private:
12451
    /*!
12452
    @param[in] reference_string  the reference string to the current value
12453
    @param[in] value             the value to consider
12454
    @param[in,out] result        the result object to insert values to
12455
12456
    @note Empty objects or arrays are flattened to `null`.
12457
    */
12458
    static void flatten(const std::string& reference_string,
12459
                        const BasicJsonType& value,
12460
                        BasicJsonType& result)
12461
    {
12462
        switch (value.type())
12463
        {
12464
            case detail::value_t::array:
12465
            {
12466
                if (value.m_value.array->empty())
12467
                {
12468
                    // flatten empty array as null
12469
                    result[reference_string] = nullptr;
12470
                }
12471
                else
12472
                {
12473
                    // iterate array and use index as reference string
12474
                    for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12475
                    {
12476
                        flatten(reference_string + "/" + std::to_string(i),
12477
                                value.m_value.array->operator[](i), result);
12478
                    }
12479
                }
12480
                break;
12481
            }
12482
12483
            case detail::value_t::object:
12484
            {
12485
                if (value.m_value.object->empty())
12486
                {
12487
                    // flatten empty object as null
12488
                    result[reference_string] = nullptr;
12489
                }
12490
                else
12491
                {
12492
                    // iterate object and use keys as reference string
12493
                    for (const auto& element : *value.m_value.object)
12494
                    {
12495
                        flatten(reference_string + "/" + escape(element.first), element.second, result);
12496
                    }
12497
                }
12498
                break;
12499
            }
12500
12501
            default:
12502
            {
12503
                // add primitive value with its reference string
12504
                result[reference_string] = value;
12505
                break;
12506
            }
12507
        }
12508
    }
12509
12510
    /*!
12511
    @param[in] value  flattened JSON
12512
12513
    @return unflattened JSON
12514
12515
    @throw parse_error.109 if array index is not a number
12516
    @throw type_error.314  if value is not an object
12517
    @throw type_error.315  if object values are not primitive
12518
    @throw type_error.313  if value cannot be unflattened
12519
    */
12520
    static BasicJsonType
12521
    unflatten(const BasicJsonType& value)
12522
    {
12523
        if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12524
        {
12525
            JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
12526
        }
12527
12528
        BasicJsonType result;
12529
12530
        // iterate the JSON object values
12531
        for (const auto& element : *value.m_value.object)
12532
        {
12533
            if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12534
            {
12535
                JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
12536
            }
12537
12538
            // assign value to reference pointed to by JSON pointer; Note that if
12539
            // the JSON pointer is "" (i.e., points to the whole value), function
12540
            // get_and_create returns a reference to result itself. An assignment
12541
            // will then create a primitive value.
12542
            json_pointer(element.first).get_and_create(result) = element.second;
12543
        }
12544
12545
        return result;
12546
    }
12547
12548
    /*!
12549
    @brief compares two JSON pointers for equality
12550
12551
    @param[in] lhs  JSON pointer to compare
12552
    @param[in] rhs  JSON pointer to compare
12553
    @return whether @a lhs is equal to @a rhs
12554
12555
    @complexity Linear in the length of the JSON pointer
12556
12557
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
12558
    */
12559
    friend bool operator==(json_pointer const& lhs,
12560
                           json_pointer const& rhs) noexcept
12561
    {
12562
        return lhs.reference_tokens == rhs.reference_tokens;
12563
    }
12564
12565
    /*!
12566
    @brief compares two JSON pointers for inequality
12567
12568
    @param[in] lhs  JSON pointer to compare
12569
    @param[in] rhs  JSON pointer to compare
12570
    @return whether @a lhs is not equal @a rhs
12571
12572
    @complexity Linear in the length of the JSON pointer
12573
12574
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
12575
    */
12576
    friend bool operator!=(json_pointer const& lhs,
12577
                           json_pointer const& rhs) noexcept
12578
    {
12579
        return !(lhs == rhs);
12580
    }
12581
12582
    /// the reference tokens
12583
    std::vector<std::string> reference_tokens;
12584
};
12585
}  // namespace nlohmann
12586
12587
// #include <nlohmann/detail/json_ref.hpp>
12588
12589
12590
#include <initializer_list>
12591
#include <utility>
12592
12593
// #include <nlohmann/detail/meta/type_traits.hpp>
12594
12595
12596
namespace nlohmann
12597
{
12598
namespace detail
12599
{
12600
template<typename BasicJsonType>
12601
class json_ref
12602
{
12603
  public:
12604
    using value_type = BasicJsonType;
12605
12606
    json_ref(value_type&& value)
12607
        : owned_value(std::move(value))
12608
        , value_ref(&owned_value)
12609
        , is_rvalue(true)
12610
    {}
12611
12612
    json_ref(const value_type& value)
12613
        : value_ref(const_cast<value_type*>(&value))
12614
        , is_rvalue(false)
12615
    {}
12616
12617
    json_ref(std::initializer_list<json_ref> init)
12618
        : owned_value(init)
12619
        , value_ref(&owned_value)
12620
        , is_rvalue(true)
12621
    {}
12622
12623
    template <
12624
        class... Args,
12625
        enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
12626
    json_ref(Args && ... args)
12627
        : owned_value(std::forward<Args>(args)...)
12628
        , value_ref(&owned_value)
12629
        , is_rvalue(true)
12630
    {}
12631
12632
    // class should be movable only
12633
    json_ref(json_ref&&) = default;
12634
    json_ref(const json_ref&) = delete;
12635
    json_ref& operator=(const json_ref&) = delete;
12636
    json_ref& operator=(json_ref&&) = delete;
12637
    ~json_ref() = default;
12638
12639
    value_type moved_or_copied() const
12640
0
    {
12641
0
        if (is_rvalue)
12642
0
        {
12643
0
            return std::move(*value_ref);
12644
0
        }
12645
0
        return *value_ref;
12646
0
    }
12647
12648
    value_type const& operator*() const
12649
0
    {
12650
0
        return *static_cast<value_type const*>(value_ref);
12651
0
    }
12652
12653
    value_type const* operator->() const
12654
0
    {
12655
0
        return static_cast<value_type const*>(value_ref);
12656
0
    }
12657
12658
  private:
12659
    mutable value_type owned_value = nullptr;
12660
    value_type* value_ref = nullptr;
12661
    const bool is_rvalue = true;
12662
};
12663
}  // namespace detail
12664
}  // namespace nlohmann
12665
12666
// #include <nlohmann/detail/macro_scope.hpp>
12667
12668
// #include <nlohmann/detail/meta/cpp_future.hpp>
12669
12670
// #include <nlohmann/detail/meta/type_traits.hpp>
12671
12672
// #include <nlohmann/detail/output/binary_writer.hpp>
12673
12674
12675
#include <algorithm> // reverse
12676
#include <array> // array
12677
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12678
#include <cstring> // memcpy
12679
#include <limits> // numeric_limits
12680
#include <string> // string
12681
#include <cmath> // isnan, isinf
12682
12683
// #include <nlohmann/detail/input/binary_reader.hpp>
12684
12685
// #include <nlohmann/detail/macro_scope.hpp>
12686
12687
// #include <nlohmann/detail/output/output_adapters.hpp>
12688
12689
12690
#include <algorithm> // copy
12691
#include <cstddef> // size_t
12692
#include <ios> // streamsize
12693
#include <iterator> // back_inserter
12694
#include <memory> // shared_ptr, make_shared
12695
#include <ostream> // basic_ostream
12696
#include <string> // basic_string
12697
#include <vector> // vector
12698
// #include <nlohmann/detail/macro_scope.hpp>
12699
12700
12701
namespace nlohmann
12702
{
12703
namespace detail
12704
{
12705
/// abstract output adapter interface
12706
template<typename CharType> struct output_adapter_protocol
12707
{
12708
    virtual void write_character(CharType c) = 0;
12709
    virtual void write_characters(const CharType* s, std::size_t length) = 0;
12710
0
    virtual ~output_adapter_protocol() = default;
12711
};
12712
12713
/// a type to simplify interfaces
12714
template<typename CharType>
12715
using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12716
12717
/// output adapter for byte vectors
12718
template<typename CharType>
12719
class output_vector_adapter : public output_adapter_protocol<CharType>
12720
{
12721
  public:
12722
    explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12723
        : v(vec)
12724
    {}
12725
12726
    void write_character(CharType c) override
12727
    {
12728
        v.push_back(c);
12729
    }
12730
12731
    JSON_HEDLEY_NON_NULL(2)
12732
    void write_characters(const CharType* s, std::size_t length) override
12733
    {
12734
        std::copy(s, s + length, std::back_inserter(v));
12735
    }
12736
12737
  private:
12738
    std::vector<CharType>& v;
12739
};
12740
12741
/// output adapter for output streams
12742
template<typename CharType>
12743
class output_stream_adapter : public output_adapter_protocol<CharType>
12744
{
12745
  public:
12746
    explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12747
        : stream(s)
12748
0
    {}
12749
12750
    void write_character(CharType c) override
12751
0
    {
12752
0
        stream.put(c);
12753
0
    }
12754
12755
    JSON_HEDLEY_NON_NULL(2)
12756
    void write_characters(const CharType* s, std::size_t length) override
12757
0
    {
12758
0
        stream.write(s, static_cast<std::streamsize>(length));
12759
0
    }
12760
12761
  private:
12762
    std::basic_ostream<CharType>& stream;
12763
};
12764
12765
/// output adapter for basic_string
12766
template<typename CharType, typename StringType = std::basic_string<CharType>>
12767
class output_string_adapter : public output_adapter_protocol<CharType>
12768
{
12769
  public:
12770
    explicit output_string_adapter(StringType& s) noexcept
12771
        : str(s)
12772
    {}
12773
12774
    void write_character(CharType c) override
12775
    {
12776
        str.push_back(c);
12777
    }
12778
12779
    JSON_HEDLEY_NON_NULL(2)
12780
    void write_characters(const CharType* s, std::size_t length) override
12781
    {
12782
        str.append(s, length);
12783
    }
12784
12785
  private:
12786
    StringType& str;
12787
};
12788
12789
template<typename CharType, typename StringType = std::basic_string<CharType>>
12790
class output_adapter
12791
{
12792
  public:
12793
    output_adapter(std::vector<CharType>& vec)
12794
        : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12795
12796
    output_adapter(std::basic_ostream<CharType>& s)
12797
0
        : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12798
12799
    output_adapter(StringType& s)
12800
        : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12801
12802
    operator output_adapter_t<CharType>()
12803
0
    {
12804
0
        return oa;
12805
0
    }
12806
12807
  private:
12808
    output_adapter_t<CharType> oa = nullptr;
12809
};
12810
}  // namespace detail
12811
}  // namespace nlohmann
12812
12813
12814
namespace nlohmann
12815
{
12816
namespace detail
12817
{
12818
///////////////////
12819
// binary writer //
12820
///////////////////
12821
12822
/*!
12823
@brief serialization to CBOR and MessagePack values
12824
*/
12825
template<typename BasicJsonType, typename CharType>
12826
class binary_writer
12827
{
12828
    using string_t = typename BasicJsonType::string_t;
12829
    using binary_t = typename BasicJsonType::binary_t;
12830
    using number_float_t = typename BasicJsonType::number_float_t;
12831
12832
  public:
12833
    /*!
12834
    @brief create a binary writer
12835
12836
    @param[in] adapter  output adapter to write to
12837
    */
12838
    explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12839
    {
12840
        JSON_ASSERT(oa);
12841
    }
12842
12843
    /*!
12844
    @param[in] j  JSON value to serialize
12845
    @pre       j.type() == value_t::object
12846
    */
12847
    void write_bson(const BasicJsonType& j)
12848
    {
12849
        switch (j.type())
12850
        {
12851
            case value_t::object:
12852
            {
12853
                write_bson_object(*j.m_value.object);
12854
                break;
12855
            }
12856
12857
            default:
12858
            {
12859
                JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12860
            }
12861
        }
12862
    }
12863
12864
    /*!
12865
    @param[in] j  JSON value to serialize
12866
    */
12867
    void write_cbor(const BasicJsonType& j)
12868
    {
12869
        switch (j.type())
12870
        {
12871
            case value_t::null:
12872
            {
12873
                oa->write_character(to_char_type(0xF6));
12874
                break;
12875
            }
12876
12877
            case value_t::boolean:
12878
            {
12879
                oa->write_character(j.m_value.boolean
12880
                                    ? to_char_type(0xF5)
12881
                                    : to_char_type(0xF4));
12882
                break;
12883
            }
12884
12885
            case value_t::number_integer:
12886
            {
12887
                if (j.m_value.number_integer >= 0)
12888
                {
12889
                    // CBOR does not differentiate between positive signed
12890
                    // integers and unsigned integers. Therefore, we used the
12891
                    // code from the value_t::number_unsigned case here.
12892
                    if (j.m_value.number_integer <= 0x17)
12893
                    {
12894
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12895
                    }
12896
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12897
                    {
12898
                        oa->write_character(to_char_type(0x18));
12899
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12900
                    }
12901
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12902
                    {
12903
                        oa->write_character(to_char_type(0x19));
12904
                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12905
                    }
12906
                    else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12907
                    {
12908
                        oa->write_character(to_char_type(0x1A));
12909
                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12910
                    }
12911
                    else
12912
                    {
12913
                        oa->write_character(to_char_type(0x1B));
12914
                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12915
                    }
12916
                }
12917
                else
12918
                {
12919
                    // The conversions below encode the sign in the first
12920
                    // byte, and the value is converted to a positive number.
12921
                    const auto positive_number = -1 - j.m_value.number_integer;
12922
                    if (j.m_value.number_integer >= -24)
12923
                    {
12924
                        write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12925
                    }
12926
                    else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12927
                    {
12928
                        oa->write_character(to_char_type(0x38));
12929
                        write_number(static_cast<std::uint8_t>(positive_number));
12930
                    }
12931
                    else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12932
                    {
12933
                        oa->write_character(to_char_type(0x39));
12934
                        write_number(static_cast<std::uint16_t>(positive_number));
12935
                    }
12936
                    else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12937
                    {
12938
                        oa->write_character(to_char_type(0x3A));
12939
                        write_number(static_cast<std::uint32_t>(positive_number));
12940
                    }
12941
                    else
12942
                    {
12943
                        oa->write_character(to_char_type(0x3B));
12944
                        write_number(static_cast<std::uint64_t>(positive_number));
12945
                    }
12946
                }
12947
                break;
12948
            }
12949
12950
            case value_t::number_unsigned:
12951
            {
12952
                if (j.m_value.number_unsigned <= 0x17)
12953
                {
12954
                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12955
                }
12956
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12957
                {
12958
                    oa->write_character(to_char_type(0x18));
12959
                    write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12960
                }
12961
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12962
                {
12963
                    oa->write_character(to_char_type(0x19));
12964
                    write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12965
                }
12966
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12967
                {
12968
                    oa->write_character(to_char_type(0x1A));
12969
                    write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12970
                }
12971
                else
12972
                {
12973
                    oa->write_character(to_char_type(0x1B));
12974
                    write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12975
                }
12976
                break;
12977
            }
12978
12979
            case value_t::number_float:
12980
            {
12981
                if (std::isnan(j.m_value.number_float))
12982
                {
12983
                    // NaN is 0xf97e00 in CBOR
12984
                    oa->write_character(to_char_type(0xF9));
12985
                    oa->write_character(to_char_type(0x7E));
12986
                    oa->write_character(to_char_type(0x00));
12987
                }
12988
                else if (std::isinf(j.m_value.number_float))
12989
                {
12990
                    // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12991
                    oa->write_character(to_char_type(0xf9));
12992
                    oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12993
                    oa->write_character(to_char_type(0x00));
12994
                }
12995
                else
12996
                {
12997
                    write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
12998
                }
12999
                break;
13000
            }
13001
13002
            case value_t::string:
13003
            {
13004
                // step 1: write control byte and the string length
13005
                const auto N = j.m_value.string->size();
13006
                if (N <= 0x17)
13007
                {
13008
                    write_number(static_cast<std::uint8_t>(0x60 + N));
13009
                }
13010
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13011
                {
13012
                    oa->write_character(to_char_type(0x78));
13013
                    write_number(static_cast<std::uint8_t>(N));
13014
                }
13015
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13016
                {
13017
                    oa->write_character(to_char_type(0x79));
13018
                    write_number(static_cast<std::uint16_t>(N));
13019
                }
13020
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13021
                {
13022
                    oa->write_character(to_char_type(0x7A));
13023
                    write_number(static_cast<std::uint32_t>(N));
13024
                }
13025
                // LCOV_EXCL_START
13026
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13027
                {
13028
                    oa->write_character(to_char_type(0x7B));
13029
                    write_number(static_cast<std::uint64_t>(N));
13030
                }
13031
                // LCOV_EXCL_STOP
13032
13033
                // step 2: write the string
13034
                oa->write_characters(
13035
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13036
                    j.m_value.string->size());
13037
                break;
13038
            }
13039
13040
            case value_t::array:
13041
            {
13042
                // step 1: write control byte and the array size
13043
                const auto N = j.m_value.array->size();
13044
                if (N <= 0x17)
13045
                {
13046
                    write_number(static_cast<std::uint8_t>(0x80 + N));
13047
                }
13048
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13049
                {
13050
                    oa->write_character(to_char_type(0x98));
13051
                    write_number(static_cast<std::uint8_t>(N));
13052
                }
13053
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13054
                {
13055
                    oa->write_character(to_char_type(0x99));
13056
                    write_number(static_cast<std::uint16_t>(N));
13057
                }
13058
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13059
                {
13060
                    oa->write_character(to_char_type(0x9A));
13061
                    write_number(static_cast<std::uint32_t>(N));
13062
                }
13063
                // LCOV_EXCL_START
13064
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13065
                {
13066
                    oa->write_character(to_char_type(0x9B));
13067
                    write_number(static_cast<std::uint64_t>(N));
13068
                }
13069
                // LCOV_EXCL_STOP
13070
13071
                // step 2: write each element
13072
                for (const auto& el : *j.m_value.array)
13073
                {
13074
                    write_cbor(el);
13075
                }
13076
                break;
13077
            }
13078
13079
            case value_t::binary:
13080
            {
13081
                if (j.m_value.binary->has_subtype())
13082
                {
13083
                    write_number(static_cast<std::uint8_t>(0xd8));
13084
                    write_number(j.m_value.binary->subtype());
13085
                }
13086
13087
                // step 1: write control byte and the binary array size
13088
                const auto N = j.m_value.binary->size();
13089
                if (N <= 0x17)
13090
                {
13091
                    write_number(static_cast<std::uint8_t>(0x40 + N));
13092
                }
13093
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13094
                {
13095
                    oa->write_character(to_char_type(0x58));
13096
                    write_number(static_cast<std::uint8_t>(N));
13097
                }
13098
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13099
                {
13100
                    oa->write_character(to_char_type(0x59));
13101
                    write_number(static_cast<std::uint16_t>(N));
13102
                }
13103
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13104
                {
13105
                    oa->write_character(to_char_type(0x5A));
13106
                    write_number(static_cast<std::uint32_t>(N));
13107
                }
13108
                // LCOV_EXCL_START
13109
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13110
                {
13111
                    oa->write_character(to_char_type(0x5B));
13112
                    write_number(static_cast<std::uint64_t>(N));
13113
                }
13114
                // LCOV_EXCL_STOP
13115
13116
                // step 2: write each element
13117
                oa->write_characters(
13118
                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13119
                    N);
13120
13121
                break;
13122
            }
13123
13124
            case value_t::object:
13125
            {
13126
                // step 1: write control byte and the object size
13127
                const auto N = j.m_value.object->size();
13128
                if (N <= 0x17)
13129
                {
13130
                    write_number(static_cast<std::uint8_t>(0xA0 + N));
13131
                }
13132
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13133
                {
13134
                    oa->write_character(to_char_type(0xB8));
13135
                    write_number(static_cast<std::uint8_t>(N));
13136
                }
13137
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13138
                {
13139
                    oa->write_character(to_char_type(0xB9));
13140
                    write_number(static_cast<std::uint16_t>(N));
13141
                }
13142
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13143
                {
13144
                    oa->write_character(to_char_type(0xBA));
13145
                    write_number(static_cast<std::uint32_t>(N));
13146
                }
13147
                // LCOV_EXCL_START
13148
                else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13149
                {
13150
                    oa->write_character(to_char_type(0xBB));
13151
                    write_number(static_cast<std::uint64_t>(N));
13152
                }
13153
                // LCOV_EXCL_STOP
13154
13155
                // step 2: write each element
13156
                for (const auto& el : *j.m_value.object)
13157
                {
13158
                    write_cbor(el.first);
13159
                    write_cbor(el.second);
13160
                }
13161
                break;
13162
            }
13163
13164
            default:
13165
                break;
13166
        }
13167
    }
13168
13169
    /*!
13170
    @param[in] j  JSON value to serialize
13171
    */
13172
    void write_msgpack(const BasicJsonType& j)
13173
    {
13174
        switch (j.type())
13175
        {
13176
            case value_t::null: // nil
13177
            {
13178
                oa->write_character(to_char_type(0xC0));
13179
                break;
13180
            }
13181
13182
            case value_t::boolean: // true and false
13183
            {
13184
                oa->write_character(j.m_value.boolean
13185
                                    ? to_char_type(0xC3)
13186
                                    : to_char_type(0xC2));
13187
                break;
13188
            }
13189
13190
            case value_t::number_integer:
13191
            {
13192
                if (j.m_value.number_integer >= 0)
13193
                {
13194
                    // MessagePack does not differentiate between positive
13195
                    // signed integers and unsigned integers. Therefore, we used
13196
                    // the code from the value_t::number_unsigned case here.
13197
                    if (j.m_value.number_unsigned < 128)
13198
                    {
13199
                        // positive fixnum
13200
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13201
                    }
13202
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13203
                    {
13204
                        // uint 8
13205
                        oa->write_character(to_char_type(0xCC));
13206
                        write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13207
                    }
13208
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13209
                    {
13210
                        // uint 16
13211
                        oa->write_character(to_char_type(0xCD));
13212
                        write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13213
                    }
13214
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13215
                    {
13216
                        // uint 32
13217
                        oa->write_character(to_char_type(0xCE));
13218
                        write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13219
                    }
13220
                    else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13221
                    {
13222
                        // uint 64
13223
                        oa->write_character(to_char_type(0xCF));
13224
                        write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13225
                    }
13226
                }
13227
                else
13228
                {
13229
                    if (j.m_value.number_integer >= -32)
13230
                    {
13231
                        // negative fixnum
13232
                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13233
                    }
13234
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13235
                             j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13236
                    {
13237
                        // int 8
13238
                        oa->write_character(to_char_type(0xD0));
13239
                        write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13240
                    }
13241
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13242
                             j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13243
                    {
13244
                        // int 16
13245
                        oa->write_character(to_char_type(0xD1));
13246
                        write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13247
                    }
13248
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13249
                             j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13250
                    {
13251
                        // int 32
13252
                        oa->write_character(to_char_type(0xD2));
13253
                        write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13254
                    }
13255
                    else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13256
                             j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13257
                    {
13258
                        // int 64
13259
                        oa->write_character(to_char_type(0xD3));
13260
                        write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13261
                    }
13262
                }
13263
                break;
13264
            }
13265
13266
            case value_t::number_unsigned:
13267
            {
13268
                if (j.m_value.number_unsigned < 128)
13269
                {
13270
                    // positive fixnum
13271
                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13272
                }
13273
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13274
                {
13275
                    // uint 8
13276
                    oa->write_character(to_char_type(0xCC));
13277
                    write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13278
                }
13279
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13280
                {
13281
                    // uint 16
13282
                    oa->write_character(to_char_type(0xCD));
13283
                    write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13284
                }
13285
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13286
                {
13287
                    // uint 32
13288
                    oa->write_character(to_char_type(0xCE));
13289
                    write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13290
                }
13291
                else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13292
                {
13293
                    // uint 64
13294
                    oa->write_character(to_char_type(0xCF));
13295
                    write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13296
                }
13297
                break;
13298
            }
13299
13300
            case value_t::number_float:
13301
            {
13302
                write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13303
                break;
13304
            }
13305
13306
            case value_t::string:
13307
            {
13308
                // step 1: write control byte and the string length
13309
                const auto N = j.m_value.string->size();
13310
                if (N <= 31)
13311
                {
13312
                    // fixstr
13313
                    write_number(static_cast<std::uint8_t>(0xA0 | N));
13314
                }
13315
                else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13316
                {
13317
                    // str 8
13318
                    oa->write_character(to_char_type(0xD9));
13319
                    write_number(static_cast<std::uint8_t>(N));
13320
                }
13321
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13322
                {
13323
                    // str 16
13324
                    oa->write_character(to_char_type(0xDA));
13325
                    write_number(static_cast<std::uint16_t>(N));
13326
                }
13327
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13328
                {
13329
                    // str 32
13330
                    oa->write_character(to_char_type(0xDB));
13331
                    write_number(static_cast<std::uint32_t>(N));
13332
                }
13333
13334
                // step 2: write the string
13335
                oa->write_characters(
13336
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13337
                    j.m_value.string->size());
13338
                break;
13339
            }
13340
13341
            case value_t::array:
13342
            {
13343
                // step 1: write control byte and the array size
13344
                const auto N = j.m_value.array->size();
13345
                if (N <= 15)
13346
                {
13347
                    // fixarray
13348
                    write_number(static_cast<std::uint8_t>(0x90 | N));
13349
                }
13350
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13351
                {
13352
                    // array 16
13353
                    oa->write_character(to_char_type(0xDC));
13354
                    write_number(static_cast<std::uint16_t>(N));
13355
                }
13356
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13357
                {
13358
                    // array 32
13359
                    oa->write_character(to_char_type(0xDD));
13360
                    write_number(static_cast<std::uint32_t>(N));
13361
                }
13362
13363
                // step 2: write each element
13364
                for (const auto& el : *j.m_value.array)
13365
                {
13366
                    write_msgpack(el);
13367
                }
13368
                break;
13369
            }
13370
13371
            case value_t::binary:
13372
            {
13373
                // step 0: determine if the binary type has a set subtype to
13374
                // determine whether or not to use the ext or fixext types
13375
                const bool use_ext = j.m_value.binary->has_subtype();
13376
13377
                // step 1: write control byte and the byte string length
13378
                const auto N = j.m_value.binary->size();
13379
                if (N <= (std::numeric_limits<std::uint8_t>::max)())
13380
                {
13381
                    std::uint8_t output_type{};
13382
                    bool fixed = true;
13383
                    if (use_ext)
13384
                    {
13385
                        switch (N)
13386
                        {
13387
                            case 1:
13388
                                output_type = 0xD4; // fixext 1
13389
                                break;
13390
                            case 2:
13391
                                output_type = 0xD5; // fixext 2
13392
                                break;
13393
                            case 4:
13394
                                output_type = 0xD6; // fixext 4
13395
                                break;
13396
                            case 8:
13397
                                output_type = 0xD7; // fixext 8
13398
                                break;
13399
                            case 16:
13400
                                output_type = 0xD8; // fixext 16
13401
                                break;
13402
                            default:
13403
                                output_type = 0xC7; // ext 8
13404
                                fixed = false;
13405
                                break;
13406
                        }
13407
13408
                    }
13409
                    else
13410
                    {
13411
                        output_type = 0xC4; // bin 8
13412
                        fixed = false;
13413
                    }
13414
13415
                    oa->write_character(to_char_type(output_type));
13416
                    if (!fixed)
13417
                    {
13418
                        write_number(static_cast<std::uint8_t>(N));
13419
                    }
13420
                }
13421
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13422
                {
13423
                    std::uint8_t output_type = use_ext
13424
                                               ? 0xC8 // ext 16
13425
                                               : 0xC5; // bin 16
13426
13427
                    oa->write_character(to_char_type(output_type));
13428
                    write_number(static_cast<std::uint16_t>(N));
13429
                }
13430
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13431
                {
13432
                    std::uint8_t output_type = use_ext
13433
                                               ? 0xC9 // ext 32
13434
                                               : 0xC6; // bin 32
13435
13436
                    oa->write_character(to_char_type(output_type));
13437
                    write_number(static_cast<std::uint32_t>(N));
13438
                }
13439
13440
                // step 1.5: if this is an ext type, write the subtype
13441
                if (use_ext)
13442
                {
13443
                    write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13444
                }
13445
13446
                // step 2: write the byte string
13447
                oa->write_characters(
13448
                    reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13449
                    N);
13450
13451
                break;
13452
            }
13453
13454
            case value_t::object:
13455
            {
13456
                // step 1: write control byte and the object size
13457
                const auto N = j.m_value.object->size();
13458
                if (N <= 15)
13459
                {
13460
                    // fixmap
13461
                    write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13462
                }
13463
                else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13464
                {
13465
                    // map 16
13466
                    oa->write_character(to_char_type(0xDE));
13467
                    write_number(static_cast<std::uint16_t>(N));
13468
                }
13469
                else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13470
                {
13471
                    // map 32
13472
                    oa->write_character(to_char_type(0xDF));
13473
                    write_number(static_cast<std::uint32_t>(N));
13474
                }
13475
13476
                // step 2: write each element
13477
                for (const auto& el : *j.m_value.object)
13478
                {
13479
                    write_msgpack(el.first);
13480
                    write_msgpack(el.second);
13481
                }
13482
                break;
13483
            }
13484
13485
            default:
13486
                break;
13487
        }
13488
    }
13489
13490
    /*!
13491
    @param[in] j  JSON value to serialize
13492
    @param[in] use_count   whether to use '#' prefixes (optimized format)
13493
    @param[in] use_type    whether to use '$' prefixes (optimized format)
13494
    @param[in] add_prefix  whether prefixes need to be used for this value
13495
    */
13496
    void write_ubjson(const BasicJsonType& j, const bool use_count,
13497
                      const bool use_type, const bool add_prefix = true)
13498
    {
13499
        switch (j.type())
13500
        {
13501
            case value_t::null:
13502
            {
13503
                if (add_prefix)
13504
                {
13505
                    oa->write_character(to_char_type('Z'));
13506
                }
13507
                break;
13508
            }
13509
13510
            case value_t::boolean:
13511
            {
13512
                if (add_prefix)
13513
                {
13514
                    oa->write_character(j.m_value.boolean
13515
                                        ? to_char_type('T')
13516
                                        : to_char_type('F'));
13517
                }
13518
                break;
13519
            }
13520
13521
            case value_t::number_integer:
13522
            {
13523
                write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13524
                break;
13525
            }
13526
13527
            case value_t::number_unsigned:
13528
            {
13529
                write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13530
                break;
13531
            }
13532
13533
            case value_t::number_float:
13534
            {
13535
                write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13536
                break;
13537
            }
13538
13539
            case value_t::string:
13540
            {
13541
                if (add_prefix)
13542
                {
13543
                    oa->write_character(to_char_type('S'));
13544
                }
13545
                write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13546
                oa->write_characters(
13547
                    reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13548
                    j.m_value.string->size());
13549
                break;
13550
            }
13551
13552
            case value_t::array:
13553
            {
13554
                if (add_prefix)
13555
                {
13556
                    oa->write_character(to_char_type('['));
13557
                }
13558
13559
                bool prefix_required = true;
13560
                if (use_type && !j.m_value.array->empty())
13561
                {
13562
                    JSON_ASSERT(use_count);
13563
                    const CharType first_prefix = ubjson_prefix(j.front());
13564
                    const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13565
                                                         [this, first_prefix](const BasicJsonType & v)
13566
                    {
13567
                        return ubjson_prefix(v) == first_prefix;
13568
                    });
13569
13570
                    if (same_prefix)
13571
                    {
13572
                        prefix_required = false;
13573
                        oa->write_character(to_char_type('$'));
13574
                        oa->write_character(first_prefix);
13575
                    }
13576
                }
13577
13578
                if (use_count)
13579
                {
13580
                    oa->write_character(to_char_type('#'));
13581
                    write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13582
                }
13583
13584
                for (const auto& el : *j.m_value.array)
13585
                {
13586
                    write_ubjson(el, use_count, use_type, prefix_required);
13587
                }
13588
13589
                if (!use_count)
13590
                {
13591
                    oa->write_character(to_char_type(']'));
13592
                }
13593
13594
                break;
13595
            }
13596
13597
            case value_t::binary:
13598
            {
13599
                if (add_prefix)
13600
                {
13601
                    oa->write_character(to_char_type('['));
13602
                }
13603
13604
                if (use_type && !j.m_value.binary->empty())
13605
                {
13606
                    JSON_ASSERT(use_count);
13607
                    oa->write_character(to_char_type('$'));
13608
                    oa->write_character('U');
13609
                }
13610
13611
                if (use_count)
13612
                {
13613
                    oa->write_character(to_char_type('#'));
13614
                    write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13615
                }
13616
13617
                if (use_type)
13618
                {
13619
                    oa->write_characters(
13620
                        reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13621
                        j.m_value.binary->size());
13622
                }
13623
                else
13624
                {
13625
                    for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13626
                    {
13627
                        oa->write_character(to_char_type('U'));
13628
                        oa->write_character(j.m_value.binary->data()[i]);
13629
                    }
13630
                }
13631
13632
                if (!use_count)
13633
                {
13634
                    oa->write_character(to_char_type(']'));
13635
                }
13636
13637
                break;
13638
            }
13639
13640
            case value_t::object:
13641
            {
13642
                if (add_prefix)
13643
                {
13644
                    oa->write_character(to_char_type('{'));
13645
                }
13646
13647
                bool prefix_required = true;
13648
                if (use_type && !j.m_value.object->empty())
13649
                {
13650
                    JSON_ASSERT(use_count);
13651
                    const CharType first_prefix = ubjson_prefix(j.front());
13652
                    const bool same_prefix = std::all_of(j.begin(), j.end(),
13653
                                                         [this, first_prefix](const BasicJsonType & v)
13654
                    {
13655
                        return ubjson_prefix(v) == first_prefix;
13656
                    });
13657
13658
                    if (same_prefix)
13659
                    {
13660
                        prefix_required = false;
13661
                        oa->write_character(to_char_type('$'));
13662
                        oa->write_character(first_prefix);
13663
                    }
13664
                }
13665
13666
                if (use_count)
13667
                {
13668
                    oa->write_character(to_char_type('#'));
13669
                    write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13670
                }
13671
13672
                for (const auto& el : *j.m_value.object)
13673
                {
13674
                    write_number_with_ubjson_prefix(el.first.size(), true);
13675
                    oa->write_characters(
13676
                        reinterpret_cast<const CharType*>(el.first.c_str()),
13677
                        el.first.size());
13678
                    write_ubjson(el.second, use_count, use_type, prefix_required);
13679
                }
13680
13681
                if (!use_count)
13682
                {
13683
                    oa->write_character(to_char_type('}'));
13684
                }
13685
13686
                break;
13687
            }
13688
13689
            default:
13690
                break;
13691
        }
13692
    }
13693
13694
  private:
13695
    //////////
13696
    // BSON //
13697
    //////////
13698
13699
    /*!
13700
    @return The size of a BSON document entry header, including the id marker
13701
            and the entry name size (and its null-terminator).
13702
    */
13703
    static std::size_t calc_bson_entry_header_size(const string_t& name)
13704
    {
13705
        const auto it = name.find(static_cast<typename string_t::value_type>(0));
13706
        if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13707
        {
13708
            JSON_THROW(out_of_range::create(409,
13709
                                            "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13710
        }
13711
13712
        return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13713
    }
13714
13715
    /*!
13716
    @brief Writes the given @a element_type and @a name to the output adapter
13717
    */
13718
    void write_bson_entry_header(const string_t& name,
13719
                                 const std::uint8_t element_type)
13720
    {
13721
        oa->write_character(to_char_type(element_type)); // boolean
13722
        oa->write_characters(
13723
            reinterpret_cast<const CharType*>(name.c_str()),
13724
            name.size() + 1u);
13725
    }
13726
13727
    /*!
13728
    @brief Writes a BSON element with key @a name and boolean value @a value
13729
    */
13730
    void write_bson_boolean(const string_t& name,
13731
                            const bool value)
13732
    {
13733
        write_bson_entry_header(name, 0x08);
13734
        oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13735
    }
13736
13737
    /*!
13738
    @brief Writes a BSON element with key @a name and double value @a value
13739
    */
13740
    void write_bson_double(const string_t& name,
13741
                           const double value)
13742
    {
13743
        write_bson_entry_header(name, 0x01);
13744
        write_number<double, true>(value);
13745
    }
13746
13747
    /*!
13748
    @return The size of the BSON-encoded string in @a value
13749
    */
13750
    static std::size_t calc_bson_string_size(const string_t& value)
13751
    {
13752
        return sizeof(std::int32_t) + value.size() + 1ul;
13753
    }
13754
13755
    /*!
13756
    @brief Writes a BSON element with key @a name and string value @a value
13757
    */
13758
    void write_bson_string(const string_t& name,
13759
                           const string_t& value)
13760
    {
13761
        write_bson_entry_header(name, 0x02);
13762
13763
        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13764
        oa->write_characters(
13765
            reinterpret_cast<const CharType*>(value.c_str()),
13766
            value.size() + 1);
13767
    }
13768
13769
    /*!
13770
    @brief Writes a BSON element with key @a name and null value
13771
    */
13772
    void write_bson_null(const string_t& name)
13773
    {
13774
        write_bson_entry_header(name, 0x0A);
13775
    }
13776
13777
    /*!
13778
    @return The size of the BSON-encoded integer @a value
13779
    */
13780
    static std::size_t calc_bson_integer_size(const std::int64_t value)
13781
    {
13782
        return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
13783
               ? sizeof(std::int32_t)
13784
               : sizeof(std::int64_t);
13785
    }
13786
13787
    /*!
13788
    @brief Writes a BSON element with key @a name and integer @a value
13789
    */
13790
    void write_bson_integer(const string_t& name,
13791
                            const std::int64_t value)
13792
    {
13793
        if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
13794
        {
13795
            write_bson_entry_header(name, 0x10); // int32
13796
            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13797
        }
13798
        else
13799
        {
13800
            write_bson_entry_header(name, 0x12); // int64
13801
            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13802
        }
13803
    }
13804
13805
    /*!
13806
    @return The size of the BSON-encoded unsigned integer in @a j
13807
    */
13808
    static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13809
    {
13810
        return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13811
               ? sizeof(std::int32_t)
13812
               : sizeof(std::int64_t);
13813
    }
13814
13815
    /*!
13816
    @brief Writes a BSON element with key @a name and unsigned @a value
13817
    */
13818
    void write_bson_unsigned(const string_t& name,
13819
                             const std::uint64_t value)
13820
    {
13821
        if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13822
        {
13823
            write_bson_entry_header(name, 0x10 /* int32 */);
13824
            write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13825
        }
13826
        else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13827
        {
13828
            write_bson_entry_header(name, 0x12 /* int64 */);
13829
            write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13830
        }
13831
        else
13832
        {
13833
            JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13834
        }
13835
    }
13836
13837
    /*!
13838
    @brief Writes a BSON element with key @a name and object @a value
13839
    */
13840
    void write_bson_object_entry(const string_t& name,
13841
                                 const typename BasicJsonType::object_t& value)
13842
    {
13843
        write_bson_entry_header(name, 0x03); // object
13844
        write_bson_object(value);
13845
    }
13846
13847
    /*!
13848
    @return The size of the BSON-encoded array @a value
13849
    */
13850
    static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13851
    {
13852
        std::size_t array_index = 0ul;
13853
13854
        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)
13855
        {
13856
            return result + calc_bson_element_size(std::to_string(array_index++), el);
13857
        });
13858
13859
        return sizeof(std::int32_t) + embedded_document_size + 1ul;
13860
    }
13861
13862
    /*!
13863
    @return The size of the BSON-encoded binary array @a value
13864
    */
13865
    static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13866
    {
13867
        return sizeof(std::int32_t) + value.size() + 1ul;
13868
    }
13869
13870
    /*!
13871
    @brief Writes a BSON element with key @a name and array @a value
13872
    */
13873
    void write_bson_array(const string_t& name,
13874
                          const typename BasicJsonType::array_t& value)
13875
    {
13876
        write_bson_entry_header(name, 0x04); // array
13877
        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13878
13879
        std::size_t array_index = 0ul;
13880
13881
        for (const auto& el : value)
13882
        {
13883
            write_bson_element(std::to_string(array_index++), el);
13884
        }
13885
13886
        oa->write_character(to_char_type(0x00));
13887
    }
13888
13889
    /*!
13890
    @brief Writes a BSON element with key @a name and binary value @a value
13891
    */
13892
    void write_bson_binary(const string_t& name,
13893
                           const binary_t& value)
13894
    {
13895
        write_bson_entry_header(name, 0x05);
13896
13897
        write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13898
        write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13899
13900
        oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13901
    }
13902
13903
    /*!
13904
    @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
13905
    @return The calculated size for the BSON document entry for @a j with the given @a name.
13906
    */
13907
    static std::size_t calc_bson_element_size(const string_t& name,
13908
            const BasicJsonType& j)
13909
    {
13910
        const auto header_size = calc_bson_entry_header_size(name);
13911
        switch (j.type())
13912
        {
13913
            case value_t::object:
13914
                return header_size + calc_bson_object_size(*j.m_value.object);
13915
13916
            case value_t::array:
13917
                return header_size + calc_bson_array_size(*j.m_value.array);
13918
13919
            case value_t::binary:
13920
                return header_size + calc_bson_binary_size(*j.m_value.binary);
13921
13922
            case value_t::boolean:
13923
                return header_size + 1ul;
13924
13925
            case value_t::number_float:
13926
                return header_size + 8ul;
13927
13928
            case value_t::number_integer:
13929
                return header_size + calc_bson_integer_size(j.m_value.number_integer);
13930
13931
            case value_t::number_unsigned:
13932
                return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13933
13934
            case value_t::string:
13935
                return header_size + calc_bson_string_size(*j.m_value.string);
13936
13937
            case value_t::null:
13938
                return header_size + 0ul;
13939
13940
            // LCOV_EXCL_START
13941
            default:
13942
                JSON_ASSERT(false);
13943
                return 0ul;
13944
                // LCOV_EXCL_STOP
13945
        }
13946
    }
13947
13948
    /*!
13949
    @brief Serializes the JSON value @a j to BSON and associates it with the
13950
           key @a name.
13951
    @param name The name to associate with the JSON entity @a j within the
13952
                current BSON document
13953
    @return The size of the BSON entry
13954
    */
13955
    void write_bson_element(const string_t& name,
13956
                            const BasicJsonType& j)
13957
    {
13958
        switch (j.type())
13959
        {
13960
            case value_t::object:
13961
                return write_bson_object_entry(name, *j.m_value.object);
13962
13963
            case value_t::array:
13964
                return write_bson_array(name, *j.m_value.array);
13965
13966
            case value_t::binary:
13967
                return write_bson_binary(name, *j.m_value.binary);
13968
13969
            case value_t::boolean:
13970
                return write_bson_boolean(name, j.m_value.boolean);
13971
13972
            case value_t::number_float:
13973
                return write_bson_double(name, j.m_value.number_float);
13974
13975
            case value_t::number_integer:
13976
                return write_bson_integer(name, j.m_value.number_integer);
13977
13978
            case value_t::number_unsigned:
13979
                return write_bson_unsigned(name, j.m_value.number_unsigned);
13980
13981
            case value_t::string:
13982
                return write_bson_string(name, *j.m_value.string);
13983
13984
            case value_t::null:
13985
                return write_bson_null(name);
13986
13987
            // LCOV_EXCL_START
13988
            default:
13989
                JSON_ASSERT(false);
13990
                return;
13991
                // LCOV_EXCL_STOP
13992
        }
13993
    }
13994
13995
    /*!
13996
    @brief Calculates the size of the BSON serialization of the given
13997
           JSON-object @a j.
13998
    @param[in] j  JSON value to serialize
13999
    @pre       j.type() == value_t::object
14000
    */
14001
    static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14002
    {
14003
        std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14004
                                    [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14005
        {
14006
            return result += calc_bson_element_size(el.first, el.second);
14007
        });
14008
14009
        return sizeof(std::int32_t) + document_size + 1ul;
14010
    }
14011
14012
    /*!
14013
    @param[in] j  JSON value to serialize
14014
    @pre       j.type() == value_t::object
14015
    */
14016
    void write_bson_object(const typename BasicJsonType::object_t& value)
14017
    {
14018
        write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14019
14020
        for (const auto& el : value)
14021
        {
14022
            write_bson_element(el.first, el.second);
14023
        }
14024
14025
        oa->write_character(to_char_type(0x00));
14026
    }
14027
14028
    //////////
14029
    // CBOR //
14030
    //////////
14031
14032
    static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14033
    {
14034
        return to_char_type(0xFA);  // Single-Precision Float
14035
    }
14036
14037
    static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14038
    {
14039
        return to_char_type(0xFB);  // Double-Precision Float
14040
    }
14041
14042
    /////////////
14043
    // MsgPack //
14044
    /////////////
14045
14046
    static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14047
    {
14048
        return to_char_type(0xCA);  // float 32
14049
    }
14050
14051
    static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14052
    {
14053
        return to_char_type(0xCB);  // float 64
14054
    }
14055
14056
    ////////////
14057
    // UBJSON //
14058
    ////////////
14059
14060
    // UBJSON: write number (floating point)
14061
    template<typename NumberType, typename std::enable_if<
14062
                 std::is_floating_point<NumberType>::value, int>::type = 0>
14063
    void write_number_with_ubjson_prefix(const NumberType n,
14064
                                         const bool add_prefix)
14065
    {
14066
        if (add_prefix)
14067
        {
14068
            oa->write_character(get_ubjson_float_prefix(n));
14069
        }
14070
        write_number(n);
14071
    }
14072
14073
    // UBJSON: write number (unsigned integer)
14074
    template<typename NumberType, typename std::enable_if<
14075
                 std::is_unsigned<NumberType>::value, int>::type = 0>
14076
    void write_number_with_ubjson_prefix(const NumberType n,
14077
                                         const bool add_prefix)
14078
    {
14079
        if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14080
        {
14081
            if (add_prefix)
14082
            {
14083
                oa->write_character(to_char_type('i'));  // int8
14084
            }
14085
            write_number(static_cast<std::uint8_t>(n));
14086
        }
14087
        else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14088
        {
14089
            if (add_prefix)
14090
            {
14091
                oa->write_character(to_char_type('U'));  // uint8
14092
            }
14093
            write_number(static_cast<std::uint8_t>(n));
14094
        }
14095
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14096
        {
14097
            if (add_prefix)
14098
            {
14099
                oa->write_character(to_char_type('I'));  // int16
14100
            }
14101
            write_number(static_cast<std::int16_t>(n));
14102
        }
14103
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14104
        {
14105
            if (add_prefix)
14106
            {
14107
                oa->write_character(to_char_type('l'));  // int32
14108
            }
14109
            write_number(static_cast<std::int32_t>(n));
14110
        }
14111
        else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14112
        {
14113
            if (add_prefix)
14114
            {
14115
                oa->write_character(to_char_type('L'));  // int64
14116
            }
14117
            write_number(static_cast<std::int64_t>(n));
14118
        }
14119
        else
14120
        {
14121
            if (add_prefix)
14122
            {
14123
                oa->write_character(to_char_type('H'));  // high-precision number
14124
            }
14125
14126
            const auto number = BasicJsonType(n).dump();
14127
            write_number_with_ubjson_prefix(number.size(), true);
14128
            for (std::size_t i = 0; i < number.size(); ++i)
14129
            {
14130
                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14131
            }
14132
        }
14133
    }
14134
14135
    // UBJSON: write number (signed integer)
14136
    template < typename NumberType, typename std::enable_if <
14137
                   std::is_signed<NumberType>::value&&
14138
                   !std::is_floating_point<NumberType>::value, int >::type = 0 >
14139
    void write_number_with_ubjson_prefix(const NumberType n,
14140
                                         const bool add_prefix)
14141
    {
14142
        if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14143
        {
14144
            if (add_prefix)
14145
            {
14146
                oa->write_character(to_char_type('i'));  // int8
14147
            }
14148
            write_number(static_cast<std::int8_t>(n));
14149
        }
14150
        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)()))
14151
        {
14152
            if (add_prefix)
14153
            {
14154
                oa->write_character(to_char_type('U'));  // uint8
14155
            }
14156
            write_number(static_cast<std::uint8_t>(n));
14157
        }
14158
        else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14159
        {
14160
            if (add_prefix)
14161
            {
14162
                oa->write_character(to_char_type('I'));  // int16
14163
            }
14164
            write_number(static_cast<std::int16_t>(n));
14165
        }
14166
        else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14167
        {
14168
            if (add_prefix)
14169
            {
14170
                oa->write_character(to_char_type('l'));  // int32
14171
            }
14172
            write_number(static_cast<std::int32_t>(n));
14173
        }
14174
        else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14175
        {
14176
            if (add_prefix)
14177
            {
14178
                oa->write_character(to_char_type('L'));  // int64
14179
            }
14180
            write_number(static_cast<std::int64_t>(n));
14181
        }
14182
        // LCOV_EXCL_START
14183
        else
14184
        {
14185
            if (add_prefix)
14186
            {
14187
                oa->write_character(to_char_type('H'));  // high-precision number
14188
            }
14189
14190
            const auto number = BasicJsonType(n).dump();
14191
            write_number_with_ubjson_prefix(number.size(), true);
14192
            for (std::size_t i = 0; i < number.size(); ++i)
14193
            {
14194
                oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14195
            }
14196
        }
14197
        // LCOV_EXCL_STOP
14198
    }
14199
14200
    /*!
14201
    @brief determine the type prefix of container values
14202
    */
14203
    CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14204
    {
14205
        switch (j.type())
14206
        {
14207
            case value_t::null:
14208
                return 'Z';
14209
14210
            case value_t::boolean:
14211
                return j.m_value.boolean ? 'T' : 'F';
14212
14213
            case value_t::number_integer:
14214
            {
14215
                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)())
14216
                {
14217
                    return 'i';
14218
                }
14219
                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)())
14220
                {
14221
                    return 'U';
14222
                }
14223
                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)())
14224
                {
14225
                    return 'I';
14226
                }
14227
                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)())
14228
                {
14229
                    return 'l';
14230
                }
14231
                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)())
14232
                {
14233
                    return 'L';
14234
                }
14235
                // anything else is treated as high-precision number
14236
                return 'H'; // LCOV_EXCL_LINE
14237
            }
14238
14239
            case value_t::number_unsigned:
14240
            {
14241
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14242
                {
14243
                    return 'i';
14244
                }
14245
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14246
                {
14247
                    return 'U';
14248
                }
14249
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14250
                {
14251
                    return 'I';
14252
                }
14253
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14254
                {
14255
                    return 'l';
14256
                }
14257
                if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14258
                {
14259
                    return 'L';
14260
                }
14261
                // anything else is treated as high-precision number
14262
                return 'H'; // LCOV_EXCL_LINE
14263
            }
14264
14265
            case value_t::number_float:
14266
                return get_ubjson_float_prefix(j.m_value.number_float);
14267
14268
            case value_t::string:
14269
                return 'S';
14270
14271
            case value_t::array: // fallthrough
14272
            case value_t::binary:
14273
                return '[';
14274
14275
            case value_t::object:
14276
                return '{';
14277
14278
            default:  // discarded values
14279
                return 'N';
14280
        }
14281
    }
14282
14283
    static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14284
    {
14285
        return 'd';  // float 32
14286
    }
14287
14288
    static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14289
    {
14290
        return 'D';  // float 64
14291
    }
14292
14293
    ///////////////////////
14294
    // Utility functions //
14295
    ///////////////////////
14296
14297
    /*
14298
    @brief write a number to output input
14299
    @param[in] n number of type @a NumberType
14300
    @tparam NumberType the type of the number
14301
    @tparam OutputIsLittleEndian Set to true if output data is
14302
                                 required to be little endian
14303
14304
    @note This function needs to respect the system's endianess, because bytes
14305
          in CBOR, MessagePack, and UBJSON are stored in network order (big
14306
          endian) and therefore need reordering on little endian systems.
14307
    */
14308
    template<typename NumberType, bool OutputIsLittleEndian = false>
14309
    void write_number(const NumberType n)
14310
    {
14311
        // step 1: write number to array of length NumberType
14312
        std::array<CharType, sizeof(NumberType)> vec;
14313
        std::memcpy(vec.data(), &n, sizeof(NumberType));
14314
14315
        // step 2: write array to output (with possible reordering)
14316
        if (is_little_endian != OutputIsLittleEndian)
14317
        {
14318
            // reverse byte order prior to conversion if necessary
14319
            std::reverse(vec.begin(), vec.end());
14320
        }
14321
14322
        oa->write_characters(vec.data(), sizeof(NumberType));
14323
    }
14324
14325
    void write_compact_float(const number_float_t n, detail::input_format_t format)
14326
    {
14327
        if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14328
                static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14329
                static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14330
        {
14331
            oa->write_character(format == detail::input_format_t::cbor
14332
                                ? get_cbor_float_prefix(static_cast<float>(n))
14333
                                : get_msgpack_float_prefix(static_cast<float>(n)));
14334
            write_number(static_cast<float>(n));
14335
        }
14336
        else
14337
        {
14338
            oa->write_character(format == detail::input_format_t::cbor
14339
                                ? get_cbor_float_prefix(n)
14340
                                : get_msgpack_float_prefix(n));
14341
            write_number(n);
14342
        }
14343
    }
14344
14345
  public:
14346
    // The following to_char_type functions are implement the conversion
14347
    // between uint8_t and CharType. In case CharType is not unsigned,
14348
    // such a conversion is required to allow values greater than 128.
14349
    // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14350
    template < typename C = CharType,
14351
               enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
14352
    static constexpr CharType to_char_type(std::uint8_t x) noexcept
14353
    {
14354
        return *reinterpret_cast<char*>(&x);
14355
    }
14356
14357
    template < typename C = CharType,
14358
               enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
14359
    static CharType to_char_type(std::uint8_t x) noexcept
14360
    {
14361
        static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14362
        static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14363
        CharType result;
14364
        std::memcpy(&result, &x, sizeof(x));
14365
        return result;
14366
    }
14367
14368
    template<typename C = CharType,
14369
             enable_if_t<std::is_unsigned<C>::value>* = nullptr>
14370
    static constexpr CharType to_char_type(std::uint8_t x) noexcept
14371
    {
14372
        return x;
14373
    }
14374
14375
    template < typename InputCharType, typename C = CharType,
14376
               enable_if_t <
14377
                   std::is_signed<C>::value &&
14378
                   std::is_signed<char>::value &&
14379
                   std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14380
                   > * = nullptr >
14381
    static constexpr CharType to_char_type(InputCharType x) noexcept
14382
0
    {
14383
0
        return x;
14384
0
    }
14385
14386
  private:
14387
    /// whether we can assume little endianess
14388
    const bool is_little_endian = little_endianess();
14389
14390
    /// the output
14391
    output_adapter_t<CharType> oa = nullptr;
14392
};
14393
}  // namespace detail
14394
}  // namespace nlohmann
14395
14396
// #include <nlohmann/detail/output/output_adapters.hpp>
14397
14398
// #include <nlohmann/detail/output/serializer.hpp>
14399
14400
14401
#include <algorithm> // reverse, remove, fill, find, none_of
14402
#include <array> // array
14403
#include <clocale> // localeconv, lconv
14404
#include <cmath> // labs, isfinite, isnan, signbit
14405
#include <cstddef> // size_t, ptrdiff_t
14406
#include <cstdint> // uint8_t
14407
#include <cstdio> // snprintf
14408
#include <limits> // numeric_limits
14409
#include <string> // string, char_traits
14410
#include <type_traits> // is_same
14411
#include <utility> // move
14412
14413
// #include <nlohmann/detail/conversions/to_chars.hpp>
14414
14415
14416
#include <array> // array
14417
#include <cmath>   // signbit, isfinite
14418
#include <cstdint> // intN_t, uintN_t
14419
#include <cstring> // memcpy, memmove
14420
#include <limits> // numeric_limits
14421
#include <type_traits> // conditional
14422
14423
// #include <nlohmann/detail/macro_scope.hpp>
14424
14425
14426
namespace nlohmann
14427
{
14428
namespace detail
14429
{
14430
14431
/*!
14432
@brief implements the Grisu2 algorithm for binary to decimal floating-point
14433
conversion.
14434
14435
This implementation is a slightly modified version of the reference
14436
implementation which may be obtained from
14437
http://florian.loitsch.com/publications (bench.tar.gz).
14438
14439
The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
14440
14441
For a detailed description of the algorithm see:
14442
14443
[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
14444
    Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
14445
    Language Design and Implementation, PLDI 2010
14446
[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
14447
    Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
14448
    Design and Implementation, PLDI 1996
14449
*/
14450
namespace dtoa_impl
14451
{
14452
14453
template<typename Target, typename Source>
14454
Target reinterpret_bits(const Source source)
14455
0
{
14456
0
    static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14457
14458
0
    Target target;
14459
0
    std::memcpy(&target, &source, sizeof(Source));
14460
0
    return target;
14461
0
}
14462
14463
struct diyfp // f * 2^e
14464
{
14465
    static constexpr int kPrecision = 64; // = q
14466
14467
    std::uint64_t f = 0;
14468
    int e = 0;
14469
14470
0
    constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14471
14472
    /*!
14473
    @brief returns x - y
14474
    @pre x.e == y.e and x.f >= y.f
14475
    */
14476
    static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14477
0
    {
14478
0
        JSON_ASSERT(x.e == y.e);
14479
0
        JSON_ASSERT(x.f >= y.f);
14480
14481
0
        return {x.f - y.f, x.e};
14482
0
    }
14483
14484
    /*!
14485
    @brief returns x * y
14486
    @note The result is rounded. (Only the upper q bits are returned.)
14487
    */
14488
    static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14489
0
    {
14490
0
        static_assert(kPrecision == 64, "internal error");
14491
14492
        // Computes:
14493
        //  f = round((x.f * y.f) / 2^q)
14494
        //  e = x.e + y.e + q
14495
14496
        // Emulate the 64-bit * 64-bit multiplication:
14497
        //
14498
        // p = u * v
14499
        //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14500
        //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
14501
        //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
14502
        //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
14503
        //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
14504
        //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
14505
        //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
14506
        //
14507
        // (Since Q might be larger than 2^32 - 1)
14508
        //
14509
        //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14510
        //
14511
        // (Q_hi + H does not overflow a 64-bit int)
14512
        //
14513
        //   = p_lo + 2^64 p_hi
14514
14515
0
        const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14516
0
        const std::uint64_t u_hi = x.f >> 32u;
14517
0
        const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14518
0
        const std::uint64_t v_hi = y.f >> 32u;
14519
14520
0
        const std::uint64_t p0 = u_lo * v_lo;
14521
0
        const std::uint64_t p1 = u_lo * v_hi;
14522
0
        const std::uint64_t p2 = u_hi * v_lo;
14523
0
        const std::uint64_t p3 = u_hi * v_hi;
14524
14525
0
        const std::uint64_t p0_hi = p0 >> 32u;
14526
0
        const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14527
0
        const std::uint64_t p1_hi = p1 >> 32u;
14528
0
        const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14529
0
        const std::uint64_t p2_hi = p2 >> 32u;
14530
14531
0
        std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14532
14533
        // The full product might now be computed as
14534
        //
14535
        // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14536
        // p_lo = p0_lo + (Q << 32)
14537
        //
14538
        // But in this particular case here, the full p_lo is not required.
14539
        // Effectively we only need to add the highest bit in p_lo to p_hi (and
14540
        // Q_hi + 1 does not overflow).
14541
14542
0
        Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14543
14544
0
        const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14545
14546
0
        return {h, x.e + y.e + 64};
14547
0
    }
14548
14549
    /*!
14550
    @brief normalize x such that the significand is >= 2^(q-1)
14551
    @pre x.f != 0
14552
    */
14553
    static diyfp normalize(diyfp x) noexcept
14554
0
    {
14555
0
        JSON_ASSERT(x.f != 0);
14556
14557
0
        while ((x.f >> 63u) == 0)
14558
0
        {
14559
0
            x.f <<= 1u;
14560
0
            x.e--;
14561
0
        }
14562
14563
0
        return x;
14564
0
    }
14565
14566
    /*!
14567
    @brief normalize x such that the result has the exponent E
14568
    @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
14569
    */
14570
    static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
14571
0
    {
14572
0
        const int delta = x.e - target_exponent;
14573
14574
0
        JSON_ASSERT(delta >= 0);
14575
0
        JSON_ASSERT(((x.f << delta) >> delta) == x.f);
14576
14577
0
        return {x.f << delta, target_exponent};
14578
0
    }
14579
};
14580
14581
struct boundaries
14582
{
14583
    diyfp w;
14584
    diyfp minus;
14585
    diyfp plus;
14586
};
14587
14588
/*!
14589
Compute the (normalized) diyfp representing the input number 'value' and its
14590
boundaries.
14591
14592
@pre value must be finite and positive
14593
*/
14594
template<typename FloatType>
14595
boundaries compute_boundaries(FloatType value)
14596
0
{
14597
0
    JSON_ASSERT(std::isfinite(value));
14598
0
    JSON_ASSERT(value > 0);
14599
14600
    // Convert the IEEE representation into a diyfp.
14601
    //
14602
    // If v is denormal:
14603
    //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
14604
    // If v is normalized:
14605
    //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14606
14607
0
    static_assert(std::numeric_limits<FloatType>::is_iec559,
14608
0
                  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14609
14610
0
    constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14611
0
    constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14612
0
    constexpr int      kMinExp    = 1 - kBias;
14613
0
    constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14614
14615
0
    using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14616
14617
0
    const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14618
0
    const std::uint64_t E = bits >> (kPrecision - 1);
14619
0
    const std::uint64_t F = bits & (kHiddenBit - 1);
14620
14621
0
    const bool is_denormal = E == 0;
14622
0
    const diyfp v = is_denormal
14623
0
                    ? diyfp(F, kMinExp)
14624
0
                    : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14625
14626
    // Compute the boundaries m- and m+ of the floating-point value
14627
    // v = f * 2^e.
14628
    //
14629
    // Determine v- and v+, the floating-point predecessor and successor if v,
14630
    // respectively.
14631
    //
14632
    //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
14633
    //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
14634
    //
14635
    //      v+ = v + 2^e
14636
    //
14637
    // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14638
    // between m- and m+ round to v, regardless of how the input rounding
14639
    // algorithm breaks ties.
14640
    //
14641
    //      ---+-------------+-------------+-------------+-------------+---  (A)
14642
    //         v-            m-            v             m+            v+
14643
    //
14644
    //      -----------------+------+------+-------------+-------------+---  (B)
14645
    //                       v-     m-     v             m+            v+
14646
14647
0
    const bool lower_boundary_is_closer = F == 0 && E > 1;
14648
0
    const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14649
0
    const diyfp m_minus = lower_boundary_is_closer
14650
0
                          ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
14651
0
                          : diyfp(2 * v.f - 1, v.e - 1); // (A)
14652
14653
    // Determine the normalized w+ = m+.
14654
0
    const diyfp w_plus = diyfp::normalize(m_plus);
14655
14656
    // Determine w- = m- such that e_(w-) = e_(w+).
14657
0
    const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14658
14659
0
    return {diyfp::normalize(v), w_minus, w_plus};
14660
0
}
14661
14662
// Given normalized diyfp w, Grisu needs to find a (normalized) cached
14663
// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14664
// within a certain range [alpha, gamma] (Definition 3.2 from [1])
14665
//
14666
//      alpha <= e = e_c + e_w + q <= gamma
14667
//
14668
// or
14669
//
14670
//      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14671
//                          <= f_c * f_w * 2^gamma
14672
//
14673
// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14674
//
14675
//      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14676
//
14677
// or
14678
//
14679
//      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14680
//
14681
// The choice of (alpha,gamma) determines the size of the table and the form of
14682
// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14683
// in practice:
14684
//
14685
// The idea is to cut the number c * w = f * 2^e into two parts, which can be
14686
// processed independently: An integral part p1, and a fractional part p2:
14687
//
14688
//      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14689
//              = (f div 2^-e) + (f mod 2^-e) * 2^e
14690
//              = p1 + p2 * 2^e
14691
//
14692
// The conversion of p1 into decimal form requires a series of divisions and
14693
// modulos by (a power of) 10. These operations are faster for 32-bit than for
14694
// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14695
// achieved by choosing
14696
//
14697
//      -e >= 32   or   e <= -32 := gamma
14698
//
14699
// In order to convert the fractional part
14700
//
14701
//      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14702
//
14703
// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14704
// d[-i] are extracted in order:
14705
//
14706
//      (10 * p2) div 2^-e = d[-1]
14707
//      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14708
//
14709
// The multiplication by 10 must not overflow. It is sufficient to choose
14710
//
14711
//      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14712
//
14713
// Since p2 = f mod 2^-e < 2^-e,
14714
//
14715
//      -e <= 60   or   e >= -60 := alpha
14716
14717
constexpr int kAlpha = -60;
14718
constexpr int kGamma = -32;
14719
14720
struct cached_power // c = f * 2^e ~= 10^k
14721
{
14722
    std::uint64_t f;
14723
    int e;
14724
    int k;
14725
};
14726
14727
/*!
14728
For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
14729
power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
14730
satisfies (Definition 3.2 from [1])
14731
14732
     alpha <= e_c + e + q <= gamma.
14733
*/
14734
inline cached_power get_cached_power_for_binary_exponent(int e)
14735
0
{
14736
    // Now
14737
    //
14738
    //      alpha <= e_c + e + q <= gamma                                    (1)
14739
    //      ==> f_c * 2^alpha <= c * 2^e * 2^q
14740
    //
14741
    // and since the c's are normalized, 2^(q-1) <= f_c,
14742
    //
14743
    //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14744
    //      ==> 2^(alpha - e - 1) <= c
14745
    //
14746
    // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14747
    //
14748
    //      k = ceil( log_10( 2^(alpha - e - 1) ) )
14749
    //        = ceil( (alpha - e - 1) * log_10(2) )
14750
    //
14751
    // From the paper:
14752
    // "In theory the result of the procedure could be wrong since c is rounded,
14753
    //  and the computation itself is approximated [...]. In practice, however,
14754
    //  this simple function is sufficient."
14755
    //
14756
    // For IEEE double precision floating-point numbers converted into
14757
    // normalized diyfp's w = f * 2^e, with q = 64,
14758
    //
14759
    //      e >= -1022      (min IEEE exponent)
14760
    //           -52        (p - 1)
14761
    //           -52        (p - 1, possibly normalize denormal IEEE numbers)
14762
    //           -11        (normalize the diyfp)
14763
    //         = -1137
14764
    //
14765
    // and
14766
    //
14767
    //      e <= +1023      (max IEEE exponent)
14768
    //           -52        (p - 1)
14769
    //           -11        (normalize the diyfp)
14770
    //         = 960
14771
    //
14772
    // This binary exponent range [-1137,960] results in a decimal exponent
14773
    // range [-307,324]. One does not need to store a cached power for each
14774
    // k in this range. For each such k it suffices to find a cached power
14775
    // such that the exponent of the product lies in [alpha,gamma].
14776
    // This implies that the difference of the decimal exponents of adjacent
14777
    // table entries must be less than or equal to
14778
    //
14779
    //      floor( (gamma - alpha) * log_10(2) ) = 8.
14780
    //
14781
    // (A smaller distance gamma-alpha would require a larger table.)
14782
14783
    // NB:
14784
    // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14785
14786
0
    constexpr int kCachedPowersMinDecExp = -300;
14787
0
    constexpr int kCachedPowersDecStep = 8;
14788
14789
0
    static constexpr std::array<cached_power, 79> kCachedPowers =
14790
0
    {
14791
0
        {
14792
0
            { 0xAB70FE17C79AC6CA, -1060, -300 },
14793
0
            { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14794
0
            { 0xBE5691EF416BD60C, -1007, -284 },
14795
0
            { 0x8DD01FAD907FFC3C,  -980, -276 },
14796
0
            { 0xD3515C2831559A83,  -954, -268 },
14797
0
            { 0x9D71AC8FADA6C9B5,  -927, -260 },
14798
0
            { 0xEA9C227723EE8BCB,  -901, -252 },
14799
0
            { 0xAECC49914078536D,  -874, -244 },
14800
0
            { 0x823C12795DB6CE57,  -847, -236 },
14801
0
            { 0xC21094364DFB5637,  -821, -228 },
14802
0
            { 0x9096EA6F3848984F,  -794, -220 },
14803
0
            { 0xD77485CB25823AC7,  -768, -212 },
14804
0
            { 0xA086CFCD97BF97F4,  -741, -204 },
14805
0
            { 0xEF340A98172AACE5,  -715, -196 },
14806
0
            { 0xB23867FB2A35B28E,  -688, -188 },
14807
0
            { 0x84C8D4DFD2C63F3B,  -661, -180 },
14808
0
            { 0xC5DD44271AD3CDBA,  -635, -172 },
14809
0
            { 0x936B9FCEBB25C996,  -608, -164 },
14810
0
            { 0xDBAC6C247D62A584,  -582, -156 },
14811
0
            { 0xA3AB66580D5FDAF6,  -555, -148 },
14812
0
            { 0xF3E2F893DEC3F126,  -529, -140 },
14813
0
            { 0xB5B5ADA8AAFF80B8,  -502, -132 },
14814
0
            { 0x87625F056C7C4A8B,  -475, -124 },
14815
0
            { 0xC9BCFF6034C13053,  -449, -116 },
14816
0
            { 0x964E858C91BA2655,  -422, -108 },
14817
0
            { 0xDFF9772470297EBD,  -396, -100 },
14818
0
            { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
14819
0
            { 0xF8A95FCF88747D94,  -343,  -84 },
14820
0
            { 0xB94470938FA89BCF,  -316,  -76 },
14821
0
            { 0x8A08F0F8BF0F156B,  -289,  -68 },
14822
0
            { 0xCDB02555653131B6,  -263,  -60 },
14823
0
            { 0x993FE2C6D07B7FAC,  -236,  -52 },
14824
0
            { 0xE45C10C42A2B3B06,  -210,  -44 },
14825
0
            { 0xAA242499697392D3,  -183,  -36 },
14826
0
            { 0xFD87B5F28300CA0E,  -157,  -28 },
14827
0
            { 0xBCE5086492111AEB,  -130,  -20 },
14828
0
            { 0x8CBCCC096F5088CC,  -103,  -12 },
14829
0
            { 0xD1B71758E219652C,   -77,   -4 },
14830
0
            { 0x9C40000000000000,   -50,    4 },
14831
0
            { 0xE8D4A51000000000,   -24,   12 },
14832
0
            { 0xAD78EBC5AC620000,     3,   20 },
14833
0
            { 0x813F3978F8940984,    30,   28 },
14834
0
            { 0xC097CE7BC90715B3,    56,   36 },
14835
0
            { 0x8F7E32CE7BEA5C70,    83,   44 },
14836
0
            { 0xD5D238A4ABE98068,   109,   52 },
14837
0
            { 0x9F4F2726179A2245,   136,   60 },
14838
0
            { 0xED63A231D4C4FB27,   162,   68 },
14839
0
            { 0xB0DE65388CC8ADA8,   189,   76 },
14840
0
            { 0x83C7088E1AAB65DB,   216,   84 },
14841
0
            { 0xC45D1DF942711D9A,   242,   92 },
14842
0
            { 0x924D692CA61BE758,   269,  100 },
14843
0
            { 0xDA01EE641A708DEA,   295,  108 },
14844
0
            { 0xA26DA3999AEF774A,   322,  116 },
14845
0
            { 0xF209787BB47D6B85,   348,  124 },
14846
0
            { 0xB454E4A179DD1877,   375,  132 },
14847
0
            { 0x865B86925B9BC5C2,   402,  140 },
14848
0
            { 0xC83553C5C8965D3D,   428,  148 },
14849
0
            { 0x952AB45CFA97A0B3,   455,  156 },
14850
0
            { 0xDE469FBD99A05FE3,   481,  164 },
14851
0
            { 0xA59BC234DB398C25,   508,  172 },
14852
0
            { 0xF6C69A72A3989F5C,   534,  180 },
14853
0
            { 0xB7DCBF5354E9BECE,   561,  188 },
14854
0
            { 0x88FCF317F22241E2,   588,  196 },
14855
0
            { 0xCC20CE9BD35C78A5,   614,  204 },
14856
0
            { 0x98165AF37B2153DF,   641,  212 },
14857
0
            { 0xE2A0B5DC971F303A,   667,  220 },
14858
0
            { 0xA8D9D1535CE3B396,   694,  228 },
14859
0
            { 0xFB9B7CD9A4A7443C,   720,  236 },
14860
0
            { 0xBB764C4CA7A44410,   747,  244 },
14861
0
            { 0x8BAB8EEFB6409C1A,   774,  252 },
14862
0
            { 0xD01FEF10A657842C,   800,  260 },
14863
0
            { 0x9B10A4E5E9913129,   827,  268 },
14864
0
            { 0xE7109BFBA19C0C9D,   853,  276 },
14865
0
            { 0xAC2820D9623BF429,   880,  284 },
14866
0
            { 0x80444B5E7AA7CF85,   907,  292 },
14867
0
            { 0xBF21E44003ACDD2D,   933,  300 },
14868
0
            { 0x8E679C2F5E44FF8F,   960,  308 },
14869
0
            { 0xD433179D9C8CB841,   986,  316 },
14870
0
            { 0x9E19DB92B4E31BA9,  1013,  324 },
14871
0
        }
14872
0
    };
14873
14874
    // This computation gives exactly the same results for k as
14875
    //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14876
    // for |e| <= 1500, but doesn't require floating-point operations.
14877
    // NB: log_10(2) ~= 78913 / 2^18
14878
0
    JSON_ASSERT(e >= -1500);
14879
0
    JSON_ASSERT(e <=  1500);
14880
0
    const int f = kAlpha - e - 1;
14881
0
    const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14882
14883
0
    const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14884
0
    JSON_ASSERT(index >= 0);
14885
0
    JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
14886
14887
0
    const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14888
0
    JSON_ASSERT(kAlpha <= cached.e + e + 64);
14889
0
    JSON_ASSERT(kGamma >= cached.e + e + 64);
14890
14891
0
    return cached;
14892
0
}
14893
14894
/*!
14895
For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
14896
For n == 0, returns 1 and sets pow10 := 1.
14897
*/
14898
inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14899
0
{
14900
    // LCOV_EXCL_START
14901
0
    if (n >= 1000000000)
14902
0
    {
14903
0
        pow10 = 1000000000;
14904
0
        return 10;
14905
0
    }
14906
    // LCOV_EXCL_STOP
14907
0
    else if (n >= 100000000)
14908
0
    {
14909
0
        pow10 = 100000000;
14910
0
        return  9;
14911
0
    }
14912
0
    else if (n >= 10000000)
14913
0
    {
14914
0
        pow10 = 10000000;
14915
0
        return  8;
14916
0
    }
14917
0
    else if (n >= 1000000)
14918
0
    {
14919
0
        pow10 = 1000000;
14920
0
        return  7;
14921
0
    }
14922
0
    else if (n >= 100000)
14923
0
    {
14924
0
        pow10 = 100000;
14925
0
        return  6;
14926
0
    }
14927
0
    else if (n >= 10000)
14928
0
    {
14929
0
        pow10 = 10000;
14930
0
        return  5;
14931
0
    }
14932
0
    else if (n >= 1000)
14933
0
    {
14934
0
        pow10 = 1000;
14935
0
        return  4;
14936
0
    }
14937
0
    else if (n >= 100)
14938
0
    {
14939
0
        pow10 = 100;
14940
0
        return  3;
14941
0
    }
14942
0
    else if (n >= 10)
14943
0
    {
14944
0
        pow10 = 10;
14945
0
        return  2;
14946
0
    }
14947
0
    else
14948
0
    {
14949
0
        pow10 = 1;
14950
0
        return 1;
14951
0
    }
14952
0
}
14953
14954
inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14955
                         std::uint64_t rest, std::uint64_t ten_k)
14956
0
{
14957
0
    JSON_ASSERT(len >= 1);
14958
0
    JSON_ASSERT(dist <= delta);
14959
0
    JSON_ASSERT(rest <= delta);
14960
0
    JSON_ASSERT(ten_k > 0);
14961
14962
    //               <--------------------------- delta ---->
14963
    //                                  <---- dist --------->
14964
    // --------------[------------------+-------------------]--------------
14965
    //               M-                 w                   M+
14966
    //
14967
    //                                  ten_k
14968
    //                                <------>
14969
    //                                       <---- rest ---->
14970
    // --------------[------------------+----+--------------]--------------
14971
    //                                  w    V
14972
    //                                       = buf * 10^k
14973
    //
14974
    // ten_k represents a unit-in-the-last-place in the decimal representation
14975
    // stored in buf.
14976
    // Decrement buf by ten_k while this takes buf closer to w.
14977
14978
    // The tests are written in this order to avoid overflow in unsigned
14979
    // integer arithmetic.
14980
14981
0
    while (rest < dist
14982
0
            && delta - rest >= ten_k
14983
0
            && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
14984
0
    {
14985
0
        JSON_ASSERT(buf[len - 1] != '0');
14986
0
        buf[len - 1]--;
14987
0
        rest += ten_k;
14988
0
    }
14989
0
}
14990
14991
/*!
14992
Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
14993
M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
14994
*/
14995
inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14996
                             diyfp M_minus, diyfp w, diyfp M_plus)
14997
0
{
14998
0
    static_assert(kAlpha >= -60, "internal error");
14999
0
    static_assert(kGamma <= -32, "internal error");
15000
15001
    // Generates the digits (and the exponent) of a decimal floating-point
15002
    // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15003
    // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15004
    //
15005
    //               <--------------------------- delta ---->
15006
    //                                  <---- dist --------->
15007
    // --------------[------------------+-------------------]--------------
15008
    //               M-                 w                   M+
15009
    //
15010
    // Grisu2 generates the digits of M+ from left to right and stops as soon as
15011
    // V is in [M-,M+].
15012
15013
0
    JSON_ASSERT(M_plus.e >= kAlpha);
15014
0
    JSON_ASSERT(M_plus.e <= kGamma);
15015
15016
0
    std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15017
0
    std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
15018
15019
    // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15020
    //
15021
    //      M+ = f * 2^e
15022
    //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15023
    //         = ((p1        ) * 2^-e + (p2        )) * 2^e
15024
    //         = p1 + p2 * 2^e
15025
15026
0
    const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15027
15028
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.)
15029
0
    std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
15030
15031
    // 1)
15032
    //
15033
    // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15034
15035
0
    JSON_ASSERT(p1 > 0);
15036
15037
0
    std::uint32_t pow10;
15038
0
    const int k = find_largest_pow10(p1, pow10);
15039
15040
    //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15041
    //
15042
    //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15043
    //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
15044
    //
15045
    //      M+ = p1                                             + p2 * 2^e
15046
    //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
15047
    //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15048
    //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
15049
    //
15050
    // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15051
    //
15052
    //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15053
    //
15054
    // but stop as soon as
15055
    //
15056
    //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15057
15058
0
    int n = k;
15059
0
    while (n > 0)
15060
0
    {
15061
        // Invariants:
15062
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
15063
        //      pow10 = 10^(n-1) <= p1 < 10^n
15064
        //
15065
0
        const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
15066
0
        const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
15067
        //
15068
        //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15069
        //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15070
        //
15071
0
        JSON_ASSERT(d <= 9);
15072
0
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15073
        //
15074
        //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15075
        //
15076
0
        p1 = r;
15077
0
        n--;
15078
        //
15079
        //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
15080
        //      pow10 = 10^n
15081
        //
15082
15083
        // Now check if enough digits have been generated.
15084
        // Compute
15085
        //
15086
        //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15087
        //
15088
        // Note:
15089
        // Since rest and delta share the same exponent e, it suffices to
15090
        // compare the significands.
15091
0
        const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15092
0
        if (rest <= delta)
15093
0
        {
15094
            // V = buffer * 10^n, with M- <= V <= M+.
15095
15096
0
            decimal_exponent += n;
15097
15098
            // We may now just stop. But instead look if the buffer could be
15099
            // decremented to bring V closer to w.
15100
            //
15101
            // pow10 = 10^n is now 1 ulp in the decimal representation V.
15102
            // The rounding procedure works with diyfp's with an implicit
15103
            // exponent of e.
15104
            //
15105
            //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15106
            //
15107
0
            const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15108
0
            grisu2_round(buffer, length, dist, delta, rest, ten_n);
15109
15110
0
            return;
15111
0
        }
15112
15113
0
        pow10 /= 10;
15114
        //
15115
        //      pow10 = 10^(n-1) <= p1 < 10^n
15116
        // Invariants restored.
15117
0
    }
15118
15119
    // 2)
15120
    //
15121
    // The digits of the integral part have been generated:
15122
    //
15123
    //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15124
    //         = buffer            + p2 * 2^e
15125
    //
15126
    // Now generate the digits of the fractional part p2 * 2^e.
15127
    //
15128
    // Note:
15129
    // No decimal point is generated: the exponent is adjusted instead.
15130
    //
15131
    // p2 actually represents the fraction
15132
    //
15133
    //      p2 * 2^e
15134
    //          = p2 / 2^-e
15135
    //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
15136
    //
15137
    // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15138
    //
15139
    //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15140
    //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15141
    //
15142
    // using
15143
    //
15144
    //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15145
    //                = (                   d) * 2^-e + (                   r)
15146
    //
15147
    // or
15148
    //      10^m * p2 * 2^e = d + r * 2^e
15149
    //
15150
    // i.e.
15151
    //
15152
    //      M+ = buffer + p2 * 2^e
15153
    //         = buffer + 10^-m * (d + r * 2^e)
15154
    //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15155
    //
15156
    // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15157
15158
0
    JSON_ASSERT(p2 > delta);
15159
15160
0
    int m = 0;
15161
0
    for (;;)
15162
0
    {
15163
        // Invariant:
15164
        //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15165
        //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
15166
        //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
15167
        //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15168
        //
15169
0
        JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15170
0
        p2 *= 10;
15171
0
        const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
15172
0
        const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15173
        //
15174
        //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15175
        //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15176
        //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15177
        //
15178
0
        JSON_ASSERT(d <= 9);
15179
0
        buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15180
        //
15181
        //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15182
        //
15183
0
        p2 = r;
15184
0
        m++;
15185
        //
15186
        //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15187
        // Invariant restored.
15188
15189
        // Check if enough digits have been generated.
15190
        //
15191
        //      10^-m * p2 * 2^e <= delta * 2^e
15192
        //              p2 * 2^e <= 10^m * delta * 2^e
15193
        //                    p2 <= 10^m * delta
15194
0
        delta *= 10;
15195
0
        dist  *= 10;
15196
0
        if (p2 <= delta)
15197
0
        {
15198
0
            break;
15199
0
        }
15200
0
    }
15201
15202
    // V = buffer * 10^-m, with M- <= V <= M+.
15203
15204
0
    decimal_exponent -= m;
15205
15206
    // 1 ulp in the decimal representation is now 10^-m.
15207
    // Since delta and dist are now scaled by 10^m, we need to do the
15208
    // same with ulp in order to keep the units in sync.
15209
    //
15210
    //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15211
    //
15212
0
    const std::uint64_t ten_m = one.f;
15213
0
    grisu2_round(buffer, length, dist, delta, p2, ten_m);
15214
15215
    // By construction this algorithm generates the shortest possible decimal
15216
    // number (Loitsch, Theorem 6.2) which rounds back to w.
15217
    // For an input number of precision p, at least
15218
    //
15219
    //      N = 1 + ceil(p * log_10(2))
15220
    //
15221
    // decimal digits are sufficient to identify all binary floating-point
15222
    // numbers (Matula, "In-and-Out conversions").
15223
    // This implies that the algorithm does not produce more than N decimal
15224
    // digits.
15225
    //
15226
    //      N = 17 for p = 53 (IEEE double precision)
15227
    //      N = 9  for p = 24 (IEEE single precision)
15228
0
}
15229
15230
/*!
15231
v = buf * 10^decimal_exponent
15232
len is the length of the buffer (number of decimal digits)
15233
The buffer must be large enough, i.e. >= max_digits10.
15234
*/
15235
JSON_HEDLEY_NON_NULL(1)
15236
inline void grisu2(char* buf, int& len, int& decimal_exponent,
15237
                   diyfp m_minus, diyfp v, diyfp m_plus)
15238
0
{
15239
0
    JSON_ASSERT(m_plus.e == m_minus.e);
15240
0
    JSON_ASSERT(m_plus.e == v.e);
15241
15242
    //  --------(-----------------------+-----------------------)--------    (A)
15243
    //          m-                      v                       m+
15244
    //
15245
    //  --------------------(-----------+-----------------------)--------    (B)
15246
    //                      m-          v                       m+
15247
    //
15248
    // First scale v (and m- and m+) such that the exponent is in the range
15249
    // [alpha, gamma].
15250
15251
0
    const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15252
15253
0
    const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15254
15255
    // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15256
0
    const diyfp w       = diyfp::mul(v,       c_minus_k);
15257
0
    const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15258
0
    const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
15259
15260
    //  ----(---+---)---------------(---+---)---------------(---+---)----
15261
    //          w-                      w                       w+
15262
    //          = c*m-                  = c*v                   = c*m+
15263
    //
15264
    // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15265
    // w+ are now off by a small amount.
15266
    // In fact:
15267
    //
15268
    //      w - v * 10^k < 1 ulp
15269
    //
15270
    // To account for this inaccuracy, add resp. subtract 1 ulp.
15271
    //
15272
    //  --------+---[---------------(---+---)---------------]---+--------
15273
    //          w-  M-                  w                   M+  w+
15274
    //
15275
    // Now any number in [M-, M+] (bounds included) will round to w when input,
15276
    // regardless of how the input rounding algorithm breaks ties.
15277
    //
15278
    // And digit_gen generates the shortest possible such number in [M-, M+].
15279
    // Note that this does not mean that Grisu2 always generates the shortest
15280
    // possible number in the interval (m-, m+).
15281
0
    const diyfp M_minus(w_minus.f + 1, w_minus.e);
15282
0
    const diyfp M_plus (w_plus.f  - 1, w_plus.e );
15283
15284
0
    decimal_exponent = -cached.k; // = -(-k) = k
15285
15286
0
    grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15287
0
}
15288
15289
/*!
15290
v = buf * 10^decimal_exponent
15291
len is the length of the buffer (number of decimal digits)
15292
The buffer must be large enough, i.e. >= max_digits10.
15293
*/
15294
template<typename FloatType>
15295
JSON_HEDLEY_NON_NULL(1)
15296
void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15297
0
{
15298
0
    static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15299
0
                  "internal error: not enough precision");
15300
15301
0
    JSON_ASSERT(std::isfinite(value));
15302
0
    JSON_ASSERT(value > 0);
15303
15304
    // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15305
    // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15306
    // decimal representations are not exactly "short".
15307
    //
15308
    // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15309
    // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15310
    // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15311
    // does.
15312
    // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15313
    // representation using the corresponding std::from_chars function recovers value exactly". That
15314
    // indicates that single precision floating-point numbers should be recovered using
15315
    // 'std::strtof'.
15316
    //
15317
    // NB: If the neighbors are computed for single-precision numbers, there is a single float
15318
    //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15319
    //     value is off by 1 ulp.
15320
#if 0
15321
    const boundaries w = compute_boundaries(static_cast<double>(value));
15322
#else
15323
0
    const boundaries w = compute_boundaries(value);
15324
0
#endif
15325
15326
0
    grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15327
0
}
15328
15329
/*!
15330
@brief appends a decimal representation of e to buf
15331
@return a pointer to the element following the exponent.
15332
@pre -1000 < e < 1000
15333
*/
15334
JSON_HEDLEY_NON_NULL(1)
15335
JSON_HEDLEY_RETURNS_NON_NULL
15336
inline char* append_exponent(char* buf, int e)
15337
0
{
15338
0
    JSON_ASSERT(e > -1000);
15339
0
    JSON_ASSERT(e <  1000);
15340
15341
0
    if (e < 0)
15342
0
    {
15343
0
        e = -e;
15344
0
        *buf++ = '-';
15345
0
    }
15346
0
    else
15347
0
    {
15348
0
        *buf++ = '+';
15349
0
    }
15350
15351
0
    auto k = static_cast<std::uint32_t>(e);
15352
0
    if (k < 10)
15353
0
    {
15354
        // Always print at least two digits in the exponent.
15355
        // This is for compatibility with printf("%g").
15356
0
        *buf++ = '0';
15357
0
        *buf++ = static_cast<char>('0' + k);
15358
0
    }
15359
0
    else if (k < 100)
15360
0
    {
15361
0
        *buf++ = static_cast<char>('0' + k / 10);
15362
0
        k %= 10;
15363
0
        *buf++ = static_cast<char>('0' + k);
15364
0
    }
15365
0
    else
15366
0
    {
15367
0
        *buf++ = static_cast<char>('0' + k / 100);
15368
0
        k %= 100;
15369
0
        *buf++ = static_cast<char>('0' + k / 10);
15370
0
        k %= 10;
15371
0
        *buf++ = static_cast<char>('0' + k);
15372
0
    }
15373
15374
0
    return buf;
15375
0
}
15376
15377
/*!
15378
@brief prettify v = buf * 10^decimal_exponent
15379
15380
If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
15381
notation. Otherwise it will be printed in exponential notation.
15382
15383
@pre min_exp < 0
15384
@pre max_exp > 0
15385
*/
15386
JSON_HEDLEY_NON_NULL(1)
15387
JSON_HEDLEY_RETURNS_NON_NULL
15388
inline char* format_buffer(char* buf, int len, int decimal_exponent,
15389
                           int min_exp, int max_exp)
15390
0
{
15391
0
    JSON_ASSERT(min_exp < 0);
15392
0
    JSON_ASSERT(max_exp > 0);
15393
15394
0
    const int k = len;
15395
0
    const int n = len + decimal_exponent;
15396
15397
    // v = buf * 10^(n-k)
15398
    // k is the length of the buffer (number of decimal digits)
15399
    // n is the position of the decimal point relative to the start of the buffer.
15400
15401
0
    if (k <= n && n <= max_exp)
15402
0
    {
15403
        // digits[000]
15404
        // len <= max_exp + 2
15405
15406
0
        std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15407
        // Make it look like a floating-point number (#362, #378)
15408
0
        buf[n + 0] = '.';
15409
0
        buf[n + 1] = '0';
15410
0
        return buf + (static_cast<size_t>(n) + 2);
15411
0
    }
15412
15413
0
    if (0 < n && n <= max_exp)
15414
0
    {
15415
        // dig.its
15416
        // len <= max_digits10 + 1
15417
15418
0
        JSON_ASSERT(k > n);
15419
15420
0
        std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15421
0
        buf[n] = '.';
15422
0
        return buf + (static_cast<size_t>(k) + 1U);
15423
0
    }
15424
15425
0
    if (min_exp < n && n <= 0)
15426
0
    {
15427
        // 0.[000]digits
15428
        // len <= 2 + (-min_exp - 1) + max_digits10
15429
15430
0
        std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15431
0
        buf[0] = '0';
15432
0
        buf[1] = '.';
15433
0
        std::memset(buf + 2, '0', static_cast<size_t>(-n));
15434
0
        return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15435
0
    }
15436
15437
0
    if (k == 1)
15438
0
    {
15439
        // dE+123
15440
        // len <= 1 + 5
15441
15442
0
        buf += 1;
15443
0
    }
15444
0
    else
15445
0
    {
15446
        // d.igitsE+123
15447
        // len <= max_digits10 + 1 + 5
15448
15449
0
        std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15450
0
        buf[1] = '.';
15451
0
        buf += 1 + static_cast<size_t>(k);
15452
0
    }
15453
15454
0
    *buf++ = 'e';
15455
0
    return append_exponent(buf, n - 1);
15456
0
}
15457
15458
} // namespace dtoa_impl
15459
15460
/*!
15461
@brief generates a decimal representation of the floating-point number value in [first, last).
15462
15463
The format of the resulting decimal representation is similar to printf's %g
15464
format. Returns an iterator pointing past-the-end of the decimal representation.
15465
15466
@note The input number must be finite, i.e. NaN's and Inf's are not supported.
15467
@note The buffer must be large enough.
15468
@note The result is NOT null-terminated.
15469
*/
15470
template<typename FloatType>
15471
JSON_HEDLEY_NON_NULL(1, 2)
15472
JSON_HEDLEY_RETURNS_NON_NULL
15473
char* to_chars(char* first, const char* last, FloatType value)
15474
0
{
15475
0
    static_cast<void>(last); // maybe unused - fix warning
15476
0
    JSON_ASSERT(std::isfinite(value));
15477
15478
    // Use signbit(value) instead of (value < 0) since signbit works for -0.
15479
0
    if (std::signbit(value))
15480
0
    {
15481
0
        value = -value;
15482
0
        *first++ = '-';
15483
0
    }
15484
15485
0
    if (value == 0) // +-0
15486
0
    {
15487
0
        *first++ = '0';
15488
        // Make it look like a floating-point number (#362, #378)
15489
0
        *first++ = '.';
15490
0
        *first++ = '0';
15491
0
        return first;
15492
0
    }
15493
15494
0
    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15495
15496
    // Compute v = buffer * 10^decimal_exponent.
15497
    // The decimal digits are stored in the buffer, which needs to be interpreted
15498
    // as an unsigned decimal integer.
15499
    // len is the length of the buffer, i.e. the number of decimal digits.
15500
0
    int len = 0;
15501
0
    int decimal_exponent = 0;
15502
0
    dtoa_impl::grisu2(first, len, decimal_exponent, value);
15503
15504
0
    JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15505
15506
    // Format the buffer like printf("%.*g", prec, value)
15507
0
    constexpr int kMinExp = -4;
15508
    // Use digits10 here to increase compatibility with version 2.
15509
0
    constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15510
15511
0
    JSON_ASSERT(last - first >= kMaxExp + 2);
15512
0
    JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15513
0
    JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15514
15515
0
    return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15516
0
}
15517
15518
} // namespace detail
15519
} // namespace nlohmann
15520
15521
// #include <nlohmann/detail/exceptions.hpp>
15522
15523
// #include <nlohmann/detail/macro_scope.hpp>
15524
15525
// #include <nlohmann/detail/meta/cpp_future.hpp>
15526
15527
// #include <nlohmann/detail/output/binary_writer.hpp>
15528
15529
// #include <nlohmann/detail/output/output_adapters.hpp>
15530
15531
// #include <nlohmann/detail/value_t.hpp>
15532
15533
15534
namespace nlohmann
15535
{
15536
namespace detail
15537
{
15538
///////////////////
15539
// serialization //
15540
///////////////////
15541
15542
/// how to treat decoding errors
15543
enum class error_handler_t
15544
{
15545
    strict,  ///< throw a type_error exception in case of invalid UTF-8
15546
    replace, ///< replace invalid UTF-8 sequences with U+FFFD
15547
    ignore   ///< ignore invalid UTF-8 sequences
15548
};
15549
15550
template<typename BasicJsonType>
15551
class serializer
15552
{
15553
    using string_t = typename BasicJsonType::string_t;
15554
    using number_float_t = typename BasicJsonType::number_float_t;
15555
    using number_integer_t = typename BasicJsonType::number_integer_t;
15556
    using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15557
    using binary_char_t = typename BasicJsonType::binary_t::value_type;
15558
    static constexpr std::uint8_t UTF8_ACCEPT = 0;
15559
    static constexpr std::uint8_t UTF8_REJECT = 1;
15560
15561
  public:
15562
    /*!
15563
    @param[in] s  output stream to serialize to
15564
    @param[in] ichar  indentation character to use
15565
    @param[in] error_handler_  how to react on decoding errors
15566
    */
15567
    serializer(output_adapter_t<char> s, const char ichar,
15568
               error_handler_t error_handler_ = error_handler_t::strict)
15569
        : o(std::move(s))
15570
        , loc(std::localeconv())
15571
        , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
15572
        , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
15573
        , indent_char(ichar)
15574
        , indent_string(512, indent_char)
15575
        , error_handler(error_handler_)
15576
0
    {}
15577
15578
    // delete because of pointer members
15579
    serializer(const serializer&) = delete;
15580
    serializer& operator=(const serializer&) = delete;
15581
    serializer(serializer&&) = delete;
15582
    serializer& operator=(serializer&&) = delete;
15583
0
    ~serializer() = default;
15584
15585
    /*!
15586
    @brief internal implementation of the serialization function
15587
15588
    This function is called by the public member function dump and organizes
15589
    the serialization internally. The indentation level is propagated as
15590
    additional parameter. In case of arrays and objects, the function is
15591
    called recursively.
15592
15593
    - strings and object keys are escaped using `escape_string()`
15594
    - integer numbers are converted implicitly via `operator<<`
15595
    - floating-point numbers are converted to a string using `"%g"` format
15596
    - binary values are serialized as objects containing the subtype and the
15597
      byte array
15598
15599
    @param[in] val               value to serialize
15600
    @param[in] pretty_print      whether the output shall be pretty-printed
15601
    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
15602
    in the output are escaped with `\uXXXX` sequences, and the result consists
15603
    of ASCII characters only.
15604
    @param[in] indent_step       the indent level
15605
    @param[in] current_indent    the current indent level (only used internally)
15606
    */
15607
    void dump(const BasicJsonType& val,
15608
              const bool pretty_print,
15609
              const bool ensure_ascii,
15610
              const unsigned int indent_step,
15611
              const unsigned int current_indent = 0)
15612
0
    {
15613
0
        switch (val.m_type)
15614
0
        {
15615
0
            case value_t::object:
15616
0
            {
15617
0
                if (val.m_value.object->empty())
15618
0
                {
15619
0
                    o->write_characters("{}", 2);
15620
0
                    return;
15621
0
                }
15622
15623
0
                if (pretty_print)
15624
0
                {
15625
0
                    o->write_characters("{\n", 2);
15626
15627
                    // variable to hold indentation for recursive calls
15628
0
                    const auto new_indent = current_indent + indent_step;
15629
0
                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15630
0
                    {
15631
0
                        indent_string.resize(indent_string.size() * 2, ' ');
15632
0
                    }
15633
15634
                    // first n-1 elements
15635
0
                    auto i = val.m_value.object->cbegin();
15636
0
                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15637
0
                    {
15638
0
                        o->write_characters(indent_string.c_str(), new_indent);
15639
0
                        o->write_character('\"');
15640
0
                        dump_escaped(i->first, ensure_ascii);
15641
0
                        o->write_characters("\": ", 3);
15642
0
                        dump(i->second, true, ensure_ascii, indent_step, new_indent);
15643
0
                        o->write_characters(",\n", 2);
15644
0
                    }
15645
15646
                    // last element
15647
0
                    JSON_ASSERT(i != val.m_value.object->cend());
15648
0
                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15649
0
                    o->write_characters(indent_string.c_str(), new_indent);
15650
0
                    o->write_character('\"');
15651
0
                    dump_escaped(i->first, ensure_ascii);
15652
0
                    o->write_characters("\": ", 3);
15653
0
                    dump(i->second, true, ensure_ascii, indent_step, new_indent);
15654
15655
0
                    o->write_character('\n');
15656
0
                    o->write_characters(indent_string.c_str(), current_indent);
15657
0
                    o->write_character('}');
15658
0
                }
15659
0
                else
15660
0
                {
15661
0
                    o->write_character('{');
15662
15663
                    // first n-1 elements
15664
0
                    auto i = val.m_value.object->cbegin();
15665
0
                    for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15666
0
                    {
15667
0
                        o->write_character('\"');
15668
0
                        dump_escaped(i->first, ensure_ascii);
15669
0
                        o->write_characters("\":", 2);
15670
0
                        dump(i->second, false, ensure_ascii, indent_step, current_indent);
15671
0
                        o->write_character(',');
15672
0
                    }
15673
15674
                    // last element
15675
0
                    JSON_ASSERT(i != val.m_value.object->cend());
15676
0
                    JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15677
0
                    o->write_character('\"');
15678
0
                    dump_escaped(i->first, ensure_ascii);
15679
0
                    o->write_characters("\":", 2);
15680
0
                    dump(i->second, false, ensure_ascii, indent_step, current_indent);
15681
15682
0
                    o->write_character('}');
15683
0
                }
15684
15685
0
                return;
15686
0
            }
15687
15688
0
            case value_t::array:
15689
0
            {
15690
0
                if (val.m_value.array->empty())
15691
0
                {
15692
0
                    o->write_characters("[]", 2);
15693
0
                    return;
15694
0
                }
15695
15696
0
                if (pretty_print)
15697
0
                {
15698
0
                    o->write_characters("[\n", 2);
15699
15700
                    // variable to hold indentation for recursive calls
15701
0
                    const auto new_indent = current_indent + indent_step;
15702
0
                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15703
0
                    {
15704
0
                        indent_string.resize(indent_string.size() * 2, ' ');
15705
0
                    }
15706
15707
                    // first n-1 elements
15708
0
                    for (auto i = val.m_value.array->cbegin();
15709
0
                            i != val.m_value.array->cend() - 1; ++i)
15710
0
                    {
15711
0
                        o->write_characters(indent_string.c_str(), new_indent);
15712
0
                        dump(*i, true, ensure_ascii, indent_step, new_indent);
15713
0
                        o->write_characters(",\n", 2);
15714
0
                    }
15715
15716
                    // last element
15717
0
                    JSON_ASSERT(!val.m_value.array->empty());
15718
0
                    o->write_characters(indent_string.c_str(), new_indent);
15719
0
                    dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15720
15721
0
                    o->write_character('\n');
15722
0
                    o->write_characters(indent_string.c_str(), current_indent);
15723
0
                    o->write_character(']');
15724
0
                }
15725
0
                else
15726
0
                {
15727
0
                    o->write_character('[');
15728
15729
                    // first n-1 elements
15730
0
                    for (auto i = val.m_value.array->cbegin();
15731
0
                            i != val.m_value.array->cend() - 1; ++i)
15732
0
                    {
15733
0
                        dump(*i, false, ensure_ascii, indent_step, current_indent);
15734
0
                        o->write_character(',');
15735
0
                    }
15736
15737
                    // last element
15738
0
                    JSON_ASSERT(!val.m_value.array->empty());
15739
0
                    dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15740
15741
0
                    o->write_character(']');
15742
0
                }
15743
15744
0
                return;
15745
0
            }
15746
15747
0
            case value_t::string:
15748
0
            {
15749
0
                o->write_character('\"');
15750
0
                dump_escaped(*val.m_value.string, ensure_ascii);
15751
0
                o->write_character('\"');
15752
0
                return;
15753
0
            }
15754
15755
0
            case value_t::binary:
15756
0
            {
15757
0
                if (pretty_print)
15758
0
                {
15759
0
                    o->write_characters("{\n", 2);
15760
15761
                    // variable to hold indentation for recursive calls
15762
0
                    const auto new_indent = current_indent + indent_step;
15763
0
                    if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15764
0
                    {
15765
0
                        indent_string.resize(indent_string.size() * 2, ' ');
15766
0
                    }
15767
15768
0
                    o->write_characters(indent_string.c_str(), new_indent);
15769
15770
0
                    o->write_characters("\"bytes\": [", 10);
15771
15772
0
                    if (!val.m_value.binary->empty())
15773
0
                    {
15774
0
                        for (auto i = val.m_value.binary->cbegin();
15775
0
                                i != val.m_value.binary->cend() - 1; ++i)
15776
0
                        {
15777
0
                            dump_integer(*i);
15778
0
                            o->write_characters(", ", 2);
15779
0
                        }
15780
0
                        dump_integer(val.m_value.binary->back());
15781
0
                    }
15782
15783
0
                    o->write_characters("],\n", 3);
15784
0
                    o->write_characters(indent_string.c_str(), new_indent);
15785
15786
0
                    o->write_characters("\"subtype\": ", 11);
15787
0
                    if (val.m_value.binary->has_subtype())
15788
0
                    {
15789
0
                        dump_integer(val.m_value.binary->subtype());
15790
0
                    }
15791
0
                    else
15792
0
                    {
15793
0
                        o->write_characters("null", 4);
15794
0
                    }
15795
0
                    o->write_character('\n');
15796
0
                    o->write_characters(indent_string.c_str(), current_indent);
15797
0
                    o->write_character('}');
15798
0
                }
15799
0
                else
15800
0
                {
15801
0
                    o->write_characters("{\"bytes\":[", 10);
15802
15803
0
                    if (!val.m_value.binary->empty())
15804
0
                    {
15805
0
                        for (auto i = val.m_value.binary->cbegin();
15806
0
                                i != val.m_value.binary->cend() - 1; ++i)
15807
0
                        {
15808
0
                            dump_integer(*i);
15809
0
                            o->write_character(',');
15810
0
                        }
15811
0
                        dump_integer(val.m_value.binary->back());
15812
0
                    }
15813
15814
0
                    o->write_characters("],\"subtype\":", 12);
15815
0
                    if (val.m_value.binary->has_subtype())
15816
0
                    {
15817
0
                        dump_integer(val.m_value.binary->subtype());
15818
0
                        o->write_character('}');
15819
0
                    }
15820
0
                    else
15821
0
                    {
15822
0
                        o->write_characters("null}", 5);
15823
0
                    }
15824
0
                }
15825
0
                return;
15826
0
            }
15827
15828
0
            case value_t::boolean:
15829
0
            {
15830
0
                if (val.m_value.boolean)
15831
0
                {
15832
0
                    o->write_characters("true", 4);
15833
0
                }
15834
0
                else
15835
0
                {
15836
0
                    o->write_characters("false", 5);
15837
0
                }
15838
0
                return;
15839
0
            }
15840
15841
0
            case value_t::number_integer:
15842
0
            {
15843
0
                dump_integer(val.m_value.number_integer);
15844
0
                return;
15845
0
            }
15846
15847
0
            case value_t::number_unsigned:
15848
0
            {
15849
0
                dump_integer(val.m_value.number_unsigned);
15850
0
                return;
15851
0
            }
15852
15853
0
            case value_t::number_float:
15854
0
            {
15855
0
                dump_float(val.m_value.number_float);
15856
0
                return;
15857
0
            }
15858
15859
0
            case value_t::discarded:
15860
0
            {
15861
0
                o->write_characters("<discarded>", 11);
15862
0
                return;
15863
0
            }
15864
15865
0
            case value_t::null:
15866
0
            {
15867
0
                o->write_characters("null", 4);
15868
0
                return;
15869
0
            }
15870
15871
0
            default:            // LCOV_EXCL_LINE
15872
0
                JSON_ASSERT(false);  // LCOV_EXCL_LINE
15873
0
        }
15874
0
    }
15875
15876
  JSON_PRIVATE_UNLESS_TESTED:
15877
    /*!
15878
    @brief dump escaped string
15879
15880
    Escape a string by replacing certain special characters by a sequence of an
15881
    escape character (backslash) and another character and other control
15882
    characters by a sequence of "\u" followed by a four-digit hex
15883
    representation. The escaped string is written to output stream @a o.
15884
15885
    @param[in] s  the string to escape
15886
    @param[in] ensure_ascii  whether to escape non-ASCII characters with
15887
                             \uXXXX sequences
15888
15889
    @complexity Linear in the length of string @a s.
15890
    */
15891
    void dump_escaped(const string_t& s, const bool ensure_ascii)
15892
0
    {
15893
0
        std::uint32_t codepoint;
15894
0
        std::uint8_t state = UTF8_ACCEPT;
15895
0
        std::size_t bytes = 0;  // number of bytes written to string_buffer
15896
15897
        // number of bytes written at the point of the last valid byte
15898
0
        std::size_t bytes_after_last_accept = 0;
15899
0
        std::size_t undumped_chars = 0;
15900
15901
0
        for (std::size_t i = 0; i < s.size(); ++i)
15902
0
        {
15903
0
            const auto byte = static_cast<uint8_t>(s[i]);
15904
15905
0
            switch (decode(state, codepoint, byte))
15906
0
            {
15907
0
                case UTF8_ACCEPT:  // decode found a new code point
15908
0
                {
15909
0
                    switch (codepoint)
15910
0
                    {
15911
0
                        case 0x08: // backspace
15912
0
                        {
15913
0
                            string_buffer[bytes++] = '\\';
15914
0
                            string_buffer[bytes++] = 'b';
15915
0
                            break;
15916
0
                        }
15917
15918
0
                        case 0x09: // horizontal tab
15919
0
                        {
15920
0
                            string_buffer[bytes++] = '\\';
15921
0
                            string_buffer[bytes++] = 't';
15922
0
                            break;
15923
0
                        }
15924
15925
0
                        case 0x0A: // newline
15926
0
                        {
15927
0
                            string_buffer[bytes++] = '\\';
15928
0
                            string_buffer[bytes++] = 'n';
15929
0
                            break;
15930
0
                        }
15931
15932
0
                        case 0x0C: // formfeed
15933
0
                        {
15934
0
                            string_buffer[bytes++] = '\\';
15935
0
                            string_buffer[bytes++] = 'f';
15936
0
                            break;
15937
0
                        }
15938
15939
0
                        case 0x0D: // carriage return
15940
0
                        {
15941
0
                            string_buffer[bytes++] = '\\';
15942
0
                            string_buffer[bytes++] = 'r';
15943
0
                            break;
15944
0
                        }
15945
15946
0
                        case 0x22: // quotation mark
15947
0
                        {
15948
0
                            string_buffer[bytes++] = '\\';
15949
0
                            string_buffer[bytes++] = '\"';
15950
0
                            break;
15951
0
                        }
15952
15953
0
                        case 0x5C: // reverse solidus
15954
0
                        {
15955
0
                            string_buffer[bytes++] = '\\';
15956
0
                            string_buffer[bytes++] = '\\';
15957
0
                            break;
15958
0
                        }
15959
15960
0
                        default:
15961
0
                        {
15962
                            // escape control characters (0x00..0x1F) or, if
15963
                            // ensure_ascii parameter is used, non-ASCII characters
15964
0
                            if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
15965
0
                            {
15966
0
                                if (codepoint <= 0xFFFF)
15967
0
                                {
15968
0
                                    (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15969
0
                                                    static_cast<std::uint16_t>(codepoint));
15970
0
                                    bytes += 6;
15971
0
                                }
15972
0
                                else
15973
0
                                {
15974
0
                                    (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15975
0
                                                    static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15976
0
                                                    static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15977
0
                                    bytes += 12;
15978
0
                                }
15979
0
                            }
15980
0
                            else
15981
0
                            {
15982
                                // copy byte to buffer (all previous bytes
15983
                                // been copied have in default case above)
15984
0
                                string_buffer[bytes++] = s[i];
15985
0
                            }
15986
0
                            break;
15987
0
                        }
15988
0
                    }
15989
15990
                    // write buffer and reset index; there must be 13 bytes
15991
                    // left, as this is the maximal number of bytes to be
15992
                    // written ("\uxxxx\uxxxx\0") for one code point
15993
0
                    if (string_buffer.size() - bytes < 13)
15994
0
                    {
15995
0
                        o->write_characters(string_buffer.data(), bytes);
15996
0
                        bytes = 0;
15997
0
                    }
15998
15999
                    // remember the byte position of this accept
16000
0
                    bytes_after_last_accept = bytes;
16001
0
                    undumped_chars = 0;
16002
0
                    break;
16003
0
                }
16004
16005
0
                case UTF8_REJECT:  // decode found invalid UTF-8 byte
16006
0
                {
16007
0
                    switch (error_handler)
16008
0
                    {
16009
0
                        case error_handler_t::strict:
16010
0
                        {
16011
0
                            std::string sn(3, '\0');
16012
0
                            (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16013
0
                            JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
16014
0
                        }
16015
16016
0
                        case error_handler_t::ignore:
16017
0
                        case error_handler_t::replace:
16018
0
                        {
16019
                            // in case we saw this character the first time, we
16020
                            // would like to read it again, because the byte
16021
                            // may be OK for itself, but just not OK for the
16022
                            // previous sequence
16023
0
                            if (undumped_chars > 0)
16024
0
                            {
16025
0
                                --i;
16026
0
                            }
16027
16028
                            // reset length buffer to the last accepted index;
16029
                            // thus removing/ignoring the invalid characters
16030
0
                            bytes = bytes_after_last_accept;
16031
16032
0
                            if (error_handler == error_handler_t::replace)
16033
0
                            {
16034
                                // add a replacement character
16035
0
                                if (ensure_ascii)
16036
0
                                {
16037
0
                                    string_buffer[bytes++] = '\\';
16038
0
                                    string_buffer[bytes++] = 'u';
16039
0
                                    string_buffer[bytes++] = 'f';
16040
0
                                    string_buffer[bytes++] = 'f';
16041
0
                                    string_buffer[bytes++] = 'f';
16042
0
                                    string_buffer[bytes++] = 'd';
16043
0
                                }
16044
0
                                else
16045
0
                                {
16046
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16047
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16048
0
                                    string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16049
0
                                }
16050
16051
                                // write buffer and reset index; there must be 13 bytes
16052
                                // left, as this is the maximal number of bytes to be
16053
                                // written ("\uxxxx\uxxxx\0") for one code point
16054
0
                                if (string_buffer.size() - bytes < 13)
16055
0
                                {
16056
0
                                    o->write_characters(string_buffer.data(), bytes);
16057
0
                                    bytes = 0;
16058
0
                                }
16059
16060
0
                                bytes_after_last_accept = bytes;
16061
0
                            }
16062
16063
0
                            undumped_chars = 0;
16064
16065
                            // continue processing the string
16066
0
                            state = UTF8_ACCEPT;
16067
0
                            break;
16068
0
                        }
16069
16070
0
                        default:            // LCOV_EXCL_LINE
16071
0
                            JSON_ASSERT(false);  // LCOV_EXCL_LINE
16072
0
                    }
16073
0
                    break;
16074
0
                }
16075
16076
0
                default:  // decode found yet incomplete multi-byte code point
16077
0
                {
16078
0
                    if (!ensure_ascii)
16079
0
                    {
16080
                        // code point will not be escaped - copy byte to buffer
16081
0
                        string_buffer[bytes++] = s[i];
16082
0
                    }
16083
0
                    ++undumped_chars;
16084
0
                    break;
16085
0
                }
16086
0
            }
16087
0
        }
16088
16089
        // we finished processing the string
16090
0
        if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16091
0
        {
16092
            // write buffer
16093
0
            if (bytes > 0)
16094
0
            {
16095
0
                o->write_characters(string_buffer.data(), bytes);
16096
0
            }
16097
0
        }
16098
0
        else
16099
0
        {
16100
            // we finish reading, but do not accept: string was incomplete
16101
0
            switch (error_handler)
16102
0
            {
16103
0
                case error_handler_t::strict:
16104
0
                {
16105
0
                    std::string sn(3, '\0');
16106
0
                    (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16107
0
                    JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
16108
0
                }
16109
16110
0
                case error_handler_t::ignore:
16111
0
                {
16112
                    // write all accepted bytes
16113
0
                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
16114
0
                    break;
16115
0
                }
16116
16117
0
                case error_handler_t::replace:
16118
0
                {
16119
                    // write all accepted bytes
16120
0
                    o->write_characters(string_buffer.data(), bytes_after_last_accept);
16121
                    // add a replacement character
16122
0
                    if (ensure_ascii)
16123
0
                    {
16124
0
                        o->write_characters("\\ufffd", 6);
16125
0
                    }
16126
0
                    else
16127
0
                    {
16128
0
                        o->write_characters("\xEF\xBF\xBD", 3);
16129
0
                    }
16130
0
                    break;
16131
0
                }
16132
16133
0
                default:            // LCOV_EXCL_LINE
16134
0
                    JSON_ASSERT(false);  // LCOV_EXCL_LINE
16135
0
            }
16136
0
        }
16137
0
    }
16138
16139
  private:
16140
    /*!
16141
    @brief count digits
16142
16143
    Count the number of decimal (base 10) digits for an input unsigned integer.
16144
16145
    @param[in] x  unsigned integer number to count its digits
16146
    @return    number of decimal digits
16147
    */
16148
    inline unsigned int count_digits(number_unsigned_t x) noexcept
16149
0
    {
16150
0
        unsigned int n_digits = 1;
16151
0
        for (;;)
16152
0
        {
16153
0
            if (x < 10)
16154
0
            {
16155
0
                return n_digits;
16156
0
            }
16157
0
            if (x < 100)
16158
0
            {
16159
0
                return n_digits + 1;
16160
0
            }
16161
0
            if (x < 1000)
16162
0
            {
16163
0
                return n_digits + 2;
16164
0
            }
16165
0
            if (x < 10000)
16166
0
            {
16167
0
                return n_digits + 3;
16168
0
            }
16169
0
            x = x / 10000u;
16170
0
            n_digits += 4;
16171
0
        }
16172
0
    }
16173
16174
    /*!
16175
    @brief dump an integer
16176
16177
    Dump a given integer to output stream @a o. Works internally with
16178
    @a number_buffer.
16179
16180
    @param[in] x  integer number (signed or unsigned) to dump
16181
    @tparam NumberType either @a number_integer_t or @a number_unsigned_t
16182
    */
16183
    template < typename NumberType, detail::enable_if_t <
16184
                   std::is_same<NumberType, number_unsigned_t>::value ||
16185
                   std::is_same<NumberType, number_integer_t>::value ||
16186
                   std::is_same<NumberType, binary_char_t>::value,
16187
                   int > = 0 >
16188
    void dump_integer(NumberType x)
16189
0
    {
16190
0
        static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16191
0
        {
16192
0
            {
16193
0
                {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16194
0
                {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16195
0
                {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16196
0
                {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16197
0
                {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16198
0
                {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16199
0
                {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16200
0
                {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16201
0
                {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16202
0
                {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16203
0
            }
16204
0
        };
16205
16206
        // special case for "0"
16207
0
        if (x == 0)
16208
0
        {
16209
0
            o->write_character('0');
16210
0
            return;
16211
0
        }
16212
16213
        // use a pointer to fill the buffer
16214
0
        auto buffer_ptr = number_buffer.begin();
16215
16216
0
        const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16217
0
        number_unsigned_t abs_value;
16218
16219
0
        unsigned int n_chars;
16220
16221
0
        if (is_negative)
16222
0
        {
16223
0
            *buffer_ptr = '-';
16224
0
            abs_value = remove_sign(static_cast<number_integer_t>(x));
16225
16226
            // account one more byte for the minus sign
16227
0
            n_chars = 1 + count_digits(abs_value);
16228
0
        }
16229
0
        else
16230
0
        {
16231
0
            abs_value = static_cast<number_unsigned_t>(x);
16232
0
            n_chars = count_digits(abs_value);
16233
0
        }
16234
16235
        // spare 1 byte for '\0'
16236
0
        JSON_ASSERT(n_chars < number_buffer.size() - 1);
16237
16238
        // jump to the end to generate the string from backward
16239
        // so we later avoid reversing the result
16240
0
        buffer_ptr += n_chars;
16241
16242
        // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16243
        // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16244
0
        while (abs_value >= 100)
16245
0
        {
16246
0
            const auto digits_index = static_cast<unsigned>((abs_value % 100));
16247
0
            abs_value /= 100;
16248
0
            *(--buffer_ptr) = digits_to_99[digits_index][1];
16249
0
            *(--buffer_ptr) = digits_to_99[digits_index][0];
16250
0
        }
16251
16252
0
        if (abs_value >= 10)
16253
0
        {
16254
0
            const auto digits_index = static_cast<unsigned>(abs_value);
16255
0
            *(--buffer_ptr) = digits_to_99[digits_index][1];
16256
0
            *(--buffer_ptr) = digits_to_99[digits_index][0];
16257
0
        }
16258
0
        else
16259
0
        {
16260
0
            *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16261
0
        }
16262
16263
0
        o->write_characters(number_buffer.data(), n_chars);
16264
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<long, 0>(long)
Unexecuted instantiation: void nlohmann::detail::serializer<nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >::dump_integer<unsigned long, 0>(unsigned long)
16265
16266
    /*!
16267
    @brief dump a floating-point number
16268
16269
    Dump a given floating-point number to output stream @a o. Works internally
16270
    with @a number_buffer.
16271
16272
    @param[in] x  floating-point number to dump
16273
    */
16274
    void dump_float(number_float_t x)
16275
0
    {
16276
        // NaN / inf
16277
0
        if (!std::isfinite(x))
16278
0
        {
16279
0
            o->write_characters("null", 4);
16280
0
            return;
16281
0
        }
16282
16283
        // If number_float_t is an IEEE-754 single or double precision number,
16284
        // use the Grisu2 algorithm to produce short numbers which are
16285
        // guaranteed to round-trip, using strtof and strtod, resp.
16286
        //
16287
        // NB: The test below works if <long double> == <double>.
16288
0
        static constexpr bool is_ieee_single_or_double
16289
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) ||
16290
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);
16291
16292
0
        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16293
0
    }
16294
16295
    void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16296
0
    {
16297
0
        char* begin = number_buffer.data();
16298
0
        char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16299
16300
0
        o->write_characters(begin, static_cast<size_t>(end - begin));
16301
0
    }
16302
16303
    void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16304
    {
16305
        // get number of digits for a float -> text -> float round-trip
16306
        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16307
16308
        // the actual conversion
16309
        std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16310
16311
        // negative value indicates an error
16312
        JSON_ASSERT(len > 0);
16313
        // check if buffer was large enough
16314
        JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16315
16316
        // erase thousands separator
16317
        if (thousands_sep != '\0')
16318
        {
16319
            const auto end = std::remove(number_buffer.begin(),
16320
                                         number_buffer.begin() + len, thousands_sep);
16321
            std::fill(end, number_buffer.end(), '\0');
16322
            JSON_ASSERT((end - number_buffer.begin()) <= len);
16323
            len = (end - number_buffer.begin());
16324
        }
16325
16326
        // convert decimal point to '.'
16327
        if (decimal_point != '\0' && decimal_point != '.')
16328
        {
16329
            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16330
            if (dec_pos != number_buffer.end())
16331
            {
16332
                *dec_pos = '.';
16333
            }
16334
        }
16335
16336
        o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16337
16338
        // determine if need to append ".0"
16339
        const bool value_is_int_like =
16340
            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16341
                         [](char c)
16342
        {
16343
            return c == '.' || c == 'e';
16344
        });
16345
16346
        if (value_is_int_like)
16347
        {
16348
            o->write_characters(".0", 2);
16349
        }
16350
    }
16351
16352
    /*!
16353
    @brief check whether a string is UTF-8 encoded
16354
16355
    The function checks each byte of a string whether it is UTF-8 encoded. The
16356
    result of the check is stored in the @a state parameter. The function must
16357
    be called initially with state 0 (accept). State 1 means the string must
16358
    be rejected, because the current byte is not allowed. If the string is
16359
    completely processed, but the state is non-zero, the string ended
16360
    prematurely; that is, the last byte indicated more bytes should have
16361
    followed.
16362
16363
    @param[in,out] state  the state of the decoding
16364
    @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
16365
    @param[in] byte       next byte to decode
16366
    @return               new state
16367
16368
    @note The function has been edited: a std::array is used.
16369
16370
    @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
16371
    @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
16372
    */
16373
    static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16374
0
    {
16375
0
        static const std::array<std::uint8_t, 400> utf8d =
16376
0
        {
16377
0
            {
16378
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
16379
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
16380
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
16381
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
16382
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
16383
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
16384
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
16385
0
                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16386
0
                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16387
0
                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16388
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
16389
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
16390
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
16391
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
16392
0
            }
16393
0
        };
16394
16395
0
        const std::uint8_t type = utf8d[byte];
16396
16397
0
        codep = (state != UTF8_ACCEPT)
16398
0
                ? (byte & 0x3fu) | (codep << 6u)
16399
0
                : (0xFFu >> type) & (byte);
16400
16401
0
        std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16402
0
        JSON_ASSERT(index < 400);
16403
0
        state = utf8d[index];
16404
0
        return state;
16405
0
    }
16406
16407
    /*
16408
     * Overload to make the compiler happy while it is instantiating
16409
     * dump_integer for number_unsigned_t.
16410
     * Must never be called.
16411
     */
16412
    number_unsigned_t remove_sign(number_unsigned_t x)
16413
    {
16414
        JSON_ASSERT(false); // LCOV_EXCL_LINE
16415
        return x; // LCOV_EXCL_LINE
16416
    }
16417
16418
    /*
16419
     * Helper function for dump_integer
16420
     *
16421
     * This function takes a negative signed integer and returns its absolute
16422
     * value as unsigned integer. The plus/minus shuffling is necessary as we can
16423
     * not directly remove the sign of an arbitrary signed integer as the
16424
     * absolute values of INT_MIN and INT_MAX are usually not the same. See
16425
     * #1708 for details.
16426
     */
16427
    inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16428
0
    {
16429
0
        JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)());
16430
0
        return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16431
0
    }
16432
16433
  private:
16434
    /// the output of the serializer
16435
    output_adapter_t<char> o = nullptr;
16436
16437
    /// a (hopefully) large enough character buffer
16438
    std::array<char, 64> number_buffer{{}};
16439
16440
    /// the locale
16441
    const std::lconv* loc = nullptr;
16442
    /// the locale's thousand separator character
16443
    const char thousands_sep = '\0';
16444
    /// the locale's decimal point character
16445
    const char decimal_point = '\0';
16446
16447
    /// string buffer
16448
    std::array<char, 512> string_buffer{{}};
16449
16450
    /// the indentation character
16451
    const char indent_char;
16452
    /// the indentation string
16453
    string_t indent_string;
16454
16455
    /// error_handler how to react on decoding errors
16456
    const error_handler_t error_handler;
16457
};
16458
}  // namespace detail
16459
}  // namespace nlohmann
16460
16461
// #include <nlohmann/detail/value_t.hpp>
16462
16463
// #include <nlohmann/json_fwd.hpp>
16464
16465
// #include <nlohmann/ordered_map.hpp>
16466
16467
16468
#include <functional> // less
16469
#include <memory> // allocator
16470
#include <utility> // pair
16471
#include <vector> // vector
16472
16473
// #include <nlohmann/detail/macro_scope.hpp>
16474
16475
16476
namespace nlohmann
16477
{
16478
16479
/// ordered_map: a minimal map-like container that preserves insertion order
16480
/// for use within nlohmann::basic_json<ordered_map>
16481
template <class Key, class T, class IgnoredLess = std::less<Key>,
16482
          class Allocator = std::allocator<std::pair<const Key, T>>>
16483
                  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16484
{
16485
    using key_type = Key;
16486
    using mapped_type = T;
16487
    using Container = std::vector<std::pair<const Key, T>, Allocator>;
16488
    using typename Container::iterator;
16489
    using typename Container::const_iterator;
16490
    using typename Container::size_type;
16491
    using typename Container::value_type;
16492
16493
    // Explicit constructors instead of `using Container::Container`
16494
    // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
16495
    ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16496
    template <class It>
16497
    ordered_map(It first, It last, const Allocator& alloc = Allocator())
16498
        : Container{first, last, alloc} {}
16499
    ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16500
        : Container{init, alloc} {}
16501
16502
    std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16503
    {
16504
        for (auto it = this->begin(); it != this->end(); ++it)
16505
        {
16506
            if (it->first == key)
16507
            {
16508
                return {it, false};
16509
            }
16510
        }
16511
        Container::emplace_back(key, t);
16512
        return {--this->end(), true};
16513
    }
16514
16515
    T& operator[](const Key& key)
16516
    {
16517
        return emplace(key, T{}).first->second;
16518
    }
16519
16520
    const T& operator[](const Key& key) const
16521
    {
16522
        return at(key);
16523
    }
16524
16525
    T& at(const Key& key)
16526
    {
16527
        for (auto it = this->begin(); it != this->end(); ++it)
16528
        {
16529
            if (it->first == key)
16530
            {
16531
                return it->second;
16532
            }
16533
        }
16534
16535
        JSON_THROW(std::out_of_range("key not found"));
16536
    }
16537
16538
    const T& at(const Key& key) const
16539
    {
16540
        for (auto it = this->begin(); it != this->end(); ++it)
16541
        {
16542
            if (it->first == key)
16543
            {
16544
                return it->second;
16545
            }
16546
        }
16547
16548
        JSON_THROW(std::out_of_range("key not found"));
16549
    }
16550
16551
    size_type erase(const Key& key)
16552
    {
16553
        for (auto it = this->begin(); it != this->end(); ++it)
16554
        {
16555
            if (it->first == key)
16556
            {
16557
                // Since we cannot move const Keys, re-construct them in place
16558
                for (auto next = it; ++next != this->end(); ++it)
16559
                {
16560
                    it->~value_type(); // Destroy but keep allocation
16561
                    new (&*it) value_type{std::move(*next)};
16562
                }
16563
                Container::pop_back();
16564
                return 1;
16565
            }
16566
        }
16567
        return 0;
16568
    }
16569
16570
    iterator erase(iterator pos)
16571
    {
16572
        auto it = pos;
16573
16574
        // Since we cannot move const Keys, re-construct them in place
16575
        for (auto next = it; ++next != this->end(); ++it)
16576
        {
16577
            it->~value_type(); // Destroy but keep allocation
16578
            new (&*it) value_type{std::move(*next)};
16579
        }
16580
        Container::pop_back();
16581
        return pos;
16582
    }
16583
16584
    size_type count(const Key& key) const
16585
    {
16586
        for (auto it = this->begin(); it != this->end(); ++it)
16587
        {
16588
            if (it->first == key)
16589
            {
16590
                return 1;
16591
            }
16592
        }
16593
        return 0;
16594
    }
16595
16596
    iterator find(const Key& key)
16597
    {
16598
        for (auto it = this->begin(); it != this->end(); ++it)
16599
        {
16600
            if (it->first == key)
16601
            {
16602
                return it;
16603
            }
16604
        }
16605
        return Container::end();
16606
    }
16607
16608
    const_iterator find(const Key& key) const
16609
    {
16610
        for (auto it = this->begin(); it != this->end(); ++it)
16611
        {
16612
            if (it->first == key)
16613
            {
16614
                return it;
16615
            }
16616
        }
16617
        return Container::end();
16618
    }
16619
16620
    std::pair<iterator, bool> insert( value_type&& value )
16621
    {
16622
        return emplace(value.first, std::move(value.second));
16623
    }
16624
16625
    std::pair<iterator, bool> insert( const value_type& value )
16626
    {
16627
        for (auto it = this->begin(); it != this->end(); ++it)
16628
        {
16629
            if (it->first == value.first)
16630
            {
16631
                return {it, false};
16632
            }
16633
        }
16634
        Container::push_back(value);
16635
        return {--this->end(), true};
16636
    }
16637
};
16638
16639
}  // namespace nlohmann
16640
16641
16642
/*!
16643
@brief namespace for Niels Lohmann
16644
@see https://github.com/nlohmann
16645
@since version 1.0.0
16646
*/
16647
namespace nlohmann
16648
{
16649
16650
/*!
16651
@brief a class to store JSON values
16652
16653
@tparam ObjectType type for JSON objects (`std::map` by default; will be used
16654
in @ref object_t)
16655
@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
16656
in @ref array_t)
16657
@tparam StringType type for JSON strings and object keys (`std::string` by
16658
default; will be used in @ref string_t)
16659
@tparam BooleanType type for JSON booleans (`bool` by default; will be used
16660
in @ref boolean_t)
16661
@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
16662
default; will be used in @ref number_integer_t)
16663
@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
16664
`uint64_t` by default; will be used in @ref number_unsigned_t)
16665
@tparam NumberFloatType type for JSON floating-point numbers (`double` by
16666
default; will be used in @ref number_float_t)
16667
@tparam BinaryType type for packed binary data for compatibility with binary
16668
serialization formats (`std::vector<std::uint8_t>` by default; will be used in
16669
@ref binary_t)
16670
@tparam AllocatorType type of the allocator to use (`std::allocator` by
16671
default)
16672
@tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
16673
and `from_json()` (@ref adl_serializer by default)
16674
16675
@requirement The class satisfies the following concept requirements:
16676
- Basic
16677
 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
16678
   JSON values can be default constructed. The result will be a JSON null
16679
   value.
16680
 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
16681
   A JSON value can be constructed from an rvalue argument.
16682
 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
16683
   A JSON value can be copy-constructed from an lvalue expression.
16684
 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
16685
   A JSON value van be assigned from an rvalue argument.
16686
 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
16687
   A JSON value can be copy-assigned from an lvalue expression.
16688
 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
16689
   JSON values can be destructed.
16690
- Layout
16691
 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
16692
   JSON values have
16693
   [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
16694
   All non-static data members are private and standard layout types, the
16695
   class has no virtual functions or (virtual) base classes.
16696
- Library-wide
16697
 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
16698
   JSON values can be compared with `==`, see @ref
16699
   operator==(const_reference,const_reference).
16700
 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
16701
   JSON values can be compared with `<`, see @ref
16702
   operator<(const_reference,const_reference).
16703
 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
16704
   Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
16705
   other compatible types, using unqualified function call @ref swap().
16706
 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
16707
   JSON values can be compared against `std::nullptr_t` objects which are used
16708
   to model the `null` value.
16709
- Container
16710
 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
16711
   JSON values can be used like STL containers and provide iterator access.
16712
 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
16713
   JSON values can be used like STL containers and provide reverse iterator
16714
   access.
16715
16716
@invariant The member variables @a m_value and @a m_type have the following
16717
relationship:
16718
- If `m_type == value_t::object`, then `m_value.object != nullptr`.
16719
- If `m_type == value_t::array`, then `m_value.array != nullptr`.
16720
- If `m_type == value_t::string`, then `m_value.string != nullptr`.
16721
The invariants are checked by member function assert_invariant().
16722
16723
@internal
16724
@note ObjectType trick from https://stackoverflow.com/a/9860911
16725
@endinternal
16726
16727
@see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
16728
Format](http://rfc7159.net/rfc7159)
16729
16730
@since version 1.0.0
16731
16732
@nosubgrouping
16733
*/
16734
NLOHMANN_BASIC_JSON_TPL_DECLARATION
16735
class basic_json
16736
{
16737
  private:
16738
    template<detail::value_t> friend struct detail::external_constructor;
16739
    friend ::nlohmann::json_pointer<basic_json>;
16740
16741
    template<typename BasicJsonType, typename InputType>
16742
    friend class ::nlohmann::detail::parser;
16743
    friend ::nlohmann::detail::serializer<basic_json>;
16744
    template<typename BasicJsonType>
16745
    friend class ::nlohmann::detail::iter_impl;
16746
    template<typename BasicJsonType, typename CharType>
16747
    friend class ::nlohmann::detail::binary_writer;
16748
    template<typename BasicJsonType, typename InputType, typename SAX>
16749
    friend class ::nlohmann::detail::binary_reader;
16750
    template<typename BasicJsonType>
16751
    friend class ::nlohmann::detail::json_sax_dom_parser;
16752
    template<typename BasicJsonType>
16753
    friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16754
16755
    /// workaround type for MSVC
16756
    using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
16757
16758
  JSON_PRIVATE_UNLESS_TESTED:
16759
    // convenience aliases for types residing in namespace detail;
16760
    using lexer = ::nlohmann::detail::lexer_base<basic_json>;
16761
16762
    template<typename InputAdapterType>
16763
    static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16764
        InputAdapterType adapter,
16765
        detail::parser_callback_t<basic_json>cb = nullptr,
16766
        const bool allow_exceptions = true,
16767
        const bool ignore_comments = false
16768
                                 )
16769
0
    {
16770
0
        return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16771
0
                std::move(cb), allow_exceptions, ignore_comments);
16772
0
    }
Unexecuted instantiation: 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*> > nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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> > >::parser<nlohmann::detail::iterator_input_adapter<char const*> >(nlohmann::detail::iterator_input_adapter<char const*>, std::__1::function<bool (int, nlohmann::detail::parse_event_t, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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, bool)
Unexecuted instantiation: 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::input_stream_adapter> nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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> > >::parser<nlohmann::detail::input_stream_adapter>(nlohmann::detail::input_stream_adapter, std::__1::function<bool (int, nlohmann::detail::parse_event_t, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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, bool)
16773
16774
  private:
16775
    using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
16776
    template<typename BasicJsonType>
16777
    using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16778
    template<typename BasicJsonType>
16779
    using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16780
    template<typename Iterator>
16781
    using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16782
    template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16783
16784
    template<typename CharType>
16785
    using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16786
16787
    template<typename InputType>
16788
    using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16789
    template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16790
16791
  JSON_PRIVATE_UNLESS_TESTED:
16792
    using serializer = ::nlohmann::detail::serializer<basic_json>;
16793
16794
  public:
16795
    using value_t = detail::value_t;
16796
    /// JSON Pointer, see @ref nlohmann::json_pointer
16797
    using json_pointer = ::nlohmann::json_pointer<basic_json>;
16798
    template<typename T, typename SFINAE>
16799
    using json_serializer = JSONSerializer<T, SFINAE>;
16800
    /// how to treat decoding errors
16801
    using error_handler_t = detail::error_handler_t;
16802
    /// how to treat CBOR tags
16803
    using cbor_tag_handler_t = detail::cbor_tag_handler_t;
16804
    /// helper type for initializer lists of basic_json values
16805
    using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16806
16807
    using input_format_t = detail::input_format_t;
16808
    /// SAX interface type, see @ref nlohmann::json_sax
16809
    using json_sax_t = json_sax<basic_json>;
16810
16811
    ////////////////
16812
    // exceptions //
16813
    ////////////////
16814
16815
    /// @name exceptions
16816
    /// Classes to implement user-defined exceptions.
16817
    /// @{
16818
16819
    /// @copydoc detail::exception
16820
    using exception = detail::exception;
16821
    /// @copydoc detail::parse_error
16822
    using parse_error = detail::parse_error;
16823
    /// @copydoc detail::invalid_iterator
16824
    using invalid_iterator = detail::invalid_iterator;
16825
    /// @copydoc detail::type_error
16826
    using type_error = detail::type_error;
16827
    /// @copydoc detail::out_of_range
16828
    using out_of_range = detail::out_of_range;
16829
    /// @copydoc detail::other_error
16830
    using other_error = detail::other_error;
16831
16832
    /// @}
16833
16834
16835
    /////////////////////
16836
    // container types //
16837
    /////////////////////
16838
16839
    /// @name container types
16840
    /// The canonic container types to use @ref basic_json like any other STL
16841
    /// container.
16842
    /// @{
16843
16844
    /// the type of elements in a basic_json container
16845
    using value_type = basic_json;
16846
16847
    /// the type of an element reference
16848
    using reference = value_type&;
16849
    /// the type of an element const reference
16850
    using const_reference = const value_type&;
16851
16852
    /// a type to represent differences between iterators
16853
    using difference_type = std::ptrdiff_t;
16854
    /// a type to represent container sizes
16855
    using size_type = std::size_t;
16856
16857
    /// the allocator type
16858
    using allocator_type = AllocatorType<basic_json>;
16859
16860
    /// the type of an element pointer
16861
    using pointer = typename std::allocator_traits<allocator_type>::pointer;
16862
    /// the type of an element const pointer
16863
    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16864
16865
    /// an iterator for a basic_json container
16866
    using iterator = iter_impl<basic_json>;
16867
    /// a const iterator for a basic_json container
16868
    using const_iterator = iter_impl<const basic_json>;
16869
    /// a reverse iterator for a basic_json container
16870
    using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16871
    /// a const reverse iterator for a basic_json container
16872
    using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16873
16874
    /// @}
16875
16876
16877
    /*!
16878
    @brief returns the allocator associated with the container
16879
    */
16880
    static allocator_type get_allocator()
16881
    {
16882
        return allocator_type();
16883
    }
16884
16885
    /*!
16886
    @brief returns version information on the library
16887
16888
    This function returns a JSON object with information about the library,
16889
    including the version number and information on the platform and compiler.
16890
16891
    @return JSON object holding version information
16892
    key         | description
16893
    ----------- | ---------------
16894
    `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).
16895
    `copyright` | The copyright line for the library as string.
16896
    `name`      | The name of the library as string.
16897
    `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
16898
    `url`       | The URL of the project as string.
16899
    `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).
16900
16901
    @liveexample{The following code shows an example output of the `meta()`
16902
    function.,meta}
16903
16904
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16905
    changes to any JSON value.
16906
16907
    @complexity Constant.
16908
16909
    @since 2.1.0
16910
    */
16911
    JSON_HEDLEY_WARN_UNUSED_RESULT
16912
    static basic_json meta()
16913
    {
16914
        basic_json result;
16915
16916
        result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16917
        result["name"] = "JSON for Modern C++";
16918
        result["url"] = "https://github.com/nlohmann/json";
16919
        result["version"]["string"] =
16920
            std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16921
            std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16922
            std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16923
        result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16924
        result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16925
        result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16926
16927
#ifdef _WIN32
16928
        result["platform"] = "win32";
16929
#elif defined __linux__
16930
        result["platform"] = "linux";
16931
#elif defined __APPLE__
16932
        result["platform"] = "apple";
16933
#elif defined __unix__
16934
        result["platform"] = "unix";
16935
#else
16936
        result["platform"] = "unknown";
16937
#endif
16938
16939
#if defined(__ICC) || defined(__INTEL_COMPILER)
16940
        result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16941
#elif defined(__clang__)
16942
        result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16943
#elif defined(__GNUC__) || defined(__GNUG__)
16944
        result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16945
#elif defined(__HP_cc) || defined(__HP_aCC)
16946
        result["compiler"] = "hp"
16947
#elif defined(__IBMCPP__)
16948
        result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16949
#elif defined(_MSC_VER)
16950
        result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16951
#elif defined(__PGI)
16952
        result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16953
#elif defined(__SUNPRO_CC)
16954
        result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16955
#else
16956
        result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16957
#endif
16958
16959
#ifdef __cplusplus
16960
        result["compiler"]["c++"] = std::to_string(__cplusplus);
16961
#else
16962
        result["compiler"]["c++"] = "unknown";
16963
#endif
16964
        return result;
16965
    }
16966
16967
16968
    ///////////////////////////
16969
    // JSON value data types //
16970
    ///////////////////////////
16971
16972
    /// @name JSON value data types
16973
    /// The data types to store a JSON value. These types are derived from
16974
    /// the template arguments passed to class @ref basic_json.
16975
    /// @{
16976
16977
#if defined(JSON_HAS_CPP_14)
16978
    // Use transparent comparator if possible, combined with perfect forwarding
16979
    // on find() and count() calls prevents unnecessary string construction.
16980
    using object_comparator_t = std::less<>;
16981
#else
16982
    using object_comparator_t = std::less<StringType>;
16983
#endif
16984
16985
    /*!
16986
    @brief a type for an object
16987
16988
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
16989
    > An object is an unordered collection of zero or more name/value pairs,
16990
    > where a name is a string and a value is a string, number, boolean, null,
16991
    > object, or array.
16992
16993
    To store objects in C++, a type is defined by the template parameters
16994
    described below.
16995
16996
    @tparam ObjectType  the container to store objects (e.g., `std::map` or
16997
    `std::unordered_map`)
16998
    @tparam StringType the type of the keys or names (e.g., `std::string`).
16999
    The comparison function `std::less<StringType>` is used to order elements
17000
    inside the container.
17001
    @tparam AllocatorType the allocator to use for objects (e.g.,
17002
    `std::allocator`)
17003
17004
    #### Default type
17005
17006
    With the default values for @a ObjectType (`std::map`), @a StringType
17007
    (`std::string`), and @a AllocatorType (`std::allocator`), the default
17008
    value for @a object_t is:
17009
17010
    @code {.cpp}
17011
    std::map<
17012
      std::string, // key_type
17013
      basic_json, // value_type
17014
      std::less<std::string>, // key_compare
17015
      std::allocator<std::pair<const std::string, basic_json>> // allocator_type
17016
    >
17017
    @endcode
17018
17019
    #### Behavior
17020
17021
    The choice of @a object_t influences the behavior of the JSON class. With
17022
    the default type, objects have the following behavior:
17023
17024
    - When all names are unique, objects will be interoperable in the sense
17025
      that all software implementations receiving that object will agree on
17026
      the name-value mappings.
17027
    - When the names within an object are not unique, it is unspecified which
17028
      one of the values for a given key will be chosen. For instance,
17029
      `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
17030
      `{"key": 2}`.
17031
    - Internally, name/value pairs are stored in lexicographical order of the
17032
      names. Objects will also be serialized (see @ref dump) in this order.
17033
      For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
17034
      and serialized as `{"a": 2, "b": 1}`.
17035
    - When comparing objects, the order of the name/value pairs is irrelevant.
17036
      This makes objects interoperable in the sense that they will not be
17037
      affected by these differences. For instance, `{"b": 1, "a": 2}` and
17038
      `{"a": 2, "b": 1}` will be treated as equal.
17039
17040
    #### Limits
17041
17042
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17043
    > An implementation may set limits on the maximum depth of nesting.
17044
17045
    In this class, the object's limit of nesting is not explicitly constrained.
17046
    However, a maximum depth of nesting may be introduced by the compiler or
17047
    runtime environment. A theoretical limit can be queried by calling the
17048
    @ref max_size function of a JSON object.
17049
17050
    #### Storage
17051
17052
    Objects are stored as pointers in a @ref basic_json type. That is, for any
17053
    access to object values, a pointer of type `object_t*` must be
17054
    dereferenced.
17055
17056
    @sa @ref array_t -- type for an array value
17057
17058
    @since version 1.0.0
17059
17060
    @note The order name/value pairs are added to the object is *not*
17061
    preserved by the library. Therefore, iterating an object may return
17062
    name/value pairs in a different order than they were originally stored. In
17063
    fact, keys will be traversed in alphabetical order as `std::map` with
17064
    `std::less` is used by default. Please note this behavior conforms to [RFC
17065
    7159](http://rfc7159.net/rfc7159), because any order implements the
17066
    specified "unordered" nature of JSON objects.
17067
    */
17068
    using object_t = ObjectType<StringType,
17069
          basic_json,
17070
          object_comparator_t,
17071
          AllocatorType<std::pair<const StringType,
17072
          basic_json>>>;
17073
17074
    /*!
17075
    @brief a type for an array
17076
17077
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
17078
    > An array is an ordered sequence of zero or more values.
17079
17080
    To store objects in C++, a type is defined by the template parameters
17081
    explained below.
17082
17083
    @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
17084
    `std::list`)
17085
    @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
17086
17087
    #### Default type
17088
17089
    With the default values for @a ArrayType (`std::vector`) and @a
17090
    AllocatorType (`std::allocator`), the default value for @a array_t is:
17091
17092
    @code {.cpp}
17093
    std::vector<
17094
      basic_json, // value_type
17095
      std::allocator<basic_json> // allocator_type
17096
    >
17097
    @endcode
17098
17099
    #### Limits
17100
17101
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17102
    > An implementation may set limits on the maximum depth of nesting.
17103
17104
    In this class, the array's limit of nesting is not explicitly constrained.
17105
    However, a maximum depth of nesting may be introduced by the compiler or
17106
    runtime environment. A theoretical limit can be queried by calling the
17107
    @ref max_size function of a JSON array.
17108
17109
    #### Storage
17110
17111
    Arrays are stored as pointers in a @ref basic_json type. That is, for any
17112
    access to array values, a pointer of type `array_t*` must be dereferenced.
17113
17114
    @sa @ref object_t -- type for an object value
17115
17116
    @since version 1.0.0
17117
    */
17118
    using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17119
17120
    /*!
17121
    @brief a type for a string
17122
17123
    [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
17124
    > A string is a sequence of zero or more Unicode characters.
17125
17126
    To store objects in C++, a type is defined by the template parameter
17127
    described below. Unicode values are split by the JSON class into
17128
    byte-sized characters during deserialization.
17129
17130
    @tparam StringType  the container to store strings (e.g., `std::string`).
17131
    Note this container is used for keys/names in objects, see @ref object_t.
17132
17133
    #### Default type
17134
17135
    With the default values for @a StringType (`std::string`), the default
17136
    value for @a string_t is:
17137
17138
    @code {.cpp}
17139
    std::string
17140
    @endcode
17141
17142
    #### Encoding
17143
17144
    Strings are stored in UTF-8 encoding. Therefore, functions like
17145
    `std::string::size()` or `std::string::length()` return the number of
17146
    bytes in the string rather than the number of characters or glyphs.
17147
17148
    #### String comparison
17149
17150
    [RFC 7159](http://rfc7159.net/rfc7159) states:
17151
    > Software implementations are typically required to test names of object
17152
    > members for equality. Implementations that transform the textual
17153
    > representation into sequences of Unicode code units and then perform the
17154
    > comparison numerically, code unit by code unit, are interoperable in the
17155
    > sense that implementations will agree in all cases on equality or
17156
    > inequality of two strings. For example, implementations that compare
17157
    > strings with escaped characters unconverted may incorrectly find that
17158
    > `"a\\b"` and `"a\u005Cb"` are not equal.
17159
17160
    This implementation is interoperable as it does compare strings code unit
17161
    by code unit.
17162
17163
    #### Storage
17164
17165
    String values are stored as pointers in a @ref basic_json type. That is,
17166
    for any access to string values, a pointer of type `string_t*` must be
17167
    dereferenced.
17168
17169
    @since version 1.0.0
17170
    */
17171
    using string_t = StringType;
17172
17173
    /*!
17174
    @brief a type for a boolean
17175
17176
    [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
17177
    type which differentiates the two literals `true` and `false`.
17178
17179
    To store objects in C++, a type is defined by the template parameter @a
17180
    BooleanType which chooses the type to use.
17181
17182
    #### Default type
17183
17184
    With the default values for @a BooleanType (`bool`), the default value for
17185
    @a boolean_t is:
17186
17187
    @code {.cpp}
17188
    bool
17189
    @endcode
17190
17191
    #### Storage
17192
17193
    Boolean values are stored directly inside a @ref basic_json type.
17194
17195
    @since version 1.0.0
17196
    */
17197
    using boolean_t = BooleanType;
17198
17199
    /*!
17200
    @brief a type for a number (integer)
17201
17202
    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17203
    > The representation of numbers is similar to that used in most
17204
    > programming languages. A number is represented in base 10 using decimal
17205
    > digits. It contains an integer component that may be prefixed with an
17206
    > optional minus sign, which may be followed by a fraction part and/or an
17207
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
17208
    > cannot be represented in the grammar below (such as Infinity and NaN)
17209
    > are not permitted.
17210
17211
    This description includes both integer and floating-point numbers.
17212
    However, C++ allows more precise storage if it is known whether the number
17213
    is a signed integer, an unsigned integer or a floating-point number.
17214
    Therefore, three different types, @ref number_integer_t, @ref
17215
    number_unsigned_t and @ref number_float_t are used.
17216
17217
    To store integer numbers in C++, a type is defined by the template
17218
    parameter @a NumberIntegerType which chooses the type to use.
17219
17220
    #### Default type
17221
17222
    With the default values for @a NumberIntegerType (`int64_t`), the default
17223
    value for @a number_integer_t is:
17224
17225
    @code {.cpp}
17226
    int64_t
17227
    @endcode
17228
17229
    #### Default behavior
17230
17231
    - The restrictions about leading zeros is not enforced in C++. Instead,
17232
      leading zeros in integer literals lead to an interpretation as octal
17233
      number. Internally, the value will be stored as decimal number. For
17234
      instance, the C++ integer literal `010` will be serialized to `8`.
17235
      During deserialization, leading zeros yield an error.
17236
    - Not-a-number (NaN) values will be serialized to `null`.
17237
17238
    #### Limits
17239
17240
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17241
    > An implementation may set limits on the range and precision of numbers.
17242
17243
    When the default type is used, the maximal integer number that can be
17244
    stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
17245
    that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
17246
    that are out of range will yield over/underflow when used in a
17247
    constructor. During deserialization, too large or small integer numbers
17248
    will be automatically be stored as @ref number_unsigned_t or @ref
17249
    number_float_t.
17250
17251
    [RFC 7159](http://rfc7159.net/rfc7159) further states:
17252
    > Note that when such software is used, numbers that are integers and are
17253
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
17254
    > that implementations will agree exactly on their numeric values.
17255
17256
    As this range is a subrange of the exactly supported range [INT64_MIN,
17257
    INT64_MAX], this class's integer type is interoperable.
17258
17259
    #### Storage
17260
17261
    Integer number values are stored directly inside a @ref basic_json type.
17262
17263
    @sa @ref number_float_t -- type for number values (floating-point)
17264
17265
    @sa @ref number_unsigned_t -- type for number values (unsigned integer)
17266
17267
    @since version 1.0.0
17268
    */
17269
    using number_integer_t = NumberIntegerType;
17270
17271
    /*!
17272
    @brief a type for a number (unsigned)
17273
17274
    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17275
    > The representation of numbers is similar to that used in most
17276
    > programming languages. A number is represented in base 10 using decimal
17277
    > digits. It contains an integer component that may be prefixed with an
17278
    > optional minus sign, which may be followed by a fraction part and/or an
17279
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
17280
    > cannot be represented in the grammar below (such as Infinity and NaN)
17281
    > are not permitted.
17282
17283
    This description includes both integer and floating-point numbers.
17284
    However, C++ allows more precise storage if it is known whether the number
17285
    is a signed integer, an unsigned integer or a floating-point number.
17286
    Therefore, three different types, @ref number_integer_t, @ref
17287
    number_unsigned_t and @ref number_float_t are used.
17288
17289
    To store unsigned integer numbers in C++, a type is defined by the
17290
    template parameter @a NumberUnsignedType which chooses the type to use.
17291
17292
    #### Default type
17293
17294
    With the default values for @a NumberUnsignedType (`uint64_t`), the
17295
    default value for @a number_unsigned_t is:
17296
17297
    @code {.cpp}
17298
    uint64_t
17299
    @endcode
17300
17301
    #### Default behavior
17302
17303
    - The restrictions about leading zeros is not enforced in C++. Instead,
17304
      leading zeros in integer literals lead to an interpretation as octal
17305
      number. Internally, the value will be stored as decimal number. For
17306
      instance, the C++ integer literal `010` will be serialized to `8`.
17307
      During deserialization, leading zeros yield an error.
17308
    - Not-a-number (NaN) values will be serialized to `null`.
17309
17310
    #### Limits
17311
17312
    [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17313
    > An implementation may set limits on the range and precision of numbers.
17314
17315
    When the default type is used, the maximal integer number that can be
17316
    stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
17317
    number that can be stored is `0`. Integer numbers that are out of range
17318
    will yield over/underflow when used in a constructor. During
17319
    deserialization, too large or small integer numbers will be automatically
17320
    be stored as @ref number_integer_t or @ref number_float_t.
17321
17322
    [RFC 7159](http://rfc7159.net/rfc7159) further states:
17323
    > Note that when such software is used, numbers that are integers and are
17324
    > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
17325
    > that implementations will agree exactly on their numeric values.
17326
17327
    As this range is a subrange (when considered in conjunction with the
17328
    number_integer_t type) of the exactly supported range [0, UINT64_MAX],
17329
    this class's integer type is interoperable.
17330
17331
    #### Storage
17332
17333
    Integer number values are stored directly inside a @ref basic_json type.
17334
17335
    @sa @ref number_float_t -- type for number values (floating-point)
17336
    @sa @ref number_integer_t -- type for number values (integer)
17337
17338
    @since version 2.0.0
17339
    */
17340
    using number_unsigned_t = NumberUnsignedType;
17341
17342
    /*!
17343
    @brief a type for a number (floating-point)
17344
17345
    [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17346
    > The representation of numbers is similar to that used in most
17347
    > programming languages. A number is represented in base 10 using decimal
17348
    > digits. It contains an integer component that may be prefixed with an
17349
    > optional minus sign, which may be followed by a fraction part and/or an
17350
    > exponent part. Leading zeros are not allowed. (...) Numeric values that
17351
    > cannot be represented in the grammar below (such as Infinity and NaN)
17352
    > are not permitted.
17353
17354
    This description includes both integer and floating-point numbers.
17355
    However, C++ allows more precise storage if it is known whether the number
17356
    is a signed integer, an unsigned integer or a floating-point number.
17357
    Therefore, three different types, @ref number_integer_t, @ref
17358
    number_unsigned_t and @ref number_float_t are used.
17359
17360
    To store floating-point numbers in C++, a type is defined by the template
17361
    parameter @a NumberFloatType which chooses the type to use.
17362
17363
    #### Default type
17364
17365
    With the default values for @a NumberFloatType (`double`), the default
17366
    value for @a number_float_t is:
17367
17368
    @code {.cpp}
17369
    double
17370
    @endcode
17371
17372
    #### Default behavior
17373
17374
    - The restrictions about leading zeros is not enforced in C++. Instead,
17375
      leading zeros in floating-point literals will be ignored. Internally,
17376
      the value will be stored as decimal number. For instance, the C++
17377
      floating-point literal `01.2` will be serialized to `1.2`. During
17378
      deserialization, leading zeros yield an error.
17379
    - Not-a-number (NaN) values will be serialized to `null`.
17380
17381
    #### Limits
17382
17383
    [RFC 7159](http://rfc7159.net/rfc7159) states:
17384
    > This specification allows implementations to set limits on the range and
17385
    > precision of numbers accepted. Since software that implements IEEE
17386
    > 754-2008 binary64 (double precision) numbers is generally available and
17387
    > widely used, good interoperability can be achieved by implementations
17388
    > that expect no more precision or range than these provide, in the sense
17389
    > that implementations will approximate JSON numbers within the expected
17390
    > precision.
17391
17392
    This implementation does exactly follow this approach, as it uses double
17393
    precision floating-point numbers. Note values smaller than
17394
    `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
17395
    will be stored as NaN internally and be serialized to `null`.
17396
17397
    #### Storage
17398
17399
    Floating-point number values are stored directly inside a @ref basic_json
17400
    type.
17401
17402
    @sa @ref number_integer_t -- type for number values (integer)
17403
17404
    @sa @ref number_unsigned_t -- type for number values (unsigned integer)
17405
17406
    @since version 1.0.0
17407
    */
17408
    using number_float_t = NumberFloatType;
17409
17410
    /*!
17411
    @brief a type for a packed binary type
17412
17413
    This type is a type designed to carry binary data that appears in various
17414
    serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
17415
    BSON's generic binary subtype. This type is NOT a part of standard JSON and
17416
    exists solely for compatibility with these binary types. As such, it is
17417
    simply defined as an ordered sequence of zero or more byte values.
17418
17419
    Additionally, as an implementation detail, the subtype of the binary data is
17420
    carried around as a `std::uint8_t`, which is compatible with both of the
17421
    binary data formats that use binary subtyping, (though the specific
17422
    numbering is incompatible with each other, and it is up to the user to
17423
    translate between them).
17424
17425
    [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
17426
    as:
17427
    > Major type 2: a byte string. The string's length in bytes is represented
17428
    > following the rules for positive integers (major type 0).
17429
17430
    [MessagePack's documentation on the bin type
17431
    family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
17432
    describes this type as:
17433
    > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
17434
    > in addition to the size of the byte array.
17435
17436
    [BSON's specifications](http://bsonspec.org/spec.html) describe several
17437
    binary types; however, this type is intended to represent the generic binary
17438
    type which has the description:
17439
    > Generic binary subtype - This is the most commonly used binary subtype and
17440
    > should be the 'default' for drivers and tools.
17441
17442
    None of these impose any limitations on the internal representation other
17443
    than the basic unit of storage be some type of array whose parts are
17444
    decomposable into bytes.
17445
17446
    The default representation of this binary format is a
17447
    `std::vector<std::uint8_t>`, which is a very common way to represent a byte
17448
    array in modern C++.
17449
17450
    #### Default type
17451
17452
    The default values for @a BinaryType is `std::vector<std::uint8_t>`
17453
17454
    #### Storage
17455
17456
    Binary Arrays are stored as pointers in a @ref basic_json type. That is,
17457
    for any access to array values, a pointer of the type `binary_t*` must be
17458
    dereferenced.
17459
17460
    #### Notes on subtypes
17461
17462
    - CBOR
17463
       - Binary values are represented as byte strings. No subtypes are
17464
         supported and will be ignored when CBOR is written.
17465
    - MessagePack
17466
       - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
17467
         or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
17468
         is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
17469
         The subtype is then added as singed 8-bit integer.
17470
       - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
17471
    - BSON
17472
       - If a subtype is given, it is used and added as unsigned 8-bit integer.
17473
       - If no subtype is given, the generic binary subtype 0x00 is used.
17474
17475
    @sa @ref binary -- create a binary array
17476
17477
    @since version 3.8.0
17478
    */
17479
    using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17480
    /// @}
17481
17482
  private:
17483
17484
    /// helper for exception-safe object creation
17485
    template<typename T, typename... Args>
17486
    JSON_HEDLEY_RETURNS_NON_NULL
17487
    static T* create(Args&& ... args)
17488
0
    {
17489
0
        AllocatorType<T> alloc;
17490
0
        using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17491
17492
0
        auto deleter = [&](T * object)
17493
0
        {
17494
0
            AllocatorTraits::deallocate(alloc, object, 1);
17495
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::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> >, 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> >&&)::{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<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<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
17496
0
        std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17497
0
        AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17498
0
        JSON_ASSERT(object != nullptr);
17499
0
        return object.release();
17500
0
    }
Unexecuted instantiation: std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::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> > > > > >>()
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> > > > >>()
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::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: 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&)
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::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> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
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*&&)
17501
17502
    ////////////////////////
17503
    // JSON value storage //
17504
    ////////////////////////
17505
17506
  JSON_PRIVATE_UNLESS_TESTED:
17507
    /*!
17508
    @brief a JSON value
17509
17510
    The actual storage for a JSON value of the @ref basic_json class. This
17511
    union combines the different storage types for the JSON value types
17512
    defined in @ref value_t.
17513
17514
    JSON type | value_t type    | used type
17515
    --------- | --------------- | ------------------------
17516
    object    | object          | pointer to @ref object_t
17517
    array     | array           | pointer to @ref array_t
17518
    string    | string          | pointer to @ref string_t
17519
    boolean   | boolean         | @ref boolean_t
17520
    number    | number_integer  | @ref number_integer_t
17521
    number    | number_unsigned | @ref number_unsigned_t
17522
    number    | number_float    | @ref number_float_t
17523
    binary    | binary          | pointer to @ref binary_t
17524
    null      | null            | *no value is stored*
17525
17526
    @note Variable-length types (objects, arrays, and strings) are stored as
17527
    pointers. The size of the union should not exceed 64 bits if the default
17528
    value types are used.
17529
17530
    @since version 1.0.0
17531
    */
17532
    union json_value
17533
    {
17534
        /// object (stored with pointer to save storage)
17535
        object_t* object;
17536
        /// array (stored with pointer to save storage)
17537
        array_t* array;
17538
        /// string (stored with pointer to save storage)
17539
        string_t* string;
17540
        /// binary (stored with pointer to save storage)
17541
        binary_t* binary;
17542
        /// boolean
17543
        boolean_t boolean;
17544
        /// number (integer)
17545
        number_integer_t number_integer;
17546
        /// number (unsigned integer)
17547
        number_unsigned_t number_unsigned;
17548
        /// number (floating-point)
17549
        number_float_t number_float;
17550
17551
        /// default constructor (for null values)
17552
        json_value() = default;
17553
        /// constructor for booleans
17554
0
        json_value(boolean_t v) noexcept : boolean(v) {}
17555
        /// constructor for numbers (integer)
17556
0
        json_value(number_integer_t v) noexcept : number_integer(v) {}
17557
        /// constructor for numbers (unsigned)
17558
0
        json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
17559
        /// constructor for numbers (floating-point)
17560
0
        json_value(number_float_t v) noexcept : number_float(v) {}
17561
        /// constructor for empty values of a given type
17562
        json_value(value_t t)
17563
0
        {
17564
0
            switch (t)
17565
0
            {
17566
0
                case value_t::object:
17567
0
                {
17568
0
                    object = create<object_t>();
17569
0
                    break;
17570
0
                }
17571
17572
0
                case value_t::array:
17573
0
                {
17574
0
                    array = create<array_t>();
17575
0
                    break;
17576
0
                }
17577
17578
0
                case value_t::string:
17579
0
                {
17580
0
                    string = create<string_t>("");
17581
0
                    break;
17582
0
                }
17583
17584
0
                case value_t::binary:
17585
0
                {
17586
0
                    binary = create<binary_t>();
17587
0
                    break;
17588
0
                }
17589
17590
0
                case value_t::boolean:
17591
0
                {
17592
0
                    boolean = boolean_t(false);
17593
0
                    break;
17594
0
                }
17595
17596
0
                case value_t::number_integer:
17597
0
                {
17598
0
                    number_integer = number_integer_t(0);
17599
0
                    break;
17600
0
                }
17601
17602
0
                case value_t::number_unsigned:
17603
0
                {
17604
0
                    number_unsigned = number_unsigned_t(0);
17605
0
                    break;
17606
0
                }
17607
17608
0
                case value_t::number_float:
17609
0
                {
17610
0
                    number_float = number_float_t(0.0);
17611
0
                    break;
17612
0
                }
17613
17614
0
                case value_t::null:
17615
0
                {
17616
0
                    object = nullptr;  // silence warning, see #821
17617
0
                    break;
17618
0
                }
17619
17620
0
                default:
17621
0
                {
17622
0
                    object = nullptr;  // silence warning, see #821
17623
0
                    if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17624
0
                    {
17625
0
                        JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
17626
0
                    }
17627
0
                    break;
17628
0
                }
17629
0
            }
17630
0
        }
17631
17632
        /// constructor for strings
17633
        json_value(const string_t& value)
17634
0
        {
17635
0
            string = create<string_t>(value);
17636
0
        }
17637
17638
        /// constructor for rvalue strings
17639
        json_value(string_t&& value)
17640
0
        {
17641
0
            string = create<string_t>(std::move(value));
17642
0
        }
17643
17644
        /// constructor for objects
17645
        json_value(const object_t& value)
17646
0
        {
17647
0
            object = create<object_t>(value);
17648
0
        }
17649
17650
        /// constructor for rvalue objects
17651
        json_value(object_t&& value)
17652
        {
17653
            object = create<object_t>(std::move(value));
17654
        }
17655
17656
        /// constructor for arrays
17657
        json_value(const array_t& value)
17658
0
        {
17659
0
            array = create<array_t>(value);
17660
0
        }
17661
17662
        /// constructor for rvalue arrays
17663
        json_value(array_t&& value)
17664
        {
17665
            array = create<array_t>(std::move(value));
17666
        }
17667
17668
        /// constructor for binary arrays
17669
        json_value(const typename binary_t::container_type& value)
17670
        {
17671
            binary = create<binary_t>(value);
17672
        }
17673
17674
        /// constructor for rvalue binary arrays
17675
        json_value(typename binary_t::container_type&& value)
17676
        {
17677
            binary = create<binary_t>(std::move(value));
17678
        }
17679
17680
        /// constructor for binary arrays (internal type)
17681
        json_value(const binary_t& value)
17682
0
        {
17683
0
            binary = create<binary_t>(value);
17684
0
        }
17685
17686
        /// constructor for rvalue binary arrays (internal type)
17687
        json_value(binary_t&& value)
17688
        {
17689
            binary = create<binary_t>(std::move(value));
17690
        }
17691
17692
        void destroy(value_t t) noexcept
17693
0
        {
17694
            // flatten the current json_value to a heap-allocated stack
17695
0
            std::vector<basic_json> stack;
17696
17697
            // move the top-level items to stack
17698
0
            if (t == value_t::array)
17699
0
            {
17700
0
                stack.reserve(array->size());
17701
0
                std::move(array->begin(), array->end(), std::back_inserter(stack));
17702
0
            }
17703
0
            else if (t == value_t::object)
17704
0
            {
17705
0
                stack.reserve(object->size());
17706
0
                for (auto&& it : *object)
17707
0
                {
17708
0
                    stack.push_back(std::move(it.second));
17709
0
                }
17710
0
            }
17711
17712
0
            while (!stack.empty())
17713
0
            {
17714
                // move the last item to local variable to be processed
17715
0
                basic_json current_item(std::move(stack.back()));
17716
0
                stack.pop_back();
17717
17718
                // if current_item is array/object, move
17719
                // its children to the stack to be processed later
17720
0
                if (current_item.is_array())
17721
0
                {
17722
0
                    std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17723
0
                              std::back_inserter(stack));
17724
17725
0
                    current_item.m_value.array->clear();
17726
0
                }
17727
0
                else if (current_item.is_object())
17728
0
                {
17729
0
                    for (auto&& it : *current_item.m_value.object)
17730
0
                    {
17731
0
                        stack.push_back(std::move(it.second));
17732
0
                    }
17733
17734
0
                    current_item.m_value.object->clear();
17735
0
                }
17736
17737
                // it's now safe that current_item get destructed
17738
                // since it doesn't have any children
17739
0
            }
17740
17741
0
            switch (t)
17742
0
            {
17743
0
                case value_t::object:
17744
0
                {
17745
0
                    AllocatorType<object_t> alloc;
17746
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17747
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17748
0
                    break;
17749
0
                }
17750
17751
0
                case value_t::array:
17752
0
                {
17753
0
                    AllocatorType<array_t> alloc;
17754
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17755
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17756
0
                    break;
17757
0
                }
17758
17759
0
                case value_t::string:
17760
0
                {
17761
0
                    AllocatorType<string_t> alloc;
17762
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17763
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17764
0
                    break;
17765
0
                }
17766
17767
0
                case value_t::binary:
17768
0
                {
17769
0
                    AllocatorType<binary_t> alloc;
17770
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17771
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17772
0
                    break;
17773
0
                }
17774
17775
0
                default:
17776
0
                {
17777
0
                    break;
17778
0
                }
17779
0
            }
17780
0
        }
17781
    };
17782
17783
  private:
17784
    /*!
17785
    @brief checks the class invariants
17786
17787
    This function asserts the class invariants. It needs to be called at the
17788
    end of every constructor to make sure that created objects respect the
17789
    invariant. Furthermore, it has to be called each time the type of a JSON
17790
    value is changed, because the invariant expresses a relationship between
17791
    @a m_type and @a m_value.
17792
    */
17793
    void assert_invariant() const noexcept
17794
0
    {
17795
0
        JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17796
0
        JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17797
0
        JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17798
0
        JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17799
0
    }
17800
17801
  public:
17802
    //////////////////////////
17803
    // JSON parser callback //
17804
    //////////////////////////
17805
17806
    /*!
17807
    @brief parser event types
17808
17809
    The parser callback distinguishes the following events:
17810
    - `object_start`: the parser read `{` and started to process a JSON object
17811
    - `key`: the parser read a key of a value in an object
17812
    - `object_end`: the parser read `}` and finished processing a JSON object
17813
    - `array_start`: the parser read `[` and started to process a JSON array
17814
    - `array_end`: the parser read `]` and finished processing a JSON array
17815
    - `value`: the parser finished reading a JSON value
17816
17817
    @image html callback_events.png "Example when certain parse events are triggered"
17818
17819
    @sa @ref parser_callback_t for more information and examples
17820
    */
17821
    using parse_event_t = detail::parse_event_t;
17822
17823
    /*!
17824
    @brief per-element parser callback type
17825
17826
    With a parser callback function, the result of parsing a JSON text can be
17827
    influenced. When passed to @ref parse, it is called on certain events
17828
    (passed as @ref parse_event_t via parameter @a event) with a set recursion
17829
    depth @a depth and context JSON value @a parsed. The return value of the
17830
    callback function is a boolean indicating whether the element that emitted
17831
    the callback shall be kept or not.
17832
17833
    We distinguish six scenarios (determined by the event type) in which the
17834
    callback function can be called. The following table describes the values
17835
    of the parameters @a depth, @a event, and @a parsed.
17836
17837
    parameter @a event | description | parameter @a depth | parameter @a parsed
17838
    ------------------ | ----------- | ------------------ | -------------------
17839
    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
17840
    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
17841
    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
17842
    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
17843
    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
17844
    parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
17845
17846
    @image html callback_events.png "Example when certain parse events are triggered"
17847
17848
    Discarding a value (i.e., returning `false`) has different effects
17849
    depending on the context in which function was called:
17850
17851
    - Discarded values in structured types are skipped. That is, the parser
17852
      will behave as if the discarded value was never read.
17853
    - In case a value outside a structured type is skipped, it is replaced
17854
      with `null`. This case happens if the top-level element is skipped.
17855
17856
    @param[in] depth  the depth of the recursion during parsing
17857
17858
    @param[in] event  an event of type parse_event_t indicating the context in
17859
    the callback function has been called
17860
17861
    @param[in,out] parsed  the current intermediate parse result; note that
17862
    writing to this value has no effect for parse_event_t::key events
17863
17864
    @return Whether the JSON value which called the function during parsing
17865
    should be kept (`true`) or not (`false`). In the latter case, it is either
17866
    skipped completely or replaced by an empty discarded object.
17867
17868
    @sa @ref parse for examples
17869
17870
    @since version 1.0.0
17871
    */
17872
    using parser_callback_t = detail::parser_callback_t<basic_json>;
17873
17874
    //////////////////
17875
    // constructors //
17876
    //////////////////
17877
17878
    /// @name constructors and destructors
17879
    /// Constructors of class @ref basic_json, copy/move constructor, copy
17880
    /// assignment, static functions creating objects, and the destructor.
17881
    /// @{
17882
17883
    /*!
17884
    @brief create an empty value with a given type
17885
17886
    Create an empty JSON value with a given type. The value will be default
17887
    initialized with an empty value which depends on the type:
17888
17889
    Value type  | initial value
17890
    ----------- | -------------
17891
    null        | `null`
17892
    boolean     | `false`
17893
    string      | `""`
17894
    number      | `0`
17895
    object      | `{}`
17896
    array       | `[]`
17897
    binary      | empty array
17898
17899
    @param[in] v  the type of the value to create
17900
17901
    @complexity Constant.
17902
17903
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17904
    changes to any JSON value.
17905
17906
    @liveexample{The following code shows the constructor for different @ref
17907
    value_t values,basic_json__value_t}
17908
17909
    @sa @ref clear() -- restores the postcondition of this constructor
17910
17911
    @since version 1.0.0
17912
    */
17913
    basic_json(const value_t v)
17914
        : m_type(v), m_value(v)
17915
0
    {
17916
0
        assert_invariant();
17917
0
    }
17918
17919
    /*!
17920
    @brief create a null object
17921
17922
    Create a `null` JSON value. It either takes a null pointer as parameter
17923
    (explicitly creating `null`) or no parameter (implicitly creating `null`).
17924
    The passed null pointer itself is not read -- it is only used to choose
17925
    the right constructor.
17926
17927
    @complexity Constant.
17928
17929
    @exceptionsafety No-throw guarantee: this constructor never throws
17930
    exceptions.
17931
17932
    @liveexample{The following code shows the constructor with and without a
17933
    null pointer parameter.,basic_json__nullptr_t}
17934
17935
    @since version 1.0.0
17936
    */
17937
    basic_json(std::nullptr_t = nullptr) noexcept
17938
        : basic_json(value_t::null)
17939
0
    {
17940
0
        assert_invariant();
17941
0
    }
17942
17943
    /*!
17944
    @brief create a JSON value
17945
17946
    This is a "catch all" constructor for all compatible JSON types; that is,
17947
    types for which a `to_json()` method exists. The constructor forwards the
17948
    parameter @a val to that method (to `json_serializer<U>::to_json` method
17949
    with `U = uncvref_t<CompatibleType>`, to be exact).
17950
17951
    Template type @a CompatibleType includes, but is not limited to, the
17952
    following types:
17953
    - **arrays**: @ref array_t and all kinds of compatible containers such as
17954
      `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
17955
      `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
17956
      `std::multiset`, and `std::unordered_multiset` with a `value_type` from
17957
      which a @ref basic_json value can be constructed.
17958
    - **objects**: @ref object_t and all kinds of compatible associative
17959
      containers such as `std::map`, `std::unordered_map`, `std::multimap`,
17960
      and `std::unordered_multimap` with a `key_type` compatible to
17961
      @ref string_t and a `value_type` from which a @ref basic_json value can
17962
      be constructed.
17963
    - **strings**: @ref string_t, string literals, and all compatible string
17964
      containers can be used.
17965
    - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
17966
      @ref number_float_t, and all convertible number types such as `int`,
17967
      `size_t`, `int64_t`, `float` or `double` can be used.
17968
    - **boolean**: @ref boolean_t / `bool` can be used.
17969
    - **binary**: @ref binary_t / `std::vector<uint8_t>` may be used,
17970
      unfortunately because string literals cannot be distinguished from binary
17971
      character arrays by the C++ type system, all types compatible with `const
17972
      char*` will be directed to the string constructor instead.  This is both
17973
      for backwards compatibility, and due to the fact that a binary type is not
17974
      a standard JSON type.
17975
17976
    See the examples below.
17977
17978
    @tparam CompatibleType a type such that:
17979
    - @a CompatibleType is not derived from `std::istream`,
17980
    - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
17981
         constructors),
17982
    - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
17983
    - @a CompatibleType is not a @ref basic_json nested type (e.g.,
17984
         @ref json_pointer, @ref iterator, etc ...)
17985
    - @ref @ref json_serializer<U> has a
17986
         `to_json(basic_json_t&, CompatibleType&&)` method
17987
17988
    @tparam U = `uncvref_t<CompatibleType>`
17989
17990
    @param[in] val the value to be forwarded to the respective constructor
17991
17992
    @complexity Usually linear in the size of the passed @a val, also
17993
                depending on the implementation of the called `to_json()`
17994
                method.
17995
17996
    @exceptionsafety Depends on the called constructor. For types directly
17997
    supported by the library (i.e., all types for which no `to_json()` function
17998
    was provided), strong guarantee holds: if an exception is thrown, there are
17999
    no changes to any JSON value.
18000
18001
    @liveexample{The following code shows the constructor with several
18002
    compatible types.,basic_json__CompatibleType}
18003
18004
    @since version 2.1.0
18005
    */
18006
    template < typename CompatibleType,
18007
               typename U = detail::uncvref_t<CompatibleType>,
18008
               detail::enable_if_t <
18009
                   !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
18010
    basic_json(CompatibleType && val) noexcept(noexcept(
18011
                JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18012
                                           std::forward<CompatibleType>(val))))
18013
0
    {
18014
0
        JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18015
0
        assert_invariant();
18016
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> > >::basic_json<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, 0>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, 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> >&)
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&, double, 0>(double&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<bool&, bool, 0>(bool&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<long&, long, 0>(long&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<unsigned long&, unsigned long, 0>(unsigned long&)
Unexecuted instantiation: nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::basic_json<eprosima::fastrtps::rtps::ChangeKind_t const&, eprosima::fastrtps::rtps::ChangeKind_t, 0>(eprosima::fastrtps::rtps::ChangeKind_t 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<unsigned short const&, unsigned short, 0>(unsigned short 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<unsigned int const&, unsigned int, 0>(unsigned 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<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&&)
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&)
18017
18018
    /*!
18019
    @brief create a JSON value from an existing one
18020
18021
    This is a constructor for existing @ref basic_json types.
18022
    It does not hijack copy/move constructors, since the parameter has different
18023
    template arguments than the current ones.
18024
18025
    The constructor tries to convert the internal @ref m_value of the parameter.
18026
18027
    @tparam BasicJsonType a type such that:
18028
    - @a BasicJsonType is a @ref basic_json type.
18029
    - @a BasicJsonType has different template arguments than @ref basic_json_t.
18030
18031
    @param[in] val the @ref basic_json value to be converted.
18032
18033
    @complexity Usually linear in the size of the passed @a val, also
18034
                depending on the implementation of the called `to_json()`
18035
                method.
18036
18037
    @exceptionsafety Depends on the called constructor. For types directly
18038
    supported by the library (i.e., all types for which no `to_json()` function
18039
    was provided), strong guarantee holds: if an exception is thrown, there are
18040
    no changes to any JSON value.
18041
18042
    @since version 3.2.0
18043
    */
18044
    template < typename BasicJsonType,
18045
               detail::enable_if_t <
18046
                   detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
18047
    basic_json(const BasicJsonType& val)
18048
    {
18049
        using other_boolean_t = typename BasicJsonType::boolean_t;
18050
        using other_number_float_t = typename BasicJsonType::number_float_t;
18051
        using other_number_integer_t = typename BasicJsonType::number_integer_t;
18052
        using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18053
        using other_string_t = typename BasicJsonType::string_t;
18054
        using other_object_t = typename BasicJsonType::object_t;
18055
        using other_array_t = typename BasicJsonType::array_t;
18056
        using other_binary_t = typename BasicJsonType::binary_t;
18057
18058
        switch (val.type())
18059
        {
18060
            case value_t::boolean:
18061
                JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18062
                break;
18063
            case value_t::number_float:
18064
                JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18065
                break;
18066
            case value_t::number_integer:
18067
                JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18068
                break;
18069
            case value_t::number_unsigned:
18070
                JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18071
                break;
18072
            case value_t::string:
18073
                JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18074
                break;
18075
            case value_t::object:
18076
                JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18077
                break;
18078
            case value_t::array:
18079
                JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18080
                break;
18081
            case value_t::binary:
18082
                JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18083
                break;
18084
            case value_t::null:
18085
                *this = nullptr;
18086
                break;
18087
            case value_t::discarded:
18088
                m_type = value_t::discarded;
18089
                break;
18090
            default:            // LCOV_EXCL_LINE
18091
                JSON_ASSERT(false);  // LCOV_EXCL_LINE
18092
        }
18093
        assert_invariant();
18094
    }
18095
18096
    /*!
18097
    @brief create a container (array or object) from an initializer list
18098
18099
    Creates a JSON value of type array or object from the passed initializer
18100
    list @a init. In case @a type_deduction is `true` (default), the type of
18101
    the JSON value to be created is deducted from the initializer list @a init
18102
    according to the following rules:
18103
18104
    1. If the list is empty, an empty JSON object value `{}` is created.
18105
    2. If the list consists of pairs whose first element is a string, a JSON
18106
       object value is created where the first elements of the pairs are
18107
       treated as keys and the second elements are as values.
18108
    3. In all other cases, an array is created.
18109
18110
    The rules aim to create the best fit between a C++ initializer list and
18111
    JSON values. The rationale is as follows:
18112
18113
    1. The empty initializer list is written as `{}` which is exactly an empty
18114
       JSON object.
18115
    2. C++ has no way of describing mapped types other than to list a list of
18116
       pairs. As JSON requires that keys must be of type string, rule 2 is the
18117
       weakest constraint one can pose on initializer lists to interpret them
18118
       as an object.
18119
    3. In all other cases, the initializer list could not be interpreted as
18120
       JSON object type, so interpreting it as JSON array type is safe.
18121
18122
    With the rules described above, the following JSON values cannot be
18123
    expressed by an initializer list:
18124
18125
    - the empty array (`[]`): use @ref array(initializer_list_t)
18126
      with an empty initializer list in this case
18127
    - arrays whose elements satisfy rule 2: use @ref
18128
      array(initializer_list_t) with the same initializer list
18129
      in this case
18130
18131
    @note When used without parentheses around an empty initializer list, @ref
18132
    basic_json() is called instead of this function, yielding the JSON null
18133
    value.
18134
18135
    @param[in] init  initializer list with JSON values
18136
18137
    @param[in] type_deduction internal parameter; when set to `true`, the type
18138
    of the JSON value is deducted from the initializer list @a init; when set
18139
    to `false`, the type provided via @a manual_type is forced. This mode is
18140
    used by the functions @ref array(initializer_list_t) and
18141
    @ref object(initializer_list_t).
18142
18143
    @param[in] manual_type internal parameter; when @a type_deduction is set
18144
    to `false`, the created JSON value will use the provided type (only @ref
18145
    value_t::array and @ref value_t::object are valid); when @a type_deduction
18146
    is set to `true`, this parameter has no effect
18147
18148
    @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
18149
    `value_t::object`, but @a init contains an element which is not a pair
18150
    whose first element is a string. In this case, the constructor could not
18151
    create an object. If @a type_deduction would have be `true`, an array
18152
    would have been created. See @ref object(initializer_list_t)
18153
    for an example.
18154
18155
    @complexity Linear in the size of the initializer list @a init.
18156
18157
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18158
    changes to any JSON value.
18159
18160
    @liveexample{The example below shows how JSON values are created from
18161
    initializer lists.,basic_json__list_init_t}
18162
18163
    @sa @ref array(initializer_list_t) -- create a JSON array
18164
    value from an initializer list
18165
    @sa @ref object(initializer_list_t) -- create a JSON object
18166
    value from an initializer list
18167
18168
    @since version 1.0.0
18169
    */
18170
    basic_json(initializer_list_t init,
18171
               bool type_deduction = true,
18172
               value_t manual_type = value_t::array)
18173
0
    {
18174
        // check if each element is an array with two elements whose first
18175
        // element is a string
18176
0
        bool is_an_object = std::all_of(init.begin(), init.end(),
18177
0
                                        [](const detail::json_ref<basic_json>& element_ref)
18178
0
        {
18179
0
            return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18180
0
        });
18181
18182
        // adjust type if type deduction is not wanted
18183
0
        if (!type_deduction)
18184
0
        {
18185
            // if array is wanted, do not create an object though possible
18186
0
            if (manual_type == value_t::array)
18187
0
            {
18188
0
                is_an_object = false;
18189
0
            }
18190
18191
            // if object is wanted but impossible, throw an exception
18192
0
            if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18193
0
            {
18194
0
                JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18195
0
            }
18196
0
        }
18197
18198
0
        if (is_an_object)
18199
0
        {
18200
            // the initializer list is a list of pairs -> create object
18201
0
            m_type = value_t::object;
18202
0
            m_value = value_t::object;
18203
18204
0
            std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18205
0
            {
18206
0
                auto element = element_ref.moved_or_copied();
18207
0
                m_value.object->emplace(
18208
0
                    std::move(*((*element.m_value.array)[0].m_value.string)),
18209
0
                    std::move((*element.m_value.array)[1]));
18210
0
            });
18211
0
        }
18212
0
        else
18213
0
        {
18214
            // the initializer list describes an array -> create array
18215
0
            m_type = value_t::array;
18216
0
            m_value.array = create<array_t>(init.begin(), init.end());
18217
0
        }
18218
18219
0
        assert_invariant();
18220
0
    }
18221
18222
    /*!
18223
    @brief explicitly create a binary array (without subtype)
18224
18225
    Creates a JSON binary array value from a given binary container. Binary
18226
    values are part of various binary formats, such as CBOR, MessagePack, and
18227
    BSON. This constructor is used to create a value for serialization to those
18228
    formats.
18229
18230
    @note Note, this function exists because of the difficulty in correctly
18231
    specifying the correct template overload in the standard value ctor, as both
18232
    JSON arrays and JSON binary arrays are backed with some form of a
18233
    `std::vector`. Because JSON binary arrays are a non-standard extension it
18234
    was decided that it would be best to prevent automatic initialization of a
18235
    binary array type, for backwards compatibility and so it does not happen on
18236
    accident.
18237
18238
    @param[in] init container containing bytes to use as binary type
18239
18240
    @return JSON binary array value
18241
18242
    @complexity Linear in the size of @a init.
18243
18244
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18245
    changes to any JSON value.
18246
18247
    @since version 3.8.0
18248
    */
18249
    JSON_HEDLEY_WARN_UNUSED_RESULT
18250
    static basic_json binary(const typename binary_t::container_type& init)
18251
    {
18252
        auto res = basic_json();
18253
        res.m_type = value_t::binary;
18254
        res.m_value = init;
18255
        return res;
18256
    }
18257
18258
    /*!
18259
    @brief explicitly create a binary array (with subtype)
18260
18261
    Creates a JSON binary array value from a given binary container. Binary
18262
    values are part of various binary formats, such as CBOR, MessagePack, and
18263
    BSON. This constructor is used to create a value for serialization to those
18264
    formats.
18265
18266
    @note Note, this function exists because of the difficulty in correctly
18267
    specifying the correct template overload in the standard value ctor, as both
18268
    JSON arrays and JSON binary arrays are backed with some form of a
18269
    `std::vector`. Because JSON binary arrays are a non-standard extension it
18270
    was decided that it would be best to prevent automatic initialization of a
18271
    binary array type, for backwards compatibility and so it does not happen on
18272
    accident.
18273
18274
    @param[in] init container containing bytes to use as binary type
18275
    @param[in] subtype subtype to use in MessagePack and BSON
18276
18277
    @return JSON binary array value
18278
18279
    @complexity Linear in the size of @a init.
18280
18281
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18282
    changes to any JSON value.
18283
18284
    @since version 3.8.0
18285
    */
18286
    JSON_HEDLEY_WARN_UNUSED_RESULT
18287
    static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18288
    {
18289
        auto res = basic_json();
18290
        res.m_type = value_t::binary;
18291
        res.m_value = binary_t(init, subtype);
18292
        return res;
18293
    }
18294
18295
    /// @copydoc binary(const typename binary_t::container_type&)
18296
    JSON_HEDLEY_WARN_UNUSED_RESULT
18297
    static basic_json binary(typename binary_t::container_type&& init)
18298
    {
18299
        auto res = basic_json();
18300
        res.m_type = value_t::binary;
18301
        res.m_value = std::move(init);
18302
        return res;
18303
    }
18304
18305
    /// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)
18306
    JSON_HEDLEY_WARN_UNUSED_RESULT
18307
    static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18308
    {
18309
        auto res = basic_json();
18310
        res.m_type = value_t::binary;
18311
        res.m_value = binary_t(std::move(init), subtype);
18312
        return res;
18313
    }
18314
18315
    /*!
18316
    @brief explicitly create an array from an initializer list
18317
18318
    Creates a JSON array value from a given initializer list. That is, given a
18319
    list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
18320
    initializer list is empty, the empty array `[]` is created.
18321
18322
    @note This function is only needed to express two edge cases that cannot
18323
    be realized with the initializer list constructor (@ref
18324
    basic_json(initializer_list_t, bool, value_t)). These cases
18325
    are:
18326
    1. creating an array whose elements are all pairs whose first element is a
18327
    string -- in this case, the initializer list constructor would create an
18328
    object, taking the first elements as keys
18329
    2. creating an empty array -- passing the empty initializer list to the
18330
    initializer list constructor yields an empty object
18331
18332
    @param[in] init  initializer list with JSON values to create an array from
18333
    (optional)
18334
18335
    @return JSON array value
18336
18337
    @complexity Linear in the size of @a init.
18338
18339
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18340
    changes to any JSON value.
18341
18342
    @liveexample{The following code shows an example for the `array`
18343
    function.,array}
18344
18345
    @sa @ref basic_json(initializer_list_t, bool, value_t) --
18346
    create a JSON value from an initializer list
18347
    @sa @ref object(initializer_list_t) -- create a JSON object
18348
    value from an initializer list
18349
18350
    @since version 1.0.0
18351
    */
18352
    JSON_HEDLEY_WARN_UNUSED_RESULT
18353
    static basic_json array(initializer_list_t init = {})
18354
    {
18355
        return basic_json(init, false, value_t::array);
18356
    }
18357
18358
    /*!
18359
    @brief explicitly create an object from an initializer list
18360
18361
    Creates a JSON object value from a given initializer list. The initializer
18362
    lists elements must be pairs, and their first elements must be strings. If
18363
    the initializer list is empty, the empty object `{}` is created.
18364
18365
    @note This function is only added for symmetry reasons. In contrast to the
18366
    related function @ref array(initializer_list_t), there are
18367
    no cases which can only be expressed by this function. That is, any
18368
    initializer list @a init can also be passed to the initializer list
18369
    constructor @ref basic_json(initializer_list_t, bool, value_t).
18370
18371
    @param[in] init  initializer list to create an object from (optional)
18372
18373
    @return JSON object value
18374
18375
    @throw type_error.301 if @a init is not a list of pairs whose first
18376
    elements are strings. In this case, no object can be created. When such a
18377
    value is passed to @ref basic_json(initializer_list_t, bool, value_t),
18378
    an array would have been created from the passed initializer list @a init.
18379
    See example below.
18380
18381
    @complexity Linear in the size of @a init.
18382
18383
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18384
    changes to any JSON value.
18385
18386
    @liveexample{The following code shows an example for the `object`
18387
    function.,object}
18388
18389
    @sa @ref basic_json(initializer_list_t, bool, value_t) --
18390
    create a JSON value from an initializer list
18391
    @sa @ref array(initializer_list_t) -- create a JSON array
18392
    value from an initializer list
18393
18394
    @since version 1.0.0
18395
    */
18396
    JSON_HEDLEY_WARN_UNUSED_RESULT
18397
    static basic_json object(initializer_list_t init = {})
18398
    {
18399
        return basic_json(init, false, value_t::object);
18400
    }
18401
18402
    /*!
18403
    @brief construct an array with count copies of given value
18404
18405
    Constructs a JSON array value by creating @a cnt copies of a passed value.
18406
    In case @a cnt is `0`, an empty array is created.
18407
18408
    @param[in] cnt  the number of JSON copies of @a val to create
18409
    @param[in] val  the JSON value to copy
18410
18411
    @post `std::distance(begin(),end()) == cnt` holds.
18412
18413
    @complexity Linear in @a cnt.
18414
18415
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18416
    changes to any JSON value.
18417
18418
    @liveexample{The following code shows examples for the @ref
18419
    basic_json(size_type\, const basic_json&)
18420
    constructor.,basic_json__size_type_basic_json}
18421
18422
    @since version 1.0.0
18423
    */
18424
    basic_json(size_type cnt, const basic_json& val)
18425
        : m_type(value_t::array)
18426
    {
18427
        m_value.array = create<array_t>(cnt, val);
18428
        assert_invariant();
18429
    }
18430
18431
    /*!
18432
    @brief construct a JSON container given an iterator range
18433
18434
    Constructs the JSON value with the contents of the range `[first, last)`.
18435
    The semantics depends on the different types a JSON value can have:
18436
    - In case of a null type, invalid_iterator.206 is thrown.
18437
    - In case of other primitive types (number, boolean, or string), @a first
18438
      must be `begin()` and @a last must be `end()`. In this case, the value is
18439
      copied. Otherwise, invalid_iterator.204 is thrown.
18440
    - In case of structured types (array, object), the constructor behaves as
18441
      similar versions for `std::vector` or `std::map`; that is, a JSON array
18442
      or object is constructed from the values in the range.
18443
18444
    @tparam InputIT an input iterator type (@ref iterator or @ref
18445
    const_iterator)
18446
18447
    @param[in] first begin of the range to copy from (included)
18448
    @param[in] last end of the range to copy from (excluded)
18449
18450
    @pre Iterators @a first and @a last must be initialized. **This
18451
         precondition is enforced with an assertion (see warning).** If
18452
         assertions are switched off, a violation of this precondition yields
18453
         undefined behavior.
18454
18455
    @pre Range `[first, last)` is valid. Usually, this precondition cannot be
18456
         checked efficiently. Only certain edge cases are detected; see the
18457
         description of the exceptions below. A violation of this precondition
18458
         yields undefined behavior.
18459
18460
    @warning A precondition is enforced with a runtime assertion that will
18461
             result in calling `std::abort` if this precondition is not met.
18462
             Assertions can be disabled by defining `NDEBUG` at compile time.
18463
             See https://en.cppreference.com/w/cpp/error/assert for more
18464
             information.
18465
18466
    @throw invalid_iterator.201 if iterators @a first and @a last are not
18467
    compatible (i.e., do not belong to the same JSON value). In this case,
18468
    the range `[first, last)` is undefined.
18469
    @throw invalid_iterator.204 if iterators @a first and @a last belong to a
18470
    primitive type (number, boolean, or string), but @a first does not point
18471
    to the first element any more. In this case, the range `[first, last)` is
18472
    undefined. See example code below.
18473
    @throw invalid_iterator.206 if iterators @a first and @a last belong to a
18474
    null value. In this case, the range `[first, last)` is undefined.
18475
18476
    @complexity Linear in distance between @a first and @a last.
18477
18478
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18479
    changes to any JSON value.
18480
18481
    @liveexample{The example below shows several ways to create JSON values by
18482
    specifying a subrange with iterators.,basic_json__InputIt_InputIt}
18483
18484
    @since version 1.0.0
18485
    */
18486
    template < class InputIT, typename std::enable_if <
18487
                   std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18488
                   std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
18489
    basic_json(InputIT first, InputIT last)
18490
    {
18491
        JSON_ASSERT(first.m_object != nullptr);
18492
        JSON_ASSERT(last.m_object != nullptr);
18493
18494
        // make sure iterator fits the current value
18495
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18496
        {
18497
            JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18498
        }
18499
18500
        // copy type from first iterator
18501
        m_type = first.m_object->m_type;
18502
18503
        // check if iterator range is complete for primitive values
18504
        switch (m_type)
18505
        {
18506
            case value_t::boolean:
18507
            case value_t::number_float:
18508
            case value_t::number_integer:
18509
            case value_t::number_unsigned:
18510
            case value_t::string:
18511
            {
18512
                if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18513
                                         || !last.m_it.primitive_iterator.is_end()))
18514
                {
18515
                    JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18516
                }
18517
                break;
18518
            }
18519
18520
            default:
18521
                break;
18522
        }
18523
18524
        switch (m_type)
18525
        {
18526
            case value_t::number_integer:
18527
            {
18528
                m_value.number_integer = first.m_object->m_value.number_integer;
18529
                break;
18530
            }
18531
18532
            case value_t::number_unsigned:
18533
            {
18534
                m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18535
                break;
18536
            }
18537
18538
            case value_t::number_float:
18539
            {
18540
                m_value.number_float = first.m_object->m_value.number_float;
18541
                break;
18542
            }
18543
18544
            case value_t::boolean:
18545
            {
18546
                m_value.boolean = first.m_object->m_value.boolean;
18547
                break;
18548
            }
18549
18550
            case value_t::string:
18551
            {
18552
                m_value = *first.m_object->m_value.string;
18553
                break;
18554
            }
18555
18556
            case value_t::object:
18557
            {
18558
                m_value.object = create<object_t>(first.m_it.object_iterator,
18559
                                                  last.m_it.object_iterator);
18560
                break;
18561
            }
18562
18563
            case value_t::array:
18564
            {
18565
                m_value.array = create<array_t>(first.m_it.array_iterator,
18566
                                                last.m_it.array_iterator);
18567
                break;
18568
            }
18569
18570
            case value_t::binary:
18571
            {
18572
                m_value = *first.m_object->m_value.binary;
18573
                break;
18574
            }
18575
18576
            default:
18577
                JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18578
                                                    std::string(first.m_object->type_name())));
18579
        }
18580
18581
        assert_invariant();
18582
    }
18583
18584
18585
    ///////////////////////////////////////
18586
    // other constructors and destructor //
18587
    ///////////////////////////////////////
18588
18589
    template<typename JsonRef,
18590
             detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
18591
                                 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
18592
0
    basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18593
18594
    /*!
18595
    @brief copy constructor
18596
18597
    Creates a copy of a given JSON value.
18598
18599
    @param[in] other  the JSON value to copy
18600
18601
    @post `*this == other`
18602
18603
    @complexity Linear in the size of @a other.
18604
18605
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18606
    changes to any JSON value.
18607
18608
    @requirement This function helps `basic_json` satisfying the
18609
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18610
    requirements:
18611
    - The complexity is linear.
18612
    - As postcondition, it holds: `other == basic_json(other)`.
18613
18614
    @liveexample{The following code shows an example for the copy
18615
    constructor.,basic_json__basic_json}
18616
18617
    @since version 1.0.0
18618
    */
18619
    basic_json(const basic_json& other)
18620
        : m_type(other.m_type)
18621
0
    {
18622
        // check of passed value is valid
18623
0
        other.assert_invariant();
18624
18625
0
        switch (m_type)
18626
0
        {
18627
0
            case value_t::object:
18628
0
            {
18629
0
                m_value = *other.m_value.object;
18630
0
                break;
18631
0
            }
18632
18633
0
            case value_t::array:
18634
0
            {
18635
0
                m_value = *other.m_value.array;
18636
0
                break;
18637
0
            }
18638
18639
0
            case value_t::string:
18640
0
            {
18641
0
                m_value = *other.m_value.string;
18642
0
                break;
18643
0
            }
18644
18645
0
            case value_t::boolean:
18646
0
            {
18647
0
                m_value = other.m_value.boolean;
18648
0
                break;
18649
0
            }
18650
18651
0
            case value_t::number_integer:
18652
0
            {
18653
0
                m_value = other.m_value.number_integer;
18654
0
                break;
18655
0
            }
18656
18657
0
            case value_t::number_unsigned:
18658
0
            {
18659
0
                m_value = other.m_value.number_unsigned;
18660
0
                break;
18661
0
            }
18662
18663
0
            case value_t::number_float:
18664
0
            {
18665
0
                m_value = other.m_value.number_float;
18666
0
                break;
18667
0
            }
18668
18669
0
            case value_t::binary:
18670
0
            {
18671
0
                m_value = *other.m_value.binary;
18672
0
                break;
18673
0
            }
18674
18675
0
            default:
18676
0
                break;
18677
0
        }
18678
18679
0
        assert_invariant();
18680
0
    }
18681
18682
    /*!
18683
    @brief move constructor
18684
18685
    Move constructor. Constructs a JSON value with the contents of the given
18686
    value @a other using move semantics. It "steals" the resources from @a
18687
    other and leaves it as JSON null value.
18688
18689
    @param[in,out] other  value to move to this object
18690
18691
    @post `*this` has the same value as @a other before the call.
18692
    @post @a other is a JSON null value.
18693
18694
    @complexity Constant.
18695
18696
    @exceptionsafety No-throw guarantee: this constructor never throws
18697
    exceptions.
18698
18699
    @requirement This function helps `basic_json` satisfying the
18700
    [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
18701
    requirements.
18702
18703
    @liveexample{The code below shows the move constructor explicitly called
18704
    via std::move.,basic_json__moveconstructor}
18705
18706
    @since version 1.0.0
18707
    */
18708
    basic_json(basic_json&& other) noexcept
18709
        : m_type(std::move(other.m_type)),
18710
          m_value(std::move(other.m_value))
18711
0
    {
18712
        // check that passed value is valid
18713
0
        other.assert_invariant();
18714
18715
        // invalidate payload
18716
0
        other.m_type = value_t::null;
18717
0
        other.m_value = {};
18718
18719
0
        assert_invariant();
18720
0
    }
18721
18722
    /*!
18723
    @brief copy assignment
18724
18725
    Copy assignment operator. Copies a JSON value via the "copy and swap"
18726
    strategy: It is expressed in terms of the copy constructor, destructor,
18727
    and the `swap()` member function.
18728
18729
    @param[in] other  value to copy from
18730
18731
    @complexity Linear.
18732
18733
    @requirement This function helps `basic_json` satisfying the
18734
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18735
    requirements:
18736
    - The complexity is linear.
18737
18738
    @liveexample{The code below shows and example for the copy assignment. It
18739
    creates a copy of value `a` which is then swapped with `b`. Finally\, the
18740
    copy of `a` (which is the null value after the swap) is
18741
    destroyed.,basic_json__copyassignment}
18742
18743
    @since version 1.0.0
18744
    */
18745
    basic_json& operator=(basic_json other) noexcept (
18746
        std::is_nothrow_move_constructible<value_t>::value&&
18747
        std::is_nothrow_move_assignable<value_t>::value&&
18748
        std::is_nothrow_move_constructible<json_value>::value&&
18749
        std::is_nothrow_move_assignable<json_value>::value
18750
    )
18751
0
    {
18752
        // check that passed value is valid
18753
0
        other.assert_invariant();
18754
18755
0
        using std::swap;
18756
0
        swap(m_type, other.m_type);
18757
0
        swap(m_value, other.m_value);
18758
18759
0
        assert_invariant();
18760
0
        return *this;
18761
0
    }
18762
18763
    /*!
18764
    @brief destructor
18765
18766
    Destroys the JSON value and frees all allocated memory.
18767
18768
    @complexity Linear.
18769
18770
    @requirement This function helps `basic_json` satisfying the
18771
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18772
    requirements:
18773
    - The complexity is linear.
18774
    - All stored elements are destroyed and all memory is freed.
18775
18776
    @since version 1.0.0
18777
    */
18778
    ~basic_json() noexcept
18779
0
    {
18780
0
        assert_invariant();
18781
0
        m_value.destroy(m_type);
18782
0
    }
18783
18784
    /// @}
18785
18786
  public:
18787
    ///////////////////////
18788
    // object inspection //
18789
    ///////////////////////
18790
18791
    /// @name object inspection
18792
    /// Functions to inspect the type of a JSON value.
18793
    /// @{
18794
18795
    /*!
18796
    @brief serialization
18797
18798
    Serialization function for JSON values. The function tries to mimic
18799
    Python's `json.dumps()` function, and currently supports its @a indent
18800
    and @a ensure_ascii parameters.
18801
18802
    @param[in] indent If indent is nonnegative, then array elements and object
18803
    members will be pretty-printed with that indent level. An indent level of
18804
    `0` will only insert newlines. `-1` (the default) selects the most compact
18805
    representation.
18806
    @param[in] indent_char The character to use for indentation if @a indent is
18807
    greater than `0`. The default is ` ` (space).
18808
    @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
18809
    in the output are escaped with `\uXXXX` sequences, and the result consists
18810
    of ASCII characters only.
18811
    @param[in] error_handler  how to react on decoding errors; there are three
18812
    possible values: `strict` (throws and exception in case a decoding error
18813
    occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
18814
    and `ignore` (ignore invalid UTF-8 sequences during serialization; all
18815
    bytes are copied to the output unchanged).
18816
18817
    @return string containing the serialization of the JSON value
18818
18819
    @throw type_error.316 if a string stored inside the JSON value is not
18820
                          UTF-8 encoded and @a error_handler is set to strict
18821
18822
    @note Binary values are serialized as object containing two keys:
18823
      - "bytes": an array of bytes as integers
18824
      - "subtype": the subtype as integer or "null" if the binary has no subtype
18825
18826
    @complexity Linear.
18827
18828
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18829
    changes in the JSON value.
18830
18831
    @liveexample{The following example shows the effect of different @a indent\,
18832
    @a indent_char\, and @a ensure_ascii parameters to the result of the
18833
    serialization.,dump}
18834
18835
    @see https://docs.python.org/2/library/json.html#json.dump
18836
18837
    @since version 1.0.0; indentation character @a indent_char, option
18838
           @a ensure_ascii and exceptions added in version 3.0.0; error
18839
           handlers added in version 3.4.0; serialization of binary values added
18840
           in version 3.8.0.
18841
    */
18842
    string_t dump(const int indent = -1,
18843
                  const char indent_char = ' ',
18844
                  const bool ensure_ascii = false,
18845
                  const error_handler_t error_handler = error_handler_t::strict) const
18846
    {
18847
        string_t result;
18848
        serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18849
18850
        if (indent >= 0)
18851
        {
18852
            s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18853
        }
18854
        else
18855
        {
18856
            s.dump(*this, false, ensure_ascii, 0);
18857
        }
18858
18859
        return result;
18860
    }
18861
18862
    /*!
18863
    @brief return the type of the JSON value (explicit)
18864
18865
    Return the type of the JSON value as a value from the @ref value_t
18866
    enumeration.
18867
18868
    @return the type of the JSON value
18869
            Value type                | return value
18870
            ------------------------- | -------------------------
18871
            null                      | value_t::null
18872
            boolean                   | value_t::boolean
18873
            string                    | value_t::string
18874
            number (integer)          | value_t::number_integer
18875
            number (unsigned integer) | value_t::number_unsigned
18876
            number (floating-point)   | value_t::number_float
18877
            object                    | value_t::object
18878
            array                     | value_t::array
18879
            binary                    | value_t::binary
18880
            discarded                 | value_t::discarded
18881
18882
    @complexity Constant.
18883
18884
    @exceptionsafety No-throw guarantee: this member function never throws
18885
    exceptions.
18886
18887
    @liveexample{The following code exemplifies `type()` for all JSON
18888
    types.,type}
18889
18890
    @sa @ref operator value_t() -- return the type of the JSON value (implicit)
18891
    @sa @ref type_name() -- return the type as string
18892
18893
    @since version 1.0.0
18894
    */
18895
    constexpr value_t type() const noexcept
18896
0
    {
18897
0
        return m_type;
18898
0
    }
18899
18900
    /*!
18901
    @brief return whether type is primitive
18902
18903
    This function returns true if and only if the JSON type is primitive
18904
    (string, number, boolean, or null).
18905
18906
    @return `true` if type is primitive (string, number, boolean, or null),
18907
    `false` otherwise.
18908
18909
    @complexity Constant.
18910
18911
    @exceptionsafety No-throw guarantee: this member function never throws
18912
    exceptions.
18913
18914
    @liveexample{The following code exemplifies `is_primitive()` for all JSON
18915
    types.,is_primitive}
18916
18917
    @sa @ref is_structured() -- returns whether JSON value is structured
18918
    @sa @ref is_null() -- returns whether JSON value is `null`
18919
    @sa @ref is_string() -- returns whether JSON value is a string
18920
    @sa @ref is_boolean() -- returns whether JSON value is a boolean
18921
    @sa @ref is_number() -- returns whether JSON value is a number
18922
    @sa @ref is_binary() -- returns whether JSON value is a binary array
18923
18924
    @since version 1.0.0
18925
    */
18926
    constexpr bool is_primitive() const noexcept
18927
    {
18928
        return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18929
    }
18930
18931
    /*!
18932
    @brief return whether type is structured
18933
18934
    This function returns true if and only if the JSON type is structured
18935
    (array or object).
18936
18937
    @return `true` if type is structured (array or object), `false` otherwise.
18938
18939
    @complexity Constant.
18940
18941
    @exceptionsafety No-throw guarantee: this member function never throws
18942
    exceptions.
18943
18944
    @liveexample{The following code exemplifies `is_structured()` for all JSON
18945
    types.,is_structured}
18946
18947
    @sa @ref is_primitive() -- returns whether value is primitive
18948
    @sa @ref is_array() -- returns whether value is an array
18949
    @sa @ref is_object() -- returns whether value is an object
18950
18951
    @since version 1.0.0
18952
    */
18953
    constexpr bool is_structured() const noexcept
18954
0
    {
18955
0
        return is_array() || is_object();
18956
0
    }
18957
18958
    /*!
18959
    @brief return whether value is null
18960
18961
    This function returns true if and only if the JSON value is null.
18962
18963
    @return `true` if type is null, `false` otherwise.
18964
18965
    @complexity Constant.
18966
18967
    @exceptionsafety No-throw guarantee: this member function never throws
18968
    exceptions.
18969
18970
    @liveexample{The following code exemplifies `is_null()` for all JSON
18971
    types.,is_null}
18972
18973
    @since version 1.0.0
18974
    */
18975
    constexpr bool is_null() const noexcept
18976
0
    {
18977
0
        return m_type == value_t::null;
18978
0
    }
18979
18980
    /*!
18981
    @brief return whether value is a boolean
18982
18983
    This function returns true if and only if the JSON value is a boolean.
18984
18985
    @return `true` if type is boolean, `false` otherwise.
18986
18987
    @complexity Constant.
18988
18989
    @exceptionsafety No-throw guarantee: this member function never throws
18990
    exceptions.
18991
18992
    @liveexample{The following code exemplifies `is_boolean()` for all JSON
18993
    types.,is_boolean}
18994
18995
    @since version 1.0.0
18996
    */
18997
    constexpr bool is_boolean() const noexcept
18998
0
    {
18999
0
        return m_type == value_t::boolean;
19000
0
    }
19001
19002
    /*!
19003
    @brief return whether value is a number
19004
19005
    This function returns true if and only if the JSON value is a number. This
19006
    includes both integer (signed and unsigned) and floating-point values.
19007
19008
    @return `true` if type is number (regardless whether integer, unsigned
19009
    integer or floating-type), `false` otherwise.
19010
19011
    @complexity Constant.
19012
19013
    @exceptionsafety No-throw guarantee: this member function never throws
19014
    exceptions.
19015
19016
    @liveexample{The following code exemplifies `is_number()` for all JSON
19017
    types.,is_number}
19018
19019
    @sa @ref is_number_integer() -- check if value is an integer or unsigned
19020
    integer number
19021
    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
19022
    number
19023
    @sa @ref is_number_float() -- check if value is a floating-point number
19024
19025
    @since version 1.0.0
19026
    */
19027
    constexpr bool is_number() const noexcept
19028
    {
19029
        return is_number_integer() || is_number_float();
19030
    }
19031
19032
    /*!
19033
    @brief return whether value is an integer number
19034
19035
    This function returns true if and only if the JSON value is a signed or
19036
    unsigned integer number. This excludes floating-point values.
19037
19038
    @return `true` if type is an integer or unsigned integer number, `false`
19039
    otherwise.
19040
19041
    @complexity Constant.
19042
19043
    @exceptionsafety No-throw guarantee: this member function never throws
19044
    exceptions.
19045
19046
    @liveexample{The following code exemplifies `is_number_integer()` for all
19047
    JSON types.,is_number_integer}
19048
19049
    @sa @ref is_number() -- check if value is a number
19050
    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
19051
    number
19052
    @sa @ref is_number_float() -- check if value is a floating-point number
19053
19054
    @since version 1.0.0
19055
    */
19056
    constexpr bool is_number_integer() const noexcept
19057
0
    {
19058
0
        return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19059
0
    }
19060
19061
    /*!
19062
    @brief return whether value is an unsigned integer number
19063
19064
    This function returns true if and only if the JSON value is an unsigned
19065
    integer number. This excludes floating-point and signed integer values.
19066
19067
    @return `true` if type is an unsigned integer number, `false` otherwise.
19068
19069
    @complexity Constant.
19070
19071
    @exceptionsafety No-throw guarantee: this member function never throws
19072
    exceptions.
19073
19074
    @liveexample{The following code exemplifies `is_number_unsigned()` for all
19075
    JSON types.,is_number_unsigned}
19076
19077
    @sa @ref is_number() -- check if value is a number
19078
    @sa @ref is_number_integer() -- check if value is an integer or unsigned
19079
    integer number
19080
    @sa @ref is_number_float() -- check if value is a floating-point number
19081
19082
    @since version 2.0.0
19083
    */
19084
    constexpr bool is_number_unsigned() const noexcept
19085
0
    {
19086
0
        return m_type == value_t::number_unsigned;
19087
0
    }
19088
19089
    /*!
19090
    @brief return whether value is a floating-point number
19091
19092
    This function returns true if and only if the JSON value is a
19093
    floating-point number. This excludes signed and unsigned integer values.
19094
19095
    @return `true` if type is a floating-point number, `false` otherwise.
19096
19097
    @complexity Constant.
19098
19099
    @exceptionsafety No-throw guarantee: this member function never throws
19100
    exceptions.
19101
19102
    @liveexample{The following code exemplifies `is_number_float()` for all
19103
    JSON types.,is_number_float}
19104
19105
    @sa @ref is_number() -- check if value is number
19106
    @sa @ref is_number_integer() -- check if value is an integer number
19107
    @sa @ref is_number_unsigned() -- check if value is an unsigned integer
19108
    number
19109
19110
    @since version 1.0.0
19111
    */
19112
    constexpr bool is_number_float() const noexcept
19113
0
    {
19114
0
        return m_type == value_t::number_float;
19115
0
    }
19116
19117
    /*!
19118
    @brief return whether value is an object
19119
19120
    This function returns true if and only if the JSON value is an object.
19121
19122
    @return `true` if type is object, `false` otherwise.
19123
19124
    @complexity Constant.
19125
19126
    @exceptionsafety No-throw guarantee: this member function never throws
19127
    exceptions.
19128
19129
    @liveexample{The following code exemplifies `is_object()` for all JSON
19130
    types.,is_object}
19131
19132
    @since version 1.0.0
19133
    */
19134
    constexpr bool is_object() const noexcept
19135
0
    {
19136
0
        return m_type == value_t::object;
19137
0
    }
19138
19139
    /*!
19140
    @brief return whether value is an array
19141
19142
    This function returns true if and only if the JSON value is an array.
19143
19144
    @return `true` if type is array, `false` otherwise.
19145
19146
    @complexity Constant.
19147
19148
    @exceptionsafety No-throw guarantee: this member function never throws
19149
    exceptions.
19150
19151
    @liveexample{The following code exemplifies `is_array()` for all JSON
19152
    types.,is_array}
19153
19154
    @since version 1.0.0
19155
    */
19156
    constexpr bool is_array() const noexcept
19157
0
    {
19158
0
        return m_type == value_t::array;
19159
0
    }
19160
19161
    /*!
19162
    @brief return whether value is a string
19163
19164
    This function returns true if and only if the JSON value is a string.
19165
19166
    @return `true` if type is string, `false` otherwise.
19167
19168
    @complexity Constant.
19169
19170
    @exceptionsafety No-throw guarantee: this member function never throws
19171
    exceptions.
19172
19173
    @liveexample{The following code exemplifies `is_string()` for all JSON
19174
    types.,is_string}
19175
19176
    @since version 1.0.0
19177
    */
19178
    constexpr bool is_string() const noexcept
19179
0
    {
19180
0
        return m_type == value_t::string;
19181
0
    }
19182
19183
    /*!
19184
    @brief return whether value is a binary array
19185
19186
    This function returns true if and only if the JSON value is a binary array.
19187
19188
    @return `true` if type is binary array, `false` otherwise.
19189
19190
    @complexity Constant.
19191
19192
    @exceptionsafety No-throw guarantee: this member function never throws
19193
    exceptions.
19194
19195
    @liveexample{The following code exemplifies `is_binary()` for all JSON
19196
    types.,is_binary}
19197
19198
    @since version 3.8.0
19199
    */
19200
    constexpr bool is_binary() const noexcept
19201
0
    {
19202
0
        return m_type == value_t::binary;
19203
0
    }
19204
19205
    /*!
19206
    @brief return whether value is discarded
19207
19208
    This function returns true if and only if the JSON value was discarded
19209
    during parsing with a callback function (see @ref parser_callback_t).
19210
19211
    @note This function will always be `false` for JSON values after parsing.
19212
    That is, discarded values can only occur during parsing, but will be
19213
    removed when inside a structured value or replaced by null in other cases.
19214
19215
    @return `true` if type is discarded, `false` otherwise.
19216
19217
    @complexity Constant.
19218
19219
    @exceptionsafety No-throw guarantee: this member function never throws
19220
    exceptions.
19221
19222
    @liveexample{The following code exemplifies `is_discarded()` for all JSON
19223
    types.,is_discarded}
19224
19225
    @since version 1.0.0
19226
    */
19227
    constexpr bool is_discarded() const noexcept
19228
0
    {
19229
0
        return m_type == value_t::discarded;
19230
0
    }
19231
19232
    /*!
19233
    @brief return the type of the JSON value (implicit)
19234
19235
    Implicitly return the type of the JSON value as a value from the @ref
19236
    value_t enumeration.
19237
19238
    @return the type of the JSON value
19239
19240
    @complexity Constant.
19241
19242
    @exceptionsafety No-throw guarantee: this member function never throws
19243
    exceptions.
19244
19245
    @liveexample{The following code exemplifies the @ref value_t operator for
19246
    all JSON types.,operator__value_t}
19247
19248
    @sa @ref type() -- return the type of the JSON value (explicit)
19249
    @sa @ref type_name() -- return the type as string
19250
19251
    @since version 1.0.0
19252
    */
19253
    constexpr operator value_t() const noexcept
19254
0
    {
19255
0
        return m_type;
19256
0
    }
19257
19258
    /// @}
19259
19260
  private:
19261
    //////////////////
19262
    // value access //
19263
    //////////////////
19264
19265
    /// get a boolean (explicit)
19266
    boolean_t get_impl(boolean_t* /*unused*/) const
19267
    {
19268
        if (JSON_HEDLEY_LIKELY(is_boolean()))
19269
        {
19270
            return m_value.boolean;
19271
        }
19272
19273
        JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19274
    }
19275
19276
    /// get a pointer to the value (object)
19277
    object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19278
    {
19279
        return is_object() ? m_value.object : nullptr;
19280
    }
19281
19282
    /// get a pointer to the value (object)
19283
    constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19284
    {
19285
        return is_object() ? m_value.object : nullptr;
19286
    }
19287
19288
    /// get a pointer to the value (array)
19289
    array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19290
    {
19291
        return is_array() ? m_value.array : nullptr;
19292
    }
19293
19294
    /// get a pointer to the value (array)
19295
    constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19296
    {
19297
        return is_array() ? m_value.array : nullptr;
19298
    }
19299
19300
    /// get a pointer to the value (string)
19301
    string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19302
    {
19303
        return is_string() ? m_value.string : nullptr;
19304
    }
19305
19306
    /// get a pointer to the value (string)
19307
    constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19308
0
    {
19309
0
        return is_string() ? m_value.string : nullptr;
19310
0
    }
19311
19312
    /// get a pointer to the value (boolean)
19313
    boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19314
    {
19315
        return is_boolean() ? &m_value.boolean : nullptr;
19316
    }
19317
19318
    /// get a pointer to the value (boolean)
19319
    constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19320
0
    {
19321
0
        return is_boolean() ? &m_value.boolean : nullptr;
19322
0
    }
19323
19324
    /// get a pointer to the value (integer number)
19325
    number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19326
    {
19327
        return is_number_integer() ? &m_value.number_integer : nullptr;
19328
    }
19329
19330
    /// get a pointer to the value (integer number)
19331
    constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19332
0
    {
19333
0
        return is_number_integer() ? &m_value.number_integer : nullptr;
19334
0
    }
19335
19336
    /// get a pointer to the value (unsigned number)
19337
    number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19338
    {
19339
        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19340
    }
19341
19342
    /// get a pointer to the value (unsigned number)
19343
    constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19344
0
    {
19345
0
        return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19346
0
    }
19347
19348
    /// get a pointer to the value (floating-point number)
19349
    number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19350
    {
19351
        return is_number_float() ? &m_value.number_float : nullptr;
19352
    }
19353
19354
    /// get a pointer to the value (floating-point number)
19355
    constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19356
0
    {
19357
0
        return is_number_float() ? &m_value.number_float : nullptr;
19358
0
    }
19359
19360
    /// get a pointer to the value (binary)
19361
    binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19362
    {
19363
        return is_binary() ? m_value.binary : nullptr;
19364
    }
19365
19366
    /// get a pointer to the value (binary)
19367
    constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19368
0
    {
19369
0
        return is_binary() ? m_value.binary : nullptr;
19370
0
    }
19371
19372
    /*!
19373
    @brief helper function to implement get_ref()
19374
19375
    This function helps to implement get_ref() without code duplication for
19376
    const and non-const overloads
19377
19378
    @tparam ThisType will be deduced as `basic_json` or `const basic_json`
19379
19380
    @throw type_error.303 if ReferenceType does not match underlying value
19381
    type of the current JSON
19382
    */
19383
    template<typename ReferenceType, typename ThisType>
19384
    static ReferenceType get_ref_impl(ThisType& obj)
19385
0
    {
19386
0
        // delegate the call to get_ptr<>()
19387
0
        auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19388
0
19389
0
        if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19390
0
        {
19391
0
            return *ptr;
19392
0
        }
19393
0
19394
0
        JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19395
0
    }
19396
19397
  public:
19398
    /// @name value access
19399
    /// Direct access to the stored value of a JSON value.
19400
    /// @{
19401
19402
    /*!
19403
    @brief get special-case overload
19404
19405
    This overloads avoids a lot of template boilerplate, it can be seen as the
19406
    identity method
19407
19408
    @tparam BasicJsonType == @ref basic_json
19409
19410
    @return a copy of *this
19411
19412
    @complexity Constant.
19413
19414
    @since version 2.1.0
19415
    */
19416
    template<typename BasicJsonType, detail::enable_if_t<
19417
                 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19418
                 int> = 0>
19419
    basic_json get() const
19420
    {
19421
        return *this;
19422
    }
19423
19424
    /*!
19425
    @brief get special-case overload
19426
19427
    This overloads converts the current @ref basic_json in a different
19428
    @ref basic_json type
19429
19430
    @tparam BasicJsonType == @ref basic_json
19431
19432
    @return a copy of *this, converted into @tparam BasicJsonType
19433
19434
    @complexity Depending on the implementation of the called `from_json()`
19435
                method.
19436
19437
    @since version 3.2.0
19438
    */
19439
    template < typename BasicJsonType, detail::enable_if_t <
19440
                   !std::is_same<BasicJsonType, basic_json>::value&&
19441
                   detail::is_basic_json<BasicJsonType>::value, int > = 0 >
19442
    BasicJsonType get() const
19443
    {
19444
        return *this;
19445
    }
19446
19447
    /*!
19448
    @brief get a value (explicit)
19449
19450
    Explicit type conversion between the JSON value and a compatible value
19451
    which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
19452
    and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
19453
    The value is converted by calling the @ref json_serializer<ValueType>
19454
    `from_json()` method.
19455
19456
    The function is equivalent to executing
19457
    @code {.cpp}
19458
    ValueType ret;
19459
    JSONSerializer<ValueType>::from_json(*this, ret);
19460
    return ret;
19461
    @endcode
19462
19463
    This overloads is chosen if:
19464
    - @a ValueType is not @ref basic_json,
19465
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
19466
      `void from_json(const basic_json&, ValueType&)`, and
19467
    - @ref json_serializer<ValueType> does not have a `from_json()` method of
19468
      the form `ValueType from_json(const basic_json&)`
19469
19470
    @tparam ValueTypeCV the provided value type
19471
    @tparam ValueType the returned value type
19472
19473
    @return copy of the JSON value, converted to @a ValueType
19474
19475
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
19476
19477
    @liveexample{The example below shows several conversions from JSON values
19478
    to other types. There a few things to note: (1) Floating-point numbers can
19479
    be converted to integers\, (2) A JSON array can be converted to a standard
19480
    `std::vector<short>`\, (3) A JSON object can be converted to C++
19481
    associative containers such as `std::unordered_map<std::string\,
19482
    json>`.,get__ValueType_const}
19483
19484
    @since version 2.1.0
19485
    */
19486
    template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19487
               detail::enable_if_t <
19488
                   !detail::is_basic_json<ValueType>::value &&
19489
                   detail::has_from_json<basic_json_t, ValueType>::value &&
19490
                   !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19491
                   int > = 0 >
19492
    ValueType get() const noexcept(noexcept(
19493
                                       JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19494
0
    {
19495
        // we cannot static_assert on ValueTypeCV being non-const, because
19496
        // there is support for get<const basic_json_t>(), which is why we
19497
        // still need the uncvref
19498
0
        static_assert(!std::is_reference<ValueTypeCV>::value,
19499
0
                      "get() cannot be used with reference types, you might want to use get_ref()");
19500
0
        static_assert(std::is_default_constructible<ValueType>::value,
19501
0
                      "types must be DefaultConstructible when used with get()");
19502
19503
0
        ValueType ret;
19504
0
        JSONSerializer<ValueType>::from_json(*this, ret);
19505
0
        return ret;
19506
0
    }
Unexecuted instantiation: bool nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::get<bool, bool, 0>() const
Unexecuted instantiation: 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<long, long, 0>() const
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<unsigned long, unsigned long, 0>() const
Unexecuted instantiation: double nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::get<double, double, 0>() const
Unexecuted instantiation: unsigned 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> > >::get<unsigned int, unsigned int, 0>() const
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > nlohmann::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, long, unsigned long, double, std::__1::allocator, nlohmann::adl_serializer, 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> >, 0>() const
Unexecuted instantiation: std::__1::basic_string_view<char, std::__1::char_traits<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<std::__1::basic_string_view<char, std::__1::char_traits<char> >, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 0>() const
Unexecuted instantiation: 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> > >::get<unsigned char, unsigned char, 0>() const
Unexecuted instantiation: unsigned short nlohmann::basic_json<std::__1::map, std::__1::vector, std::__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 short, unsigned short, 0>() const
19507
19508
    /*!
19509
    @brief get a value (explicit); special case
19510
19511
    Explicit type conversion between the JSON value and a compatible value
19512
    which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
19513
    and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
19514
    The value is converted by calling the @ref json_serializer<ValueType>
19515
    `from_json()` method.
19516
19517
    The function is equivalent to executing
19518
    @code {.cpp}
19519
    return JSONSerializer<ValueTypeCV>::from_json(*this);
19520
    @endcode
19521
19522
    This overloads is chosen if:
19523
    - @a ValueType is not @ref basic_json and
19524
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
19525
      `ValueType from_json(const basic_json&)`
19526
19527
    @note If @ref json_serializer<ValueType> has both overloads of
19528
    `from_json()`, this one is chosen.
19529
19530
    @tparam ValueTypeCV the provided value type
19531
    @tparam ValueType the returned value type
19532
19533
    @return copy of the JSON value, converted to @a ValueType
19534
19535
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
19536
19537
    @since version 2.1.0
19538
    */
19539
    template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19540
               detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19541
                                     detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19542
                                     int > = 0 >
19543
    ValueType get() const noexcept(noexcept(
19544
                                       JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19545
    {
19546
        static_assert(!std::is_reference<ValueTypeCV>::value,
19547
                      "get() cannot be used with reference types, you might want to use get_ref()");
19548
        return JSONSerializer<ValueType>::from_json(*this);
19549
    }
19550
19551
    /*!
19552
    @brief get a value (explicit)
19553
19554
    Explicit type conversion between the JSON value and a compatible value.
19555
    The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
19556
    `from_json()` method.
19557
19558
    The function is equivalent to executing
19559
    @code {.cpp}
19560
    ValueType v;
19561
    JSONSerializer<ValueType>::from_json(*this, v);
19562
    @endcode
19563
19564
    This overloads is chosen if:
19565
    - @a ValueType is not @ref basic_json,
19566
    - @ref json_serializer<ValueType> has a `from_json()` method of the form
19567
      `void from_json(const basic_json&, ValueType&)`, and
19568
19569
    @tparam ValueType the input parameter type.
19570
19571
    @return the input parameter, allowing chaining calls.
19572
19573
    @throw what @ref json_serializer<ValueType> `from_json()` method throws
19574
19575
    @liveexample{The example below shows several conversions from JSON values
19576
    to other types. There a few things to note: (1) Floating-point numbers can
19577
    be converted to integers\, (2) A JSON array can be converted to a standard
19578
    `std::vector<short>`\, (3) A JSON object can be converted to C++
19579
    associative containers such as `std::unordered_map<std::string\,
19580
    json>`.,get_to}
19581
19582
    @since version 3.3.0
19583
    */
19584
    template < typename ValueType,
19585
               detail::enable_if_t <
19586
                   !detail::is_basic_json<ValueType>::value&&
19587
                   detail::has_from_json<basic_json_t, ValueType>::value,
19588
                   int > = 0 >
19589
    ValueType & get_to(ValueType& v) const noexcept(noexcept(
19590
                JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19591
    {
19592
        JSONSerializer<ValueType>::from_json(*this, v);
19593
        return v;
19594
    }
19595
19596
    // specialization to allow to call get_to with a basic_json value
19597
    // see https://github.com/nlohmann/json/issues/2175
19598
    template<typename ValueType,
19599
             detail::enable_if_t <
19600
                 detail::is_basic_json<ValueType>::value,
19601
                 int> = 0>
19602
    ValueType & get_to(ValueType& v) const
19603
    {
19604
        v = *this;
19605
        return v;
19606
    }
19607
19608
    template <
19609
        typename T, std::size_t N,
19610
        typename Array = T (&)[N],
19611
        detail::enable_if_t <
19612
            detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
19613
    Array get_to(T (&v)[N]) const
19614
    noexcept(noexcept(JSONSerializer<Array>::from_json(
19615
                          std::declval<const basic_json_t&>(), v)))
19616
    {
19617
        JSONSerializer<Array>::from_json(*this, v);
19618
        return v;
19619
    }
19620
19621
19622
    /*!
19623
    @brief get a pointer value (implicit)
19624
19625
    Implicit pointer access to the internally stored JSON value. No copies are
19626
    made.
19627
19628
    @warning Writing data to the pointee of the result yields an undefined
19629
    state.
19630
19631
    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
19632
    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
19633
    @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
19634
    assertion.
19635
19636
    @return pointer to the internally stored JSON value if the requested
19637
    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
19638
19639
    @complexity Constant.
19640
19641
    @liveexample{The example below shows how pointers to internal values of a
19642
    JSON value can be requested. Note that no type conversions are made and a
19643
    `nullptr` is returned if the value and the requested pointer type does not
19644
    match.,get_ptr}
19645
19646
    @since version 1.0.0
19647
    */
19648
    template<typename PointerType, typename std::enable_if<
19649
                 std::is_pointer<PointerType>::value, int>::type = 0>
19650
    auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19651
    {
19652
        // delegate the call to get_impl_ptr<>()
19653
        return get_impl_ptr(static_cast<PointerType>(nullptr));
19654
    }
19655
19656
    /*!
19657
    @brief get a pointer value (implicit)
19658
    @copydoc get_ptr()
19659
    */
19660
    template < typename PointerType, typename std::enable_if <
19661
                   std::is_pointer<PointerType>::value&&
19662
                   std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19663
    constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19664
0
    {
19665
        // delegate the call to get_impl_ptr<>() const
19666
0
        return get_impl_ptr(static_cast<PointerType>(nullptr));
19667
0
    }
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKS9_Li0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKbLi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKmLi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKlLi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
Unexecuted instantiation: _ZNK8nlohmann10basic_jsonINSt3__13mapENS1_6vectorENS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEblmdS7_NS_14adl_serializerENS3_IhNS7_IhEEEEE7get_ptrIPKdLi0EEEDTcldtclL_ZNS1_7declvalIRKSD_EEDTcl9__declvalIT_ELi0EEEvEE12get_impl_ptrclsr3stdE7declvalISK_EEEEv
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
19668
19669
    /*!
19670
    @brief get a pointer value (explicit)
19671
19672
    Explicit pointer access to the internally stored JSON value. No copies are
19673
    made.
19674
19675
    @warning The pointer becomes invalid if the underlying JSON object
19676
    changes.
19677
19678
    @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
19679
    object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
19680
    @ref number_unsigned_t, or @ref number_float_t.
19681
19682
    @return pointer to the internally stored JSON value if the requested
19683
    pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
19684
19685
    @complexity Constant.
19686
19687
    @liveexample{The example below shows how pointers to internal values of a
19688
    JSON value can be requested. Note that no type conversions are made and a
19689
    `nullptr` is returned if the value and the requested pointer type does not
19690
    match.,get__PointerType}
19691
19692
    @sa @ref get_ptr() for explicit pointer-member access
19693
19694
    @since version 1.0.0
19695
    */
19696
    template<typename PointerType, typename std::enable_if<
19697
                 std::is_pointer<PointerType>::value, int>::type = 0>
19698
    auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19699
    {
19700
        // delegate the call to get_ptr
19701
        return get_ptr<PointerType>();
19702
    }
19703
19704
    /*!
19705
    @brief get a pointer value (explicit)
19706
    @copydoc get()
19707
    */
19708
    template<typename PointerType, typename std::enable_if<
19709
                 std::is_pointer<PointerType>::value, int>::type = 0>
19710
    constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19711
    {
19712
        // delegate the call to get_ptr
19713
        return get_ptr<PointerType>();
19714
    }
19715
19716
    /*!
19717
    @brief get a reference value (implicit)
19718
19719
    Implicit reference access to the internally stored JSON value. No copies
19720
    are made.
19721
19722
    @warning Writing data to the referee of the result yields an undefined
19723
    state.
19724
19725
    @tparam ReferenceType reference type; must be a reference to @ref array_t,
19726
    @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
19727
    @ref number_float_t. Enforced by static assertion.
19728
19729
    @return reference to the internally stored JSON value if the requested
19730
    reference type @a ReferenceType fits to the JSON value; throws
19731
    type_error.303 otherwise
19732
19733
    @throw type_error.303 in case passed type @a ReferenceType is incompatible
19734
    with the stored JSON value; see example below
19735
19736
    @complexity Constant.
19737
19738
    @liveexample{The example shows several calls to `get_ref()`.,get_ref}
19739
19740
    @since version 1.1.0
19741
    */
19742
    template<typename ReferenceType, typename std::enable_if<
19743
                 std::is_reference<ReferenceType>::value, int>::type = 0>
19744
    ReferenceType get_ref()
19745
    {
19746
        // delegate call to get_ref_impl
19747
        return get_ref_impl<ReferenceType>(*this);
19748
    }
19749
19750
    /*!
19751
    @brief get a reference value (implicit)
19752
    @copydoc get_ref()
19753
    */
19754
    template < typename ReferenceType, typename std::enable_if <
19755
                   std::is_reference<ReferenceType>::value&&
19756
                   std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19757
    ReferenceType get_ref() const
19758
0
    {
19759
0
        // delegate call to get_ref_impl
19760
0
        return get_ref_impl<ReferenceType>(*this);
19761
0
    }
19762
19763
    /*!
19764
    @brief get a value (implicit)
19765
19766
    Implicit type conversion between the JSON value and a compatible value.
19767
    The call is realized by calling @ref get() const.
19768
19769
    @tparam ValueType non-pointer type compatible to the JSON value, for
19770
    instance `int` for JSON integer numbers, `bool` for JSON booleans, or
19771
    `std::vector` types for JSON arrays. The character type of @ref string_t
19772
    as well as an initializer list of this type is excluded to avoid
19773
    ambiguities as these types implicitly convert to `std::string`.
19774
19775
    @return copy of the JSON value, converted to type @a ValueType
19776
19777
    @throw type_error.302 in case passed type @a ValueType is incompatible
19778
    to the JSON value type (e.g., the JSON value is of type boolean, but a
19779
    string is requested); see example below
19780
19781
    @complexity Linear in the size of the JSON value.
19782
19783
    @liveexample{The example below shows several conversions from JSON values
19784
    to other types. There a few things to note: (1) Floating-point numbers can
19785
    be converted to integers\, (2) A JSON array can be converted to a standard
19786
    `std::vector<short>`\, (3) A JSON object can be converted to C++
19787
    associative containers such as `std::unordered_map<std::string\,
19788
    json>`.,operator__ValueType}
19789
19790
    @since version 1.0.0
19791
    */
19792
    template < typename ValueType, typename std::enable_if <
19793
                   !std::is_pointer<ValueType>::value&&
19794
                   !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19795
                   !std::is_same<ValueType, typename string_t::value_type>::value&&
19796
                   !detail::is_basic_json<ValueType>::value
19797
                   && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19798
#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19799
                   && !std::is_same<ValueType, typename std::string_view>::value
19800
#endif
19801
                   && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19802
                   , int >::type = 0 >
19803
    JSON_EXPLICIT operator ValueType() const
19804
0
    {
19805
        // delegate the call to get<>() const
19806
0
        return get<ValueType>();
19807
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> > >::operator std::__1::basic_string_view<char, std::__1::char_traits<char> ><std::__1::basic_string_view<char, std::__1::char_traits<char> >, 0>() 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> > >::operator unsigned short<unsigned short, 0>() 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> > >::operator unsigned int<unsigned int, 0>() const
19808
19809
    /*!
19810
    @return reference to the binary value
19811
19812
    @throw type_error.302 if the value is not binary
19813
19814
    @sa @ref is_binary() to check if the value is binary
19815
19816
    @since version 3.8.0
19817
    */
19818
    binary_t& get_binary()
19819
    {
19820
        if (!is_binary())
19821
        {
19822
            JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19823
        }
19824
19825
        return *get_ptr<binary_t*>();
19826
    }
19827
19828
    /// @copydoc get_binary()
19829
    const binary_t& get_binary() const
19830
0
    {
19831
0
        if (!is_binary())
19832
0
        {
19833
0
            JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19834
0
        }
19835
0
19836
0
        return *get_ptr<const binary_t*>();
19837
0
    }
19838
19839
    /// @}
19840
19841
19842
    ////////////////////
19843
    // element access //
19844
    ////////////////////
19845
19846
    /// @name element access
19847
    /// Access to the JSON value.
19848
    /// @{
19849
19850
    /*!
19851
    @brief access specified array element with bounds checking
19852
19853
    Returns a reference to the element at specified location @a idx, with
19854
    bounds checking.
19855
19856
    @param[in] idx  index of the element to access
19857
19858
    @return reference to the element at index @a idx
19859
19860
    @throw type_error.304 if the JSON value is not an array; in this case,
19861
    calling `at` with an index makes no sense. See example below.
19862
    @throw out_of_range.401 if the index @a idx is out of range of the array;
19863
    that is, `idx >= size()`. See example below.
19864
19865
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19866
    changes in the JSON value.
19867
19868
    @complexity Constant.
19869
19870
    @since version 1.0.0
19871
19872
    @liveexample{The example below shows how array elements can be read and
19873
    written using `at()`. It also demonstrates the different exceptions that
19874
    can be thrown.,at__size_type}
19875
    */
19876
    reference at(size_type idx)
19877
    {
19878
        // at only works for arrays
19879
        if (JSON_HEDLEY_LIKELY(is_array()))
19880
        {
19881
            JSON_TRY
19882
            {
19883
                return m_value.array->at(idx);
19884
            }
19885
            JSON_CATCH (std::out_of_range&)
19886
            {
19887
                // create better exception explanation
19888
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19889
            }
19890
        }
19891
        else
19892
        {
19893
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19894
        }
19895
    }
19896
19897
    /*!
19898
    @brief access specified array element with bounds checking
19899
19900
    Returns a const reference to the element at specified location @a idx,
19901
    with bounds checking.
19902
19903
    @param[in] idx  index of the element to access
19904
19905
    @return const reference to the element at index @a idx
19906
19907
    @throw type_error.304 if the JSON value is not an array; in this case,
19908
    calling `at` with an index makes no sense. See example below.
19909
    @throw out_of_range.401 if the index @a idx is out of range of the array;
19910
    that is, `idx >= size()`. See example below.
19911
19912
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19913
    changes in the JSON value.
19914
19915
    @complexity Constant.
19916
19917
    @since version 1.0.0
19918
19919
    @liveexample{The example below shows how array elements can be read using
19920
    `at()`. It also demonstrates the different exceptions that can be thrown.,
19921
    at__size_type_const}
19922
    */
19923
    const_reference at(size_type idx) const
19924
    {
19925
        // at only works for arrays
19926
        if (JSON_HEDLEY_LIKELY(is_array()))
19927
        {
19928
            JSON_TRY
19929
            {
19930
                return m_value.array->at(idx);
19931
            }
19932
            JSON_CATCH (std::out_of_range&)
19933
            {
19934
                // create better exception explanation
19935
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19936
            }
19937
        }
19938
        else
19939
        {
19940
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19941
        }
19942
    }
19943
19944
    /*!
19945
    @brief access specified object element with bounds checking
19946
19947
    Returns a reference to the element at with specified key @a key, with
19948
    bounds checking.
19949
19950
    @param[in] key  key of the element to access
19951
19952
    @return reference to the element at key @a key
19953
19954
    @throw type_error.304 if the JSON value is not an object; in this case,
19955
    calling `at` with a key makes no sense. See example below.
19956
    @throw out_of_range.403 if the key @a key is is not stored in the object;
19957
    that is, `find(key) == end()`. See example below.
19958
19959
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19960
    changes in the JSON value.
19961
19962
    @complexity Logarithmic in the size of the container.
19963
19964
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
19965
    access by reference
19966
    @sa @ref value() for access by value with a default value
19967
19968
    @since version 1.0.0
19969
19970
    @liveexample{The example below shows how object elements can be read and
19971
    written using `at()`. It also demonstrates the different exceptions that
19972
    can be thrown.,at__object_t_key_type}
19973
    */
19974
    reference at(const typename object_t::key_type& key)
19975
0
    {
19976
        // at only works for objects
19977
0
        if (JSON_HEDLEY_LIKELY(is_object()))
19978
0
        {
19979
0
            JSON_TRY
19980
0
            {
19981
0
                return m_value.object->at(key);
19982
0
            }
19983
0
            JSON_CATCH (std::out_of_range&)
19984
0
            {
19985
                // create better exception explanation
19986
0
                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19987
0
            }
19988
0
        }
19989
0
        else
19990
0
        {
19991
0
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19992
0
        }
19993
0
    }
19994
19995
    /*!
19996
    @brief access specified object element with bounds checking
19997
19998
    Returns a const reference to the element at with specified key @a key,
19999
    with bounds checking.
20000
20001
    @param[in] key  key of the element to access
20002
20003
    @return const reference to the element at key @a key
20004
20005
    @throw type_error.304 if the JSON value is not an object; in this case,
20006
    calling `at` with a key makes no sense. See example below.
20007
    @throw out_of_range.403 if the key @a key is is not stored in the object;
20008
    that is, `find(key) == end()`. See example below.
20009
20010
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20011
    changes in the JSON value.
20012
20013
    @complexity Logarithmic in the size of the container.
20014
20015
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
20016
    access by reference
20017
    @sa @ref value() for access by value with a default value
20018
20019
    @since version 1.0.0
20020
20021
    @liveexample{The example below shows how object elements can be read using
20022
    `at()`. It also demonstrates the different exceptions that can be thrown.,
20023
    at__object_t_key_type_const}
20024
    */
20025
    const_reference at(const typename object_t::key_type& key) const
20026
    {
20027
        // at only works for objects
20028
        if (JSON_HEDLEY_LIKELY(is_object()))
20029
        {
20030
            JSON_TRY
20031
            {
20032
                return m_value.object->at(key);
20033
            }
20034
            JSON_CATCH (std::out_of_range&)
20035
            {
20036
                // create better exception explanation
20037
                JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
20038
            }
20039
        }
20040
        else
20041
        {
20042
            JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
20043
        }
20044
    }
20045
20046
    /*!
20047
    @brief access specified array element
20048
20049
    Returns a reference to the element at specified location @a idx.
20050
20051
    @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
20052
    then the array is silently filled up with `null` values to make `idx` a
20053
    valid reference to the last stored element.
20054
20055
    @param[in] idx  index of the element to access
20056
20057
    @return reference to the element at index @a idx
20058
20059
    @throw type_error.305 if the JSON value is not an array or null; in that
20060
    cases, using the [] operator with an index makes no sense.
20061
20062
    @complexity Constant if @a idx is in the range of the array. Otherwise
20063
    linear in `idx - size()`.
20064
20065
    @liveexample{The example below shows how array elements can be read and
20066
    written using `[]` operator. Note the addition of `null`
20067
    values.,operatorarray__size_type}
20068
20069
    @since version 1.0.0
20070
    */
20071
    reference operator[](size_type idx)
20072
    {
20073
        // implicitly convert null value to an empty array
20074
        if (is_null())
20075
        {
20076
            m_type = value_t::array;
20077
            m_value.array = create<array_t>();
20078
            assert_invariant();
20079
        }
20080
20081
        // operator[] only works for arrays
20082
        if (JSON_HEDLEY_LIKELY(is_array()))
20083
        {
20084
            // fill up array with null values if given idx is outside range
20085
            if (idx >= m_value.array->size())
20086
            {
20087
                m_value.array->insert(m_value.array->end(),
20088
                                      idx - m_value.array->size() + 1,
20089
                                      basic_json());
20090
            }
20091
20092
            return m_value.array->operator[](idx);
20093
        }
20094
20095
        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20096
    }
20097
20098
    /*!
20099
    @brief access specified array element
20100
20101
    Returns a const reference to the element at specified location @a idx.
20102
20103
    @param[in] idx  index of the element to access
20104
20105
    @return const reference to the element at index @a idx
20106
20107
    @throw type_error.305 if the JSON value is not an array; in that case,
20108
    using the [] operator with an index makes no sense.
20109
20110
    @complexity Constant.
20111
20112
    @liveexample{The example below shows how array elements can be read using
20113
    the `[]` operator.,operatorarray__size_type_const}
20114
20115
    @since version 1.0.0
20116
    */
20117
    const_reference operator[](size_type idx) const
20118
0
    {
20119
        // const operator[] only works for arrays
20120
0
        if (JSON_HEDLEY_LIKELY(is_array()))
20121
0
        {
20122
0
            return m_value.array->operator[](idx);
20123
0
        }
20124
20125
0
        JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20126
0
    }
20127
20128
    /*!
20129
    @brief access specified object element
20130
20131
    Returns a reference to the element at with specified key @a key.
20132
20133
    @note If @a key is not found in the object, then it is silently added to
20134
    the object and filled with a `null` value to make `key` a valid reference.
20135
    In case the value was `null` before, it is converted to an object.
20136
20137
    @param[in] key  key of the element to access
20138
20139
    @return reference to the element at key @a key
20140
20141
    @throw type_error.305 if the JSON value is not an object or null; in that
20142
    cases, using the [] operator with a key makes no sense.
20143
20144
    @complexity Logarithmic in the size of the container.
20145
20146
    @liveexample{The example below shows how object elements can be read and
20147
    written using the `[]` operator.,operatorarray__key_type}
20148
20149
    @sa @ref at(const typename object_t::key_type&) for access by reference
20150
    with range checking
20151
    @sa @ref value() for access by value with a default value
20152
20153
    @since version 1.0.0
20154
    */
20155
    reference operator[](const typename object_t::key_type& key)
20156
0
    {
20157
        // implicitly convert null value to an empty object
20158
0
        if (is_null())
20159
0
        {
20160
0
            m_type = value_t::object;
20161
0
            m_value.object = create<object_t>();
20162
0
            assert_invariant();
20163
0
        }
20164
20165
        // operator[] only works for objects
20166
0
        if (JSON_HEDLEY_LIKELY(is_object()))
20167
0
        {
20168
0
            return m_value.object->operator[](key);
20169
0
        }
20170
20171
0
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20172
0
    }
20173
20174
    /*!
20175
    @brief read-only access specified object element
20176
20177
    Returns a const reference to the element at with specified key @a key. No
20178
    bounds checking is performed.
20179
20180
    @warning If the element with key @a key does not exist, the behavior is
20181
    undefined.
20182
20183
    @param[in] key  key of the element to access
20184
20185
    @return const reference to the element at key @a key
20186
20187
    @pre The element with key @a key must exist. **This precondition is
20188
         enforced with an assertion.**
20189
20190
    @throw type_error.305 if the JSON value is not an object; in that case,
20191
    using the [] operator with a key makes no sense.
20192
20193
    @complexity Logarithmic in the size of the container.
20194
20195
    @liveexample{The example below shows how object elements can be read using
20196
    the `[]` operator.,operatorarray__key_type_const}
20197
20198
    @sa @ref at(const typename object_t::key_type&) for access by reference
20199
    with range checking
20200
    @sa @ref value() for access by value with a default value
20201
20202
    @since version 1.0.0
20203
    */
20204
    const_reference operator[](const typename object_t::key_type& key) const
20205
    {
20206
        // const operator[] only works for objects
20207
        if (JSON_HEDLEY_LIKELY(is_object()))
20208
        {
20209
            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20210
            return m_value.object->find(key)->second;
20211
        }
20212
20213
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20214
    }
20215
20216
    /*!
20217
    @brief access specified object element
20218
20219
    Returns a reference to the element at with specified key @a key.
20220
20221
    @note If @a key is not found in the object, then it is silently added to
20222
    the object and filled with a `null` value to make `key` a valid reference.
20223
    In case the value was `null` before, it is converted to an object.
20224
20225
    @param[in] key  key of the element to access
20226
20227
    @return reference to the element at key @a key
20228
20229
    @throw type_error.305 if the JSON value is not an object or null; in that
20230
    cases, using the [] operator with a key makes no sense.
20231
20232
    @complexity Logarithmic in the size of the container.
20233
20234
    @liveexample{The example below shows how object elements can be read and
20235
    written using the `[]` operator.,operatorarray__key_type}
20236
20237
    @sa @ref at(const typename object_t::key_type&) for access by reference
20238
    with range checking
20239
    @sa @ref value() for access by value with a default value
20240
20241
    @since version 1.1.0
20242
    */
20243
    template<typename T>
20244
    JSON_HEDLEY_NON_NULL(2)
20245
    reference operator[](T* key)
20246
0
    {
20247
        // implicitly convert null to object
20248
0
        if (is_null())
20249
0
        {
20250
0
            m_type = value_t::object;
20251
0
            m_value = value_t::object;
20252
0
            assert_invariant();
20253
0
        }
20254
20255
        // at only works for objects
20256
0
        if (JSON_HEDLEY_LIKELY(is_object()))
20257
0
        {
20258
0
            return m_value.object->operator[](key);
20259
0
        }
20260
20261
0
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20262
0
    }
20263
20264
    /*!
20265
    @brief read-only access specified object element
20266
20267
    Returns a const reference to the element at with specified key @a key. No
20268
    bounds checking is performed.
20269
20270
    @warning If the element with key @a key does not exist, the behavior is
20271
    undefined.
20272
20273
    @param[in] key  key of the element to access
20274
20275
    @return const reference to the element at key @a key
20276
20277
    @pre The element with key @a key must exist. **This precondition is
20278
         enforced with an assertion.**
20279
20280
    @throw type_error.305 if the JSON value is not an object; in that case,
20281
    using the [] operator with a key makes no sense.
20282
20283
    @complexity Logarithmic in the size of the container.
20284
20285
    @liveexample{The example below shows how object elements can be read using
20286
    the `[]` operator.,operatorarray__key_type_const}
20287
20288
    @sa @ref at(const typename object_t::key_type&) for access by reference
20289
    with range checking
20290
    @sa @ref value() for access by value with a default value
20291
20292
    @since version 1.1.0
20293
    */
20294
    template<typename T>
20295
    JSON_HEDLEY_NON_NULL(2)
20296
    const_reference operator[](T* key) const
20297
0
    {
20298
        // at only works for objects
20299
0
        if (JSON_HEDLEY_LIKELY(is_object()))
20300
0
        {
20301
0
            JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20302
0
            return m_value.object->find(key)->second;
20303
0
        }
20304
20305
0
        JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20306
0
    }
20307
20308
    /*!
20309
    @brief access specified object element with default value
20310
20311
    Returns either a copy of an object's element at the specified key @a key
20312
    or a given default value if no element with key @a key exists.
20313
20314
    The function is basically equivalent to executing
20315
    @code {.cpp}
20316
    try {
20317
        return at(key);
20318
    } catch(out_of_range) {
20319
        return default_value;
20320
    }
20321
    @endcode
20322
20323
    @note Unlike @ref at(const typename object_t::key_type&), this function
20324
    does not throw if the given key @a key was not found.
20325
20326
    @note Unlike @ref operator[](const typename object_t::key_type& key), this
20327
    function does not implicitly add an element to the position defined by @a
20328
    key. This function is furthermore also applicable to const objects.
20329
20330
    @param[in] key  key of the element to access
20331
    @param[in] default_value  the value to return if @a key is not found
20332
20333
    @tparam ValueType type compatible to JSON values, for instance `int` for
20334
    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
20335
    JSON arrays. Note the type of the expected value at @a key and the default
20336
    value @a default_value must be compatible.
20337
20338
    @return copy of the element at key @a key or @a default_value if @a key
20339
    is not found
20340
20341
    @throw type_error.302 if @a default_value does not match the type of the
20342
    value at @a key
20343
    @throw type_error.306 if the JSON value is not an object; in that case,
20344
    using `value()` with a key makes no sense.
20345
20346
    @complexity Logarithmic in the size of the container.
20347
20348
    @liveexample{The example below shows how object elements can be queried
20349
    with a default value.,basic_json__value}
20350
20351
    @sa @ref at(const typename object_t::key_type&) for access by reference
20352
    with range checking
20353
    @sa @ref operator[](const typename object_t::key_type&) for unchecked
20354
    access by reference
20355
20356
    @since version 1.0.0
20357
    */
20358
    // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20359
    template < class ValueType, typename std::enable_if <
20360
                   detail::is_getable<basic_json_t, ValueType>::value
20361
                   && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20362
    ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20363
    {
20364
        // at only works for objects
20365
        if (JSON_HEDLEY_LIKELY(is_object()))
20366
        {
20367
            // if key is found, return value and given default value otherwise
20368
            const auto it = find(key);
20369
            if (it != end())
20370
            {
20371
                return it->template get<ValueType>();
20372
            }
20373
20374
            return default_value;
20375
        }
20376
20377
        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20378
    }
20379
20380
    /*!
20381
    @brief overload for a default value of type const char*
20382
    @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
20383
    */
20384
    string_t value(const typename object_t::key_type& key, const char* default_value) const
20385
    {
20386
        return value(key, string_t(default_value));
20387
    }
20388
20389
    /*!
20390
    @brief access specified object element via JSON Pointer with default value
20391
20392
    Returns either a copy of an object's element at the specified key @a key
20393
    or a given default value if no element with key @a key exists.
20394
20395
    The function is basically equivalent to executing
20396
    @code {.cpp}
20397
    try {
20398
        return at(ptr);
20399
    } catch(out_of_range) {
20400
        return default_value;
20401
    }
20402
    @endcode
20403
20404
    @note Unlike @ref at(const json_pointer&), this function does not throw
20405
    if the given key @a key was not found.
20406
20407
    @param[in] ptr  a JSON pointer to the element to access
20408
    @param[in] default_value  the value to return if @a ptr found no value
20409
20410
    @tparam ValueType type compatible to JSON values, for instance `int` for
20411
    JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
20412
    JSON arrays. Note the type of the expected value at @a key and the default
20413
    value @a default_value must be compatible.
20414
20415
    @return copy of the element at key @a key or @a default_value if @a key
20416
    is not found
20417
20418
    @throw type_error.302 if @a default_value does not match the type of the
20419
    value at @a ptr
20420
    @throw type_error.306 if the JSON value is not an object; in that case,
20421
    using `value()` with a key makes no sense.
20422
20423
    @complexity Logarithmic in the size of the container.
20424
20425
    @liveexample{The example below shows how object elements can be queried
20426
    with a default value.,basic_json__value_ptr}
20427
20428
    @sa @ref operator[](const json_pointer&) for unchecked access by reference
20429
20430
    @since version 2.0.2
20431
    */
20432
    template<class ValueType, typename std::enable_if<
20433
                 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
20434
    ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20435
    {
20436
        // at only works for objects
20437
        if (JSON_HEDLEY_LIKELY(is_object()))
20438
        {
20439
            // if pointer resolves a value, return it or use default value
20440
            JSON_TRY
20441
            {
20442
                return ptr.get_checked(this).template get<ValueType>();
20443
            }
20444
            JSON_INTERNAL_CATCH (out_of_range&)
20445
            {
20446
                return default_value;
20447
            }
20448
        }
20449
20450
        JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20451
    }
20452
20453
    /*!
20454
    @brief overload for a default value of type const char*
20455
    @copydoc basic_json::value(const json_pointer&, ValueType) const
20456
    */
20457
    JSON_HEDLEY_NON_NULL(3)
20458
    string_t value(const json_pointer& ptr, const char* default_value) const
20459
    {
20460
        return value(ptr, string_t(default_value));
20461
    }
20462
20463
    /*!
20464
    @brief access the first element
20465
20466
    Returns a reference to the first element in the container. For a JSON
20467
    container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
20468
20469
    @return In case of a structured type (array or object), a reference to the
20470
    first element is returned. In case of number, string, boolean, or binary
20471
    values, a reference to the value is returned.
20472
20473
    @complexity Constant.
20474
20475
    @pre The JSON value must not be `null` (would throw `std::out_of_range`)
20476
    or an empty array or object (undefined behavior, **guarded by
20477
    assertions**).
20478
    @post The JSON value remains unchanged.
20479
20480
    @throw invalid_iterator.214 when called on `null` value
20481
20482
    @liveexample{The following code shows an example for `front()`.,front}
20483
20484
    @sa @ref back() -- access the last element
20485
20486
    @since version 1.0.0
20487
    */
20488
    reference front()
20489
    {
20490
        return *begin();
20491
    }
20492
20493
    /*!
20494
    @copydoc basic_json::front()
20495
    */
20496
    const_reference front() const
20497
    {
20498
        return *cbegin();
20499
    }
20500
20501
    /*!
20502
    @brief access the last element
20503
20504
    Returns a reference to the last element in the container. For a JSON
20505
    container `c`, the expression `c.back()` is equivalent to
20506
    @code {.cpp}
20507
    auto tmp = c.end();
20508
    --tmp;
20509
    return *tmp;
20510
    @endcode
20511
20512
    @return In case of a structured type (array or object), a reference to the
20513
    last element is returned. In case of number, string, boolean, or binary
20514
    values, a reference to the value is returned.
20515
20516
    @complexity Constant.
20517
20518
    @pre The JSON value must not be `null` (would throw `std::out_of_range`)
20519
    or an empty array or object (undefined behavior, **guarded by
20520
    assertions**).
20521
    @post The JSON value remains unchanged.
20522
20523
    @throw invalid_iterator.214 when called on a `null` value. See example
20524
    below.
20525
20526
    @liveexample{The following code shows an example for `back()`.,back}
20527
20528
    @sa @ref front() -- access the first element
20529
20530
    @since version 1.0.0
20531
    */
20532
    reference back()
20533
    {
20534
        auto tmp = end();
20535
        --tmp;
20536
        return *tmp;
20537
    }
20538
20539
    /*!
20540
    @copydoc basic_json::back()
20541
    */
20542
    const_reference back() const
20543
    {
20544
        auto tmp = cend();
20545
        --tmp;
20546
        return *tmp;
20547
    }
20548
20549
    /*!
20550
    @brief remove element given an iterator
20551
20552
    Removes the element specified by iterator @a pos. The iterator @a pos must
20553
    be valid and dereferenceable. Thus the `end()` iterator (which is valid,
20554
    but is not dereferenceable) cannot be used as a value for @a pos.
20555
20556
    If called on a primitive type other than `null`, the resulting JSON value
20557
    will be `null`.
20558
20559
    @param[in] pos iterator to the element to remove
20560
    @return Iterator following the last removed element. If the iterator @a
20561
    pos refers to the last element, the `end()` iterator is returned.
20562
20563
    @tparam IteratorType an @ref iterator or @ref const_iterator
20564
20565
    @post Invalidates iterators and references at or after the point of the
20566
    erase, including the `end()` iterator.
20567
20568
    @throw type_error.307 if called on a `null` value; example: `"cannot use
20569
    erase() with null"`
20570
    @throw invalid_iterator.202 if called on an iterator which does not belong
20571
    to the current JSON value; example: `"iterator does not fit current
20572
    value"`
20573
    @throw invalid_iterator.205 if called on a primitive type with invalid
20574
    iterator (i.e., any iterator which is not `begin()`); example: `"iterator
20575
    out of range"`
20576
20577
    @complexity The complexity depends on the type:
20578
    - objects: amortized constant
20579
    - arrays: linear in distance between @a pos and the end of the container
20580
    - strings and binary: linear in the length of the member
20581
    - other types: constant
20582
20583
    @liveexample{The example shows the result of `erase()` for different JSON
20584
    types.,erase__IteratorType}
20585
20586
    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20587
    the given range
20588
    @sa @ref erase(const typename object_t::key_type&) -- removes the element
20589
    from an object at the given key
20590
    @sa @ref erase(const size_type) -- removes the element from an array at
20591
    the given index
20592
20593
    @since version 1.0.0
20594
    */
20595
    template < class IteratorType, typename std::enable_if <
20596
                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20597
                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20598
               = 0 >
20599
    IteratorType erase(IteratorType pos)
20600
0
    {
20601
        // make sure iterator fits the current value
20602
0
        if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20603
0
        {
20604
0
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20605
0
        }
20606
20607
0
        IteratorType result = end();
20608
20609
0
        switch (m_type)
20610
0
        {
20611
0
            case value_t::boolean:
20612
0
            case value_t::number_float:
20613
0
            case value_t::number_integer:
20614
0
            case value_t::number_unsigned:
20615
0
            case value_t::string:
20616
0
            case value_t::binary:
20617
0
            {
20618
0
                if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20619
0
                {
20620
0
                    JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20621
0
                }
20622
20623
0
                if (is_string())
20624
0
                {
20625
0
                    AllocatorType<string_t> alloc;
20626
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20627
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20628
0
                    m_value.string = nullptr;
20629
0
                }
20630
0
                else if (is_binary())
20631
0
                {
20632
0
                    AllocatorType<binary_t> alloc;
20633
0
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20634
0
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20635
0
                    m_value.binary = nullptr;
20636
0
                }
20637
20638
0
                m_type = value_t::null;
20639
0
                assert_invariant();
20640
0
                break;
20641
0
            }
20642
20643
0
            case value_t::object:
20644
0
            {
20645
0
                result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20646
0
                break;
20647
0
            }
20648
20649
0
            case value_t::array:
20650
0
            {
20651
0
                result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20652
0
                break;
20653
0
            }
20654
20655
0
            default:
20656
0
                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20657
0
        }
20658
20659
0
        return result;
20660
0
    }
20661
20662
    /*!
20663
    @brief remove elements given an iterator range
20664
20665
    Removes the element specified by the range `[first; last)`. The iterator
20666
    @a first does not need to be dereferenceable if `first == last`: erasing
20667
    an empty range is a no-op.
20668
20669
    If called on a primitive type other than `null`, the resulting JSON value
20670
    will be `null`.
20671
20672
    @param[in] first iterator to the beginning of the range to remove
20673
    @param[in] last iterator past the end of the range to remove
20674
    @return Iterator following the last removed element. If the iterator @a
20675
    second refers to the last element, the `end()` iterator is returned.
20676
20677
    @tparam IteratorType an @ref iterator or @ref const_iterator
20678
20679
    @post Invalidates iterators and references at or after the point of the
20680
    erase, including the `end()` iterator.
20681
20682
    @throw type_error.307 if called on a `null` value; example: `"cannot use
20683
    erase() with null"`
20684
    @throw invalid_iterator.203 if called on iterators which does not belong
20685
    to the current JSON value; example: `"iterators do not fit current value"`
20686
    @throw invalid_iterator.204 if called on a primitive type with invalid
20687
    iterators (i.e., if `first != begin()` and `last != end()`); example:
20688
    `"iterators out of range"`
20689
20690
    @complexity The complexity depends on the type:
20691
    - objects: `log(size()) + std::distance(first, last)`
20692
    - arrays: linear in the distance between @a first and @a last, plus linear
20693
      in the distance between @a last and end of the container
20694
    - strings and binary: linear in the length of the member
20695
    - other types: constant
20696
20697
    @liveexample{The example shows the result of `erase()` for different JSON
20698
    types.,erase__IteratorType_IteratorType}
20699
20700
    @sa @ref erase(IteratorType) -- removes the element at a given position
20701
    @sa @ref erase(const typename object_t::key_type&) -- removes the element
20702
    from an object at the given key
20703
    @sa @ref erase(const size_type) -- removes the element from an array at
20704
    the given index
20705
20706
    @since version 1.0.0
20707
    */
20708
    template < class IteratorType, typename std::enable_if <
20709
                   std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20710
                   std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20711
               = 0 >
20712
    IteratorType erase(IteratorType first, IteratorType last)
20713
    {
20714
        // make sure iterator fits the current value
20715
        if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20716
        {
20717
            JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20718
        }
20719
20720
        IteratorType result = end();
20721
20722
        switch (m_type)
20723
        {
20724
            case value_t::boolean:
20725
            case value_t::number_float:
20726
            case value_t::number_integer:
20727
            case value_t::number_unsigned:
20728
            case value_t::string:
20729
            case value_t::binary:
20730
            {
20731
                if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20732
                                       || !last.m_it.primitive_iterator.is_end()))
20733
                {
20734
                    JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20735
                }
20736
20737
                if (is_string())
20738
                {
20739
                    AllocatorType<string_t> alloc;
20740
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20741
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20742
                    m_value.string = nullptr;
20743
                }
20744
                else if (is_binary())
20745
                {
20746
                    AllocatorType<binary_t> alloc;
20747
                    std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20748
                    std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20749
                    m_value.binary = nullptr;
20750
                }
20751
20752
                m_type = value_t::null;
20753
                assert_invariant();
20754
                break;
20755
            }
20756
20757
            case value_t::object:
20758
            {
20759
                result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20760
                                              last.m_it.object_iterator);
20761
                break;
20762
            }
20763
20764
            case value_t::array:
20765
            {
20766
                result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20767
                                             last.m_it.array_iterator);
20768
                break;
20769
            }
20770
20771
            default:
20772
                JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20773
        }
20774
20775
        return result;
20776
    }
20777
20778
    /*!
20779
    @brief remove element from a JSON object given a key
20780
20781
    Removes elements from a JSON object with the key value @a key.
20782
20783
    @param[in] key value of the elements to remove
20784
20785
    @return Number of elements removed. If @a ObjectType is the default
20786
    `std::map` type, the return value will always be `0` (@a key was not
20787
    found) or `1` (@a key was found).
20788
20789
    @post References and iterators to the erased elements are invalidated.
20790
    Other references and iterators are not affected.
20791
20792
    @throw type_error.307 when called on a type other than JSON object;
20793
    example: `"cannot use erase() with null"`
20794
20795
    @complexity `log(size()) + count(key)`
20796
20797
    @liveexample{The example shows the effect of `erase()`.,erase__key_type}
20798
20799
    @sa @ref erase(IteratorType) -- removes the element at a given position
20800
    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20801
    the given range
20802
    @sa @ref erase(const size_type) -- removes the element from an array at
20803
    the given index
20804
20805
    @since version 1.0.0
20806
    */
20807
    size_type erase(const typename object_t::key_type& key)
20808
    {
20809
        // this erase only works for objects
20810
        if (JSON_HEDLEY_LIKELY(is_object()))
20811
        {
20812
            return m_value.object->erase(key);
20813
        }
20814
20815
        JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20816
    }
20817
20818
    /*!
20819
    @brief remove element from a JSON array given an index
20820
20821
    Removes element from a JSON array at the index @a idx.
20822
20823
    @param[in] idx index of the element to remove
20824
20825
    @throw type_error.307 when called on a type other than JSON object;
20826
    example: `"cannot use erase() with null"`
20827
    @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
20828
    is out of range"`
20829
20830
    @complexity Linear in distance between @a idx and the end of the container.
20831
20832
    @liveexample{The example shows the effect of `erase()`.,erase__size_type}
20833
20834
    @sa @ref erase(IteratorType) -- removes the element at a given position
20835
    @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20836
    the given range
20837
    @sa @ref erase(const typename object_t::key_type&) -- removes the element
20838
    from an object at the given key
20839
20840
    @since version 1.0.0
20841
    */
20842
    void erase(const size_type idx)
20843
    {
20844
        // this erase only works for arrays
20845
        if (JSON_HEDLEY_LIKELY(is_array()))
20846
        {
20847
            if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20848
            {
20849
                JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20850
            }
20851
20852
            m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20853
        }
20854
        else
20855
        {
20856
            JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20857
        }
20858
    }
20859
20860
    /// @}
20861
20862
20863
    ////////////
20864
    // lookup //
20865
    ////////////
20866
20867
    /// @name lookup
20868
    /// @{
20869
20870
    /*!
20871
    @brief find an element in a JSON object
20872
20873
    Finds an element in a JSON object with key equivalent to @a key. If the
20874
    element is not found or the JSON value is not an object, end() is
20875
    returned.
20876
20877
    @note This method always returns @ref end() when executed on a JSON type
20878
          that is not an object.
20879
20880
    @param[in] key key value of the element to search for.
20881
20882
    @return Iterator to an element with key equivalent to @a key. If no such
20883
    element is found or the JSON value is not an object, past-the-end (see
20884
    @ref end()) iterator is returned.
20885
20886
    @complexity Logarithmic in the size of the JSON object.
20887
20888
    @liveexample{The example shows how `find()` is used.,find__key_type}
20889
20890
    @sa @ref contains(KeyT&&) const -- checks whether a key exists
20891
20892
    @since version 1.0.0
20893
    */
20894
    template<typename KeyT>
20895
    iterator find(KeyT&& key)
20896
    {
20897
        auto result = end();
20898
20899
        if (is_object())
20900
        {
20901
            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20902
        }
20903
20904
        return result;
20905
    }
20906
20907
    /*!
20908
    @brief find an element in a JSON object
20909
    @copydoc find(KeyT&&)
20910
    */
20911
    template<typename KeyT>
20912
    const_iterator find(KeyT&& key) const
20913
    {
20914
        auto result = cend();
20915
20916
        if (is_object())
20917
        {
20918
            result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20919
        }
20920
20921
        return result;
20922
    }
20923
20924
    /*!
20925
    @brief returns the number of occurrences of a key in a JSON object
20926
20927
    Returns the number of elements with key @a key. If ObjectType is the
20928
    default `std::map` type, the return value will always be `0` (@a key was
20929
    not found) or `1` (@a key was found).
20930
20931
    @note This method always returns `0` when executed on a JSON type that is
20932
          not an object.
20933
20934
    @param[in] key key value of the element to count
20935
20936
    @return Number of elements with key @a key. If the JSON value is not an
20937
    object, the return value will be `0`.
20938
20939
    @complexity Logarithmic in the size of the JSON object.
20940
20941
    @liveexample{The example shows how `count()` is used.,count}
20942
20943
    @since version 1.0.0
20944
    */
20945
    template<typename KeyT>
20946
    size_type count(KeyT&& key) const
20947
    {
20948
        // return 0 for all nonobject types
20949
        return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20950
    }
20951
20952
    /*!
20953
    @brief check the existence of an element in a JSON object
20954
20955
    Check whether an element exists in a JSON object with key equivalent to
20956
    @a key. If the element is not found or the JSON value is not an object,
20957
    false is returned.
20958
20959
    @note This method always returns false when executed on a JSON type
20960
          that is not an object.
20961
20962
    @param[in] key key value to check its existence.
20963
20964
    @return true if an element with specified @a key exists. If no such
20965
    element with such key is found or the JSON value is not an object,
20966
    false is returned.
20967
20968
    @complexity Logarithmic in the size of the JSON object.
20969
20970
    @liveexample{The following code shows an example for `contains()`.,contains}
20971
20972
    @sa @ref find(KeyT&&) -- returns an iterator to an object element
20973
    @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
20974
20975
    @since version 3.6.0
20976
    */
20977
    template < typename KeyT, typename std::enable_if <
20978
                   !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
20979
    bool contains(KeyT && key) const
20980
    {
20981
        return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20982
    }
20983
20984
    /*!
20985
    @brief check the existence of an element in a JSON object given a JSON pointer
20986
20987
    Check whether the given JSON pointer @a ptr can be resolved in the current
20988
    JSON value.
20989
20990
    @note This method can be executed on any JSON value type.
20991
20992
    @param[in] ptr JSON pointer to check its existence.
20993
20994
    @return true if the JSON pointer can be resolved to a stored value, false
20995
    otherwise.
20996
20997
    @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
20998
20999
    @throw parse_error.106   if an array index begins with '0'
21000
    @throw parse_error.109   if an array index was not a number
21001
21002
    @complexity Logarithmic in the size of the JSON object.
21003
21004
    @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
21005
21006
    @sa @ref contains(KeyT &&) const -- checks the existence of a key
21007
21008
    @since version 3.7.0
21009
    */
21010
    bool contains(const json_pointer& ptr) const
21011
    {
21012
        return ptr.contains(this);
21013
    }
21014
21015
    /// @}
21016
21017
21018
    ///////////////
21019
    // iterators //
21020
    ///////////////
21021
21022
    /// @name iterators
21023
    /// @{
21024
21025
    /*!
21026
    @brief returns an iterator to the first element
21027
21028
    Returns an iterator to the first element.
21029
21030
    @image html range-begin-end.svg "Illustration from cppreference.com"
21031
21032
    @return iterator to the first element
21033
21034
    @complexity Constant.
21035
21036
    @requirement This function helps `basic_json` satisfying the
21037
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21038
    requirements:
21039
    - The complexity is constant.
21040
21041
    @liveexample{The following code shows an example for `begin()`.,begin}
21042
21043
    @sa @ref cbegin() -- returns a const iterator to the beginning
21044
    @sa @ref end() -- returns an iterator to the end
21045
    @sa @ref cend() -- returns a const iterator to the end
21046
21047
    @since version 1.0.0
21048
    */
21049
    iterator begin() noexcept
21050
0
    {
21051
0
        iterator result(this);
21052
0
        result.set_begin();
21053
0
        return result;
21054
0
    }
21055
21056
    /*!
21057
    @copydoc basic_json::cbegin()
21058
    */
21059
    const_iterator begin() const noexcept
21060
0
    {
21061
0
        return cbegin();
21062
0
    }
21063
21064
    /*!
21065
    @brief returns a const iterator to the first element
21066
21067
    Returns a const iterator to the first element.
21068
21069
    @image html range-begin-end.svg "Illustration from cppreference.com"
21070
21071
    @return const iterator to the first element
21072
21073
    @complexity Constant.
21074
21075
    @requirement This function helps `basic_json` satisfying the
21076
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21077
    requirements:
21078
    - The complexity is constant.
21079
    - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
21080
21081
    @liveexample{The following code shows an example for `cbegin()`.,cbegin}
21082
21083
    @sa @ref begin() -- returns an iterator to the beginning
21084
    @sa @ref end() -- returns an iterator to the end
21085
    @sa @ref cend() -- returns a const iterator to the end
21086
21087
    @since version 1.0.0
21088
    */
21089
    const_iterator cbegin() const noexcept
21090
0
    {
21091
0
        const_iterator result(this);
21092
0
        result.set_begin();
21093
0
        return result;
21094
0
    }
21095
21096
    /*!
21097
    @brief returns an iterator to one past the last element
21098
21099
    Returns an iterator to one past the last element.
21100
21101
    @image html range-begin-end.svg "Illustration from cppreference.com"
21102
21103
    @return iterator one past the last element
21104
21105
    @complexity Constant.
21106
21107
    @requirement This function helps `basic_json` satisfying the
21108
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21109
    requirements:
21110
    - The complexity is constant.
21111
21112
    @liveexample{The following code shows an example for `end()`.,end}
21113
21114
    @sa @ref cend() -- returns a const iterator to the end
21115
    @sa @ref begin() -- returns an iterator to the beginning
21116
    @sa @ref cbegin() -- returns a const iterator to the beginning
21117
21118
    @since version 1.0.0
21119
    */
21120
    iterator end() noexcept
21121
0
    {
21122
0
        iterator result(this);
21123
0
        result.set_end();
21124
0
        return result;
21125
0
    }
21126
21127
    /*!
21128
    @copydoc basic_json::cend()
21129
    */
21130
    const_iterator end() const noexcept
21131
0
    {
21132
0
        return cend();
21133
0
    }
21134
21135
    /*!
21136
    @brief returns a const iterator to one past the last element
21137
21138
    Returns a const iterator to one past the last element.
21139
21140
    @image html range-begin-end.svg "Illustration from cppreference.com"
21141
21142
    @return const iterator one past the last element
21143
21144
    @complexity Constant.
21145
21146
    @requirement This function helps `basic_json` satisfying the
21147
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21148
    requirements:
21149
    - The complexity is constant.
21150
    - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
21151
21152
    @liveexample{The following code shows an example for `cend()`.,cend}
21153
21154
    @sa @ref end() -- returns an iterator to the end
21155
    @sa @ref begin() -- returns an iterator to the beginning
21156
    @sa @ref cbegin() -- returns a const iterator to the beginning
21157
21158
    @since version 1.0.0
21159
    */
21160
    const_iterator cend() const noexcept
21161
0
    {
21162
0
        const_iterator result(this);
21163
0
        result.set_end();
21164
0
        return result;
21165
0
    }
21166
21167
    /*!
21168
    @brief returns an iterator to the reverse-beginning
21169
21170
    Returns an iterator to the reverse-beginning; that is, the last element.
21171
21172
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21173
21174
    @complexity Constant.
21175
21176
    @requirement This function helps `basic_json` satisfying the
21177
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21178
    requirements:
21179
    - The complexity is constant.
21180
    - Has the semantics of `reverse_iterator(end())`.
21181
21182
    @liveexample{The following code shows an example for `rbegin()`.,rbegin}
21183
21184
    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21185
    @sa @ref rend() -- returns a reverse iterator to the end
21186
    @sa @ref crend() -- returns a const reverse iterator to the end
21187
21188
    @since version 1.0.0
21189
    */
21190
    reverse_iterator rbegin() noexcept
21191
    {
21192
        return reverse_iterator(end());
21193
    }
21194
21195
    /*!
21196
    @copydoc basic_json::crbegin()
21197
    */
21198
    const_reverse_iterator rbegin() const noexcept
21199
    {
21200
        return crbegin();
21201
    }
21202
21203
    /*!
21204
    @brief returns an iterator to the reverse-end
21205
21206
    Returns an iterator to the reverse-end; that is, one before the first
21207
    element.
21208
21209
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21210
21211
    @complexity Constant.
21212
21213
    @requirement This function helps `basic_json` satisfying the
21214
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21215
    requirements:
21216
    - The complexity is constant.
21217
    - Has the semantics of `reverse_iterator(begin())`.
21218
21219
    @liveexample{The following code shows an example for `rend()`.,rend}
21220
21221
    @sa @ref crend() -- returns a const reverse iterator to the end
21222
    @sa @ref rbegin() -- returns a reverse iterator to the beginning
21223
    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21224
21225
    @since version 1.0.0
21226
    */
21227
    reverse_iterator rend() noexcept
21228
    {
21229
        return reverse_iterator(begin());
21230
    }
21231
21232
    /*!
21233
    @copydoc basic_json::crend()
21234
    */
21235
    const_reverse_iterator rend() const noexcept
21236
    {
21237
        return crend();
21238
    }
21239
21240
    /*!
21241
    @brief returns a const reverse iterator to the last element
21242
21243
    Returns a const iterator to the reverse-beginning; that is, the last
21244
    element.
21245
21246
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21247
21248
    @complexity Constant.
21249
21250
    @requirement This function helps `basic_json` satisfying the
21251
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21252
    requirements:
21253
    - The complexity is constant.
21254
    - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
21255
21256
    @liveexample{The following code shows an example for `crbegin()`.,crbegin}
21257
21258
    @sa @ref rbegin() -- returns a reverse iterator to the beginning
21259
    @sa @ref rend() -- returns a reverse iterator to the end
21260
    @sa @ref crend() -- returns a const reverse iterator to the end
21261
21262
    @since version 1.0.0
21263
    */
21264
    const_reverse_iterator crbegin() const noexcept
21265
    {
21266
        return const_reverse_iterator(cend());
21267
    }
21268
21269
    /*!
21270
    @brief returns a const reverse iterator to one before the first
21271
21272
    Returns a const reverse iterator to the reverse-end; that is, one before
21273
    the first element.
21274
21275
    @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21276
21277
    @complexity Constant.
21278
21279
    @requirement This function helps `basic_json` satisfying the
21280
    [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21281
    requirements:
21282
    - The complexity is constant.
21283
    - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
21284
21285
    @liveexample{The following code shows an example for `crend()`.,crend}
21286
21287
    @sa @ref rend() -- returns a reverse iterator to the end
21288
    @sa @ref rbegin() -- returns a reverse iterator to the beginning
21289
    @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21290
21291
    @since version 1.0.0
21292
    */
21293
    const_reverse_iterator crend() const noexcept
21294
    {
21295
        return const_reverse_iterator(cbegin());
21296
    }
21297
21298
  public:
21299
    /*!
21300
    @brief wrapper to access iterator member functions in range-based for
21301
21302
    This function allows to access @ref iterator::key() and @ref
21303
    iterator::value() during range-based for loops. In these loops, a
21304
    reference to the JSON values is returned, so there is no access to the
21305
    underlying iterator.
21306
21307
    For loop without iterator_wrapper:
21308
21309
    @code{cpp}
21310
    for (auto it = j_object.begin(); it != j_object.end(); ++it)
21311
    {
21312
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21313
    }
21314
    @endcode
21315
21316
    Range-based for loop without iterator proxy:
21317
21318
    @code{cpp}
21319
    for (auto it : j_object)
21320
    {
21321
        // "it" is of type json::reference and has no key() member
21322
        std::cout << "value: " << it << '\n';
21323
    }
21324
    @endcode
21325
21326
    Range-based for loop with iterator proxy:
21327
21328
    @code{cpp}
21329
    for (auto it : json::iterator_wrapper(j_object))
21330
    {
21331
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21332
    }
21333
    @endcode
21334
21335
    @note When iterating over an array, `key()` will return the index of the
21336
          element as string (see example).
21337
21338
    @param[in] ref  reference to a JSON value
21339
    @return iteration proxy object wrapping @a ref with an interface to use in
21340
            range-based for loops
21341
21342
    @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
21343
21344
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21345
    changes in the JSON value.
21346
21347
    @complexity Constant.
21348
21349
    @note The name of this function is not yet final and may change in the
21350
    future.
21351
21352
    @deprecated This stream operator is deprecated and will be removed in
21353
                future 4.0.0 of the library. Please use @ref items() instead;
21354
                that is, replace `json::iterator_wrapper(j)` with `j.items()`.
21355
    */
21356
    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21357
    static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21358
    {
21359
        return ref.items();
21360
    }
21361
21362
    /*!
21363
    @copydoc iterator_wrapper(reference)
21364
    */
21365
    JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21366
    static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21367
    {
21368
        return ref.items();
21369
    }
21370
21371
    /*!
21372
    @brief helper to access iterator member functions in range-based for
21373
21374
    This function allows to access @ref iterator::key() and @ref
21375
    iterator::value() during range-based for loops. In these loops, a
21376
    reference to the JSON values is returned, so there is no access to the
21377
    underlying iterator.
21378
21379
    For loop without `items()` function:
21380
21381
    @code{cpp}
21382
    for (auto it = j_object.begin(); it != j_object.end(); ++it)
21383
    {
21384
        std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21385
    }
21386
    @endcode
21387
21388
    Range-based for loop without `items()` function:
21389
21390
    @code{cpp}
21391
    for (auto it : j_object)
21392
    {
21393
        // "it" is of type json::reference and has no key() member
21394
        std::cout << "value: " << it << '\n';
21395
    }
21396
    @endcode
21397
21398
    Range-based for loop with `items()` function:
21399
21400
    @code{cpp}
21401
    for (auto& el : j_object.items())
21402
    {
21403
        std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
21404
    }
21405
    @endcode
21406
21407
    The `items()` function also allows to use
21408
    [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
21409
    (C++17):
21410
21411
    @code{cpp}
21412
    for (auto& [key, val] : j_object.items())
21413
    {
21414
        std::cout << "key: " << key << ", value:" << val << '\n';
21415
    }
21416
    @endcode
21417
21418
    @note When iterating over an array, `key()` will return the index of the
21419
          element as string (see example). For primitive types (e.g., numbers),
21420
          `key()` returns an empty string.
21421
21422
    @warning Using `items()` on temporary objects is dangerous. Make sure the
21423
             object's lifetime exeeds the iteration. See
21424
             <https://github.com/nlohmann/json/issues/2040> for more
21425
             information.
21426
21427
    @return iteration proxy object wrapping @a ref with an interface to use in
21428
            range-based for loops
21429
21430
    @liveexample{The following code shows how the function is used.,items}
21431
21432
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21433
    changes in the JSON value.
21434
21435
    @complexity Constant.
21436
21437
    @since version 3.1.0, structured bindings support since 3.5.0.
21438
    */
21439
    iteration_proxy<iterator> items() noexcept
21440
    {
21441
        return iteration_proxy<iterator>(*this);
21442
    }
21443
21444
    /*!
21445
    @copydoc items()
21446
    */
21447
    iteration_proxy<const_iterator> items() const noexcept
21448
0
    {
21449
0
        return iteration_proxy<const_iterator>(*this);
21450
0
    }
21451
21452
    /// @}
21453
21454
21455
    //////////////
21456
    // capacity //
21457
    //////////////
21458
21459
    /// @name capacity
21460
    /// @{
21461
21462
    /*!
21463
    @brief checks whether the container is empty.
21464
21465
    Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
21466
21467
    @return The return value depends on the different types and is
21468
            defined as follows:
21469
            Value type  | return value
21470
            ----------- | -------------
21471
            null        | `true`
21472
            boolean     | `false`
21473
            string      | `false`
21474
            number      | `false`
21475
            binary      | `false`
21476
            object      | result of function `object_t::empty()`
21477
            array       | result of function `array_t::empty()`
21478
21479
    @liveexample{The following code uses `empty()` to check if a JSON
21480
    object contains any elements.,empty}
21481
21482
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21483
    the Container concept; that is, their `empty()` functions have constant
21484
    complexity.
21485
21486
    @iterators No changes.
21487
21488
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
21489
21490
    @note This function does not return whether a string stored as JSON value
21491
    is empty - it returns whether the JSON container itself is empty which is
21492
    false in the case of a string.
21493
21494
    @requirement This function helps `basic_json` satisfying the
21495
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21496
    requirements:
21497
    - The complexity is constant.
21498
    - Has the semantics of `begin() == end()`.
21499
21500
    @sa @ref size() -- returns the number of elements
21501
21502
    @since version 1.0.0
21503
    */
21504
    bool empty() const noexcept
21505
    {
21506
        switch (m_type)
21507
        {
21508
            case value_t::null:
21509
            {
21510
                // null values are empty
21511
                return true;
21512
            }
21513
21514
            case value_t::array:
21515
            {
21516
                // delegate call to array_t::empty()
21517
                return m_value.array->empty();
21518
            }
21519
21520
            case value_t::object:
21521
            {
21522
                // delegate call to object_t::empty()
21523
                return m_value.object->empty();
21524
            }
21525
21526
            default:
21527
            {
21528
                // all other types are nonempty
21529
                return false;
21530
            }
21531
        }
21532
    }
21533
21534
    /*!
21535
    @brief returns the number of elements
21536
21537
    Returns the number of elements in a JSON value.
21538
21539
    @return The return value depends on the different types and is
21540
            defined as follows:
21541
            Value type  | return value
21542
            ----------- | -------------
21543
            null        | `0`
21544
            boolean     | `1`
21545
            string      | `1`
21546
            number      | `1`
21547
            binary      | `1`
21548
            object      | result of function object_t::size()
21549
            array       | result of function array_t::size()
21550
21551
    @liveexample{The following code calls `size()` on the different value
21552
    types.,size}
21553
21554
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21555
    the Container concept; that is, their size() functions have constant
21556
    complexity.
21557
21558
    @iterators No changes.
21559
21560
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
21561
21562
    @note This function does not return the length of a string stored as JSON
21563
    value - it returns the number of elements in the JSON value which is 1 in
21564
    the case of a string.
21565
21566
    @requirement This function helps `basic_json` satisfying the
21567
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21568
    requirements:
21569
    - The complexity is constant.
21570
    - Has the semantics of `std::distance(begin(), end())`.
21571
21572
    @sa @ref empty() -- checks whether the container is empty
21573
    @sa @ref max_size() -- returns the maximal number of elements
21574
21575
    @since version 1.0.0
21576
    */
21577
    size_type size() const noexcept
21578
0
    {
21579
0
        switch (m_type)
21580
0
        {
21581
0
            case value_t::null:
21582
0
            {
21583
                // null values are empty
21584
0
                return 0;
21585
0
            }
21586
21587
0
            case value_t::array:
21588
0
            {
21589
                // delegate call to array_t::size()
21590
0
                return m_value.array->size();
21591
0
            }
21592
21593
0
            case value_t::object:
21594
0
            {
21595
                // delegate call to object_t::size()
21596
0
                return m_value.object->size();
21597
0
            }
21598
21599
0
            default:
21600
0
            {
21601
                // all other types have size 1
21602
0
                return 1;
21603
0
            }
21604
0
        }
21605
0
    }
21606
21607
    /*!
21608
    @brief returns the maximum possible number of elements
21609
21610
    Returns the maximum number of elements a JSON value is able to hold due to
21611
    system or library implementation limitations, i.e. `std::distance(begin(),
21612
    end())` for the JSON value.
21613
21614
    @return The return value depends on the different types and is
21615
            defined as follows:
21616
            Value type  | return value
21617
            ----------- | -------------
21618
            null        | `0` (same as `size()`)
21619
            boolean     | `1` (same as `size()`)
21620
            string      | `1` (same as `size()`)
21621
            number      | `1` (same as `size()`)
21622
            binary      | `1` (same as `size()`)
21623
            object      | result of function `object_t::max_size()`
21624
            array       | result of function `array_t::max_size()`
21625
21626
    @liveexample{The following code calls `max_size()` on the different value
21627
    types. Note the output is implementation specific.,max_size}
21628
21629
    @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21630
    the Container concept; that is, their `max_size()` functions have constant
21631
    complexity.
21632
21633
    @iterators No changes.
21634
21635
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
21636
21637
    @requirement This function helps `basic_json` satisfying the
21638
    [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21639
    requirements:
21640
    - The complexity is constant.
21641
    - Has the semantics of returning `b.size()` where `b` is the largest
21642
      possible JSON value.
21643
21644
    @sa @ref size() -- returns the number of elements
21645
21646
    @since version 1.0.0
21647
    */
21648
    size_type max_size() const noexcept
21649
0
    {
21650
0
        switch (m_type)
21651
0
        {
21652
0
            case value_t::array:
21653
0
            {
21654
                // delegate call to array_t::max_size()
21655
0
                return m_value.array->max_size();
21656
0
            }
21657
21658
0
            case value_t::object:
21659
0
            {
21660
                // delegate call to object_t::max_size()
21661
0
                return m_value.object->max_size();
21662
0
            }
21663
21664
0
            default:
21665
0
            {
21666
                // all other types have max_size() == size()
21667
0
                return size();
21668
0
            }
21669
0
        }
21670
0
    }
21671
21672
    /// @}
21673
21674
21675
    ///////////////
21676
    // modifiers //
21677
    ///////////////
21678
21679
    /// @name modifiers
21680
    /// @{
21681
21682
    /*!
21683
    @brief clears the contents
21684
21685
    Clears the content of a JSON value and resets it to the default value as
21686
    if @ref basic_json(value_t) would have been called with the current value
21687
    type from @ref type():
21688
21689
    Value type  | initial value
21690
    ----------- | -------------
21691
    null        | `null`
21692
    boolean     | `false`
21693
    string      | `""`
21694
    number      | `0`
21695
    binary      | An empty byte vector
21696
    object      | `{}`
21697
    array       | `[]`
21698
21699
    @post Has the same effect as calling
21700
    @code {.cpp}
21701
    *this = basic_json(type());
21702
    @endcode
21703
21704
    @liveexample{The example below shows the effect of `clear()` to different
21705
    JSON types.,clear}
21706
21707
    @complexity Linear in the size of the JSON value.
21708
21709
    @iterators All iterators, pointers and references related to this container
21710
               are invalidated.
21711
21712
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
21713
21714
    @sa @ref basic_json(value_t) -- constructor that creates an object with the
21715
        same value than calling `clear()`
21716
21717
    @since version 1.0.0
21718
    */
21719
    void clear() noexcept
21720
    {
21721
        switch (m_type)
21722
        {
21723
            case value_t::number_integer:
21724
            {
21725
                m_value.number_integer = 0;
21726
                break;
21727
            }
21728
21729
            case value_t::number_unsigned:
21730
            {
21731
                m_value.number_unsigned = 0;
21732
                break;
21733
            }
21734
21735
            case value_t::number_float:
21736
            {
21737
                m_value.number_float = 0.0;
21738
                break;
21739
            }
21740
21741
            case value_t::boolean:
21742
            {
21743
                m_value.boolean = false;
21744
                break;
21745
            }
21746
21747
            case value_t::string:
21748
            {
21749
                m_value.string->clear();
21750
                break;
21751
            }
21752
21753
            case value_t::binary:
21754
            {
21755
                m_value.binary->clear();
21756
                break;
21757
            }
21758
21759
            case value_t::array:
21760
            {
21761
                m_value.array->clear();
21762
                break;
21763
            }
21764
21765
            case value_t::object:
21766
            {
21767
                m_value.object->clear();
21768
                break;
21769
            }
21770
21771
            default:
21772
                break;
21773
        }
21774
    }
21775
21776
    /*!
21777
    @brief add an object to an array
21778
21779
    Appends the given element @a val to the end of the JSON value. If the
21780
    function is called on a JSON null value, an empty array is created before
21781
    appending @a val.
21782
21783
    @param[in] val the value to add to the JSON array
21784
21785
    @throw type_error.308 when called on a type other than JSON array or
21786
    null; example: `"cannot use push_back() with number"`
21787
21788
    @complexity Amortized constant.
21789
21790
    @liveexample{The example shows how `push_back()` and `+=` can be used to
21791
    add elements to a JSON array. Note how the `null` value was silently
21792
    converted to a JSON array.,push_back}
21793
21794
    @since version 1.0.0
21795
    */
21796
    void push_back(basic_json&& val)
21797
    {
21798
        // push_back only works for null objects or arrays
21799
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21800
        {
21801
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21802
        }
21803
21804
        // transform null object into an array
21805
        if (is_null())
21806
        {
21807
            m_type = value_t::array;
21808
            m_value = value_t::array;
21809
            assert_invariant();
21810
        }
21811
21812
        // add element to array (move semantics)
21813
        m_value.array->push_back(std::move(val));
21814
        // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21815
    }
21816
21817
    /*!
21818
    @brief add an object to an array
21819
    @copydoc push_back(basic_json&&)
21820
    */
21821
    reference operator+=(basic_json&& val)
21822
    {
21823
        push_back(std::move(val));
21824
        return *this;
21825
    }
21826
21827
    /*!
21828
    @brief add an object to an array
21829
    @copydoc push_back(basic_json&&)
21830
    */
21831
    void push_back(const basic_json& val)
21832
    {
21833
        // push_back only works for null objects or arrays
21834
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21835
        {
21836
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21837
        }
21838
21839
        // transform null object into an array
21840
        if (is_null())
21841
        {
21842
            m_type = value_t::array;
21843
            m_value = value_t::array;
21844
            assert_invariant();
21845
        }
21846
21847
        // add element to array
21848
        m_value.array->push_back(val);
21849
    }
21850
21851
    /*!
21852
    @brief add an object to an array
21853
    @copydoc push_back(basic_json&&)
21854
    */
21855
    reference operator+=(const basic_json& val)
21856
    {
21857
        push_back(val);
21858
        return *this;
21859
    }
21860
21861
    /*!
21862
    @brief add an object to an object
21863
21864
    Inserts the given element @a val to the JSON object. If the function is
21865
    called on a JSON null value, an empty object is created before inserting
21866
    @a val.
21867
21868
    @param[in] val the value to add to the JSON object
21869
21870
    @throw type_error.308 when called on a type other than JSON object or
21871
    null; example: `"cannot use push_back() with number"`
21872
21873
    @complexity Logarithmic in the size of the container, O(log(`size()`)).
21874
21875
    @liveexample{The example shows how `push_back()` and `+=` can be used to
21876
    add elements to a JSON object. Note how the `null` value was silently
21877
    converted to a JSON object.,push_back__object_t__value}
21878
21879
    @since version 1.0.0
21880
    */
21881
    void push_back(const typename object_t::value_type& val)
21882
    {
21883
        // push_back only works for null objects or objects
21884
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21885
        {
21886
            JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21887
        }
21888
21889
        // transform null object into an object
21890
        if (is_null())
21891
        {
21892
            m_type = value_t::object;
21893
            m_value = value_t::object;
21894
            assert_invariant();
21895
        }
21896
21897
        // add element to array
21898
        m_value.object->insert(val);
21899
    }
21900
21901
    /*!
21902
    @brief add an object to an object
21903
    @copydoc push_back(const typename object_t::value_type&)
21904
    */
21905
    reference operator+=(const typename object_t::value_type& val)
21906
    {
21907
        push_back(val);
21908
        return *this;
21909
    }
21910
21911
    /*!
21912
    @brief add an object to an object
21913
21914
    This function allows to use `push_back` with an initializer list. In case
21915
21916
    1. the current value is an object,
21917
    2. the initializer list @a init contains only two elements, and
21918
    3. the first element of @a init is a string,
21919
21920
    @a init is converted into an object element and added using
21921
    @ref push_back(const typename object_t::value_type&). Otherwise, @a init
21922
    is converted to a JSON value and added using @ref push_back(basic_json&&).
21923
21924
    @param[in] init  an initializer list
21925
21926
    @complexity Linear in the size of the initializer list @a init.
21927
21928
    @note This function is required to resolve an ambiguous overload error,
21929
          because pairs like `{"key", "value"}` can be both interpreted as
21930
          `object_t::value_type` or `std::initializer_list<basic_json>`, see
21931
          https://github.com/nlohmann/json/issues/235 for more information.
21932
21933
    @liveexample{The example shows how initializer lists are treated as
21934
    objects when possible.,push_back__initializer_list}
21935
    */
21936
    void push_back(initializer_list_t init)
21937
    {
21938
        if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21939
        {
21940
            basic_json&& key = init.begin()->moved_or_copied();
21941
            push_back(typename object_t::value_type(
21942
                          std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21943
        }
21944
        else
21945
        {
21946
            push_back(basic_json(init));
21947
        }
21948
    }
21949
21950
    /*!
21951
    @brief add an object to an object
21952
    @copydoc push_back(initializer_list_t)
21953
    */
21954
    reference operator+=(initializer_list_t init)
21955
    {
21956
        push_back(init);
21957
        return *this;
21958
    }
21959
21960
    /*!
21961
    @brief add an object to an array
21962
21963
    Creates a JSON value from the passed parameters @a args to the end of the
21964
    JSON value. If the function is called on a JSON null value, an empty array
21965
    is created before appending the value created from @a args.
21966
21967
    @param[in] args arguments to forward to a constructor of @ref basic_json
21968
    @tparam Args compatible types to create a @ref basic_json object
21969
21970
    @return reference to the inserted element
21971
21972
    @throw type_error.311 when called on a type other than JSON array or
21973
    null; example: `"cannot use emplace_back() with number"`
21974
21975
    @complexity Amortized constant.
21976
21977
    @liveexample{The example shows how `push_back()` can be used to add
21978
    elements to a JSON array. Note how the `null` value was silently converted
21979
    to a JSON array.,emplace_back}
21980
21981
    @since version 2.0.8, returns reference since 3.7.0
21982
    */
21983
    template<class... Args>
21984
    reference emplace_back(Args&& ... args)
21985
    {
21986
        // emplace_back only works for null objects or arrays
21987
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21988
        {
21989
            JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21990
        }
21991
21992
        // transform null object into an array
21993
        if (is_null())
21994
        {
21995
            m_type = value_t::array;
21996
            m_value = value_t::array;
21997
            assert_invariant();
21998
        }
21999
22000
        // add element to array (perfect forwarding)
22001
#ifdef JSON_HAS_CPP_17
22002
        return m_value.array->emplace_back(std::forward<Args>(args)...);
22003
#else
22004
        m_value.array->emplace_back(std::forward<Args>(args)...);
22005
        return m_value.array->back();
22006
#endif
22007
    }
22008
22009
    /*!
22010
    @brief add an object to an object if key does not exist
22011
22012
    Inserts a new element into a JSON object constructed in-place with the
22013
    given @a args if there is no element with the key in the container. If the
22014
    function is called on a JSON null value, an empty object is created before
22015
    appending the value created from @a args.
22016
22017
    @param[in] args arguments to forward to a constructor of @ref basic_json
22018
    @tparam Args compatible types to create a @ref basic_json object
22019
22020
    @return a pair consisting of an iterator to the inserted element, or the
22021
            already-existing element if no insertion happened, and a bool
22022
            denoting whether the insertion took place.
22023
22024
    @throw type_error.311 when called on a type other than JSON object or
22025
    null; example: `"cannot use emplace() with number"`
22026
22027
    @complexity Logarithmic in the size of the container, O(log(`size()`)).
22028
22029
    @liveexample{The example shows how `emplace()` can be used to add elements
22030
    to a JSON object. Note how the `null` value was silently converted to a
22031
    JSON object. Further note how no value is added if there was already one
22032
    value stored with the same key.,emplace}
22033
22034
    @since version 2.0.8
22035
    */
22036
    template<class... Args>
22037
    std::pair<iterator, bool> emplace(Args&& ... args)
22038
    {
22039
        // emplace only works for null objects or arrays
22040
        if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22041
        {
22042
            JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
22043
        }
22044
22045
        // transform null object into an object
22046
        if (is_null())
22047
        {
22048
            m_type = value_t::object;
22049
            m_value = value_t::object;
22050
            assert_invariant();
22051
        }
22052
22053
        // add element to array (perfect forwarding)
22054
        auto res = m_value.object->emplace(std::forward<Args>(args)...);
22055
        // create result iterator and set iterator to the result of emplace
22056
        auto it = begin();
22057
        it.m_it.object_iterator = res.first;
22058
22059
        // return pair of iterator and boolean
22060
        return {it, res.second};
22061
    }
22062
22063
    /// Helper for insertion of an iterator
22064
    /// @note: This uses std::distance to support GCC 4.8,
22065
    ///        see https://github.com/nlohmann/json/pull/1257
22066
    template<typename... Args>
22067
    iterator insert_iterator(const_iterator pos, Args&& ... args)
22068
    {
22069
        iterator result(this);
22070
        JSON_ASSERT(m_value.array != nullptr);
22071
22072
        auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22073
        m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22074
        result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22075
22076
        // This could have been written as:
22077
        // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22078
        // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22079
22080
        return result;
22081
    }
22082
22083
    /*!
22084
    @brief inserts element
22085
22086
    Inserts element @a val before iterator @a pos.
22087
22088
    @param[in] pos iterator before which the content will be inserted; may be
22089
    the end() iterator
22090
    @param[in] val element to insert
22091
    @return iterator pointing to the inserted @a val.
22092
22093
    @throw type_error.309 if called on JSON values other than arrays;
22094
    example: `"cannot use insert() with string"`
22095
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22096
    example: `"iterator does not fit current value"`
22097
22098
    @complexity Constant plus linear in the distance between @a pos and end of
22099
    the container.
22100
22101
    @liveexample{The example shows how `insert()` is used.,insert}
22102
22103
    @since version 1.0.0
22104
    */
22105
    iterator insert(const_iterator pos, const basic_json& val)
22106
    {
22107
        // insert only works for arrays
22108
        if (JSON_HEDLEY_LIKELY(is_array()))
22109
        {
22110
            // check if iterator pos fits to this JSON value
22111
            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22112
            {
22113
                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22114
            }
22115
22116
            // insert to array and return iterator
22117
            return insert_iterator(pos, val);
22118
        }
22119
22120
        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22121
    }
22122
22123
    /*!
22124
    @brief inserts element
22125
    @copydoc insert(const_iterator, const basic_json&)
22126
    */
22127
    iterator insert(const_iterator pos, basic_json&& val)
22128
    {
22129
        return insert(pos, val);
22130
    }
22131
22132
    /*!
22133
    @brief inserts elements
22134
22135
    Inserts @a cnt copies of @a val before iterator @a pos.
22136
22137
    @param[in] pos iterator before which the content will be inserted; may be
22138
    the end() iterator
22139
    @param[in] cnt number of copies of @a val to insert
22140
    @param[in] val element to insert
22141
    @return iterator pointing to the first element inserted, or @a pos if
22142
    `cnt==0`
22143
22144
    @throw type_error.309 if called on JSON values other than arrays; example:
22145
    `"cannot use insert() with string"`
22146
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22147
    example: `"iterator does not fit current value"`
22148
22149
    @complexity Linear in @a cnt plus linear in the distance between @a pos
22150
    and end of the container.
22151
22152
    @liveexample{The example shows how `insert()` is used.,insert__count}
22153
22154
    @since version 1.0.0
22155
    */
22156
    iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22157
    {
22158
        // insert only works for arrays
22159
        if (JSON_HEDLEY_LIKELY(is_array()))
22160
        {
22161
            // check if iterator pos fits to this JSON value
22162
            if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22163
            {
22164
                JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22165
            }
22166
22167
            // insert to array and return iterator
22168
            return insert_iterator(pos, cnt, val);
22169
        }
22170
22171
        JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22172
    }
22173
22174
    /*!
22175
    @brief inserts elements
22176
22177
    Inserts elements from range `[first, last)` before iterator @a pos.
22178
22179
    @param[in] pos iterator before which the content will be inserted; may be
22180
    the end() iterator
22181
    @param[in] first begin of the range of elements to insert
22182
    @param[in] last end of the range of elements to insert
22183
22184
    @throw type_error.309 if called on JSON values other than arrays; example:
22185
    `"cannot use insert() with string"`
22186
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22187
    example: `"iterator does not fit current value"`
22188
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
22189
    same JSON value; example: `"iterators do not fit"`
22190
    @throw invalid_iterator.211 if @a first or @a last are iterators into
22191
    container for which insert is called; example: `"passed iterators may not
22192
    belong to container"`
22193
22194
    @return iterator pointing to the first element inserted, or @a pos if
22195
    `first==last`
22196
22197
    @complexity Linear in `std::distance(first, last)` plus linear in the
22198
    distance between @a pos and end of the container.
22199
22200
    @liveexample{The example shows how `insert()` is used.,insert__range}
22201
22202
    @since version 1.0.0
22203
    */
22204
    iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22205
    {
22206
        // insert only works for arrays
22207
        if (JSON_HEDLEY_UNLIKELY(!is_array()))
22208
        {
22209
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22210
        }
22211
22212
        // check if iterator pos fits to this JSON value
22213
        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22214
        {
22215
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22216
        }
22217
22218
        // check if range iterators belong to the same JSON object
22219
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22220
        {
22221
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22222
        }
22223
22224
        if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22225
        {
22226
            JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22227
        }
22228
22229
        // insert to array and return iterator
22230
        return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22231
    }
22232
22233
    /*!
22234
    @brief inserts elements
22235
22236
    Inserts elements from initializer list @a ilist before iterator @a pos.
22237
22238
    @param[in] pos iterator before which the content will be inserted; may be
22239
    the end() iterator
22240
    @param[in] ilist initializer list to insert the values from
22241
22242
    @throw type_error.309 if called on JSON values other than arrays; example:
22243
    `"cannot use insert() with string"`
22244
    @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22245
    example: `"iterator does not fit current value"`
22246
22247
    @return iterator pointing to the first element inserted, or @a pos if
22248
    `ilist` is empty
22249
22250
    @complexity Linear in `ilist.size()` plus linear in the distance between
22251
    @a pos and end of the container.
22252
22253
    @liveexample{The example shows how `insert()` is used.,insert__ilist}
22254
22255
    @since version 1.0.0
22256
    */
22257
    iterator insert(const_iterator pos, initializer_list_t ilist)
22258
    {
22259
        // insert only works for arrays
22260
        if (JSON_HEDLEY_UNLIKELY(!is_array()))
22261
        {
22262
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22263
        }
22264
22265
        // check if iterator pos fits to this JSON value
22266
        if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22267
        {
22268
            JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22269
        }
22270
22271
        // insert to array and return iterator
22272
        return insert_iterator(pos, ilist.begin(), ilist.end());
22273
    }
22274
22275
    /*!
22276
    @brief inserts elements
22277
22278
    Inserts elements from range `[first, last)`.
22279
22280
    @param[in] first begin of the range of elements to insert
22281
    @param[in] last end of the range of elements to insert
22282
22283
    @throw type_error.309 if called on JSON values other than objects; example:
22284
    `"cannot use insert() with string"`
22285
    @throw invalid_iterator.202 if iterator @a first or @a last does does not
22286
    point to an object; example: `"iterators first and last must point to
22287
    objects"`
22288
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
22289
    same JSON value; example: `"iterators do not fit"`
22290
22291
    @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
22292
    of elements to insert.
22293
22294
    @liveexample{The example shows how `insert()` is used.,insert__range_object}
22295
22296
    @since version 3.0.0
22297
    */
22298
    void insert(const_iterator first, const_iterator last)
22299
    {
22300
        // insert only works for objects
22301
        if (JSON_HEDLEY_UNLIKELY(!is_object()))
22302
        {
22303
            JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22304
        }
22305
22306
        // check if range iterators belong to the same JSON object
22307
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22308
        {
22309
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22310
        }
22311
22312
        // passed iterators must belong to objects
22313
        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22314
        {
22315
            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22316
        }
22317
22318
        m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22319
    }
22320
22321
    /*!
22322
    @brief updates a JSON object from another object, overwriting existing keys
22323
22324
    Inserts all values from JSON object @a j and overwrites existing keys.
22325
22326
    @param[in] j  JSON object to read values from
22327
22328
    @throw type_error.312 if called on JSON values other than objects; example:
22329
    `"cannot use update() with string"`
22330
22331
    @complexity O(N*log(size() + N)), where N is the number of elements to
22332
                insert.
22333
22334
    @liveexample{The example shows how `update()` is used.,update}
22335
22336
    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
22337
22338
    @since version 3.0.0
22339
    */
22340
    void update(const_reference j)
22341
    {
22342
        // implicitly convert null value to an empty object
22343
        if (is_null())
22344
        {
22345
            m_type = value_t::object;
22346
            m_value.object = create<object_t>();
22347
            assert_invariant();
22348
        }
22349
22350
        if (JSON_HEDLEY_UNLIKELY(!is_object()))
22351
        {
22352
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22353
        }
22354
        if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22355
        {
22356
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22357
        }
22358
22359
        for (auto it = j.cbegin(); it != j.cend(); ++it)
22360
        {
22361
            m_value.object->operator[](it.key()) = it.value();
22362
        }
22363
    }
22364
22365
    /*!
22366
    @brief updates a JSON object from another object, overwriting existing keys
22367
22368
    Inserts all values from from range `[first, last)` and overwrites existing
22369
    keys.
22370
22371
    @param[in] first begin of the range of elements to insert
22372
    @param[in] last end of the range of elements to insert
22373
22374
    @throw type_error.312 if called on JSON values other than objects; example:
22375
    `"cannot use update() with string"`
22376
    @throw invalid_iterator.202 if iterator @a first or @a last does does not
22377
    point to an object; example: `"iterators first and last must point to
22378
    objects"`
22379
    @throw invalid_iterator.210 if @a first and @a last do not belong to the
22380
    same JSON value; example: `"iterators do not fit"`
22381
22382
    @complexity O(N*log(size() + N)), where N is the number of elements to
22383
                insert.
22384
22385
    @liveexample{The example shows how `update()` is used__range.,update}
22386
22387
    @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
22388
22389
    @since version 3.0.0
22390
    */
22391
    void update(const_iterator first, const_iterator last)
22392
    {
22393
        // implicitly convert null value to an empty object
22394
        if (is_null())
22395
        {
22396
            m_type = value_t::object;
22397
            m_value.object = create<object_t>();
22398
            assert_invariant();
22399
        }
22400
22401
        if (JSON_HEDLEY_UNLIKELY(!is_object()))
22402
        {
22403
            JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22404
        }
22405
22406
        // check if range iterators belong to the same JSON object
22407
        if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22408
        {
22409
            JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22410
        }
22411
22412
        // passed iterators must belong to objects
22413
        if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22414
                                 || !last.m_object->is_object()))
22415
        {
22416
            JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22417
        }
22418
22419
        for (auto it = first; it != last; ++it)
22420
        {
22421
            m_value.object->operator[](it.key()) = it.value();
22422
        }
22423
    }
22424
22425
    /*!
22426
    @brief exchanges the values
22427
22428
    Exchanges the contents of the JSON value with those of @a other. Does not
22429
    invoke any move, copy, or swap operations on individual elements. All
22430
    iterators and references remain valid. The past-the-end iterator is
22431
    invalidated.
22432
22433
    @param[in,out] other JSON value to exchange the contents with
22434
22435
    @complexity Constant.
22436
22437
    @liveexample{The example below shows how JSON values can be swapped with
22438
    `swap()`.,swap__reference}
22439
22440
    @since version 1.0.0
22441
    */
22442
    void swap(reference other) noexcept (
22443
        std::is_nothrow_move_constructible<value_t>::value&&
22444
        std::is_nothrow_move_assignable<value_t>::value&&
22445
        std::is_nothrow_move_constructible<json_value>::value&&
22446
        std::is_nothrow_move_assignable<json_value>::value
22447
    )
22448
0
    {
22449
0
        std::swap(m_type, other.m_type);
22450
0
        std::swap(m_value, other.m_value);
22451
0
        assert_invariant();
22452
0
    }
22453
22454
    /*!
22455
    @brief exchanges the values
22456
22457
    Exchanges the contents of the JSON value from @a left with those of @a right. Does not
22458
    invoke any move, copy, or swap operations on individual elements. All
22459
    iterators and references remain valid. The past-the-end iterator is
22460
    invalidated. implemented as a friend function callable via ADL.
22461
22462
    @param[in,out] left JSON value to exchange the contents with
22463
    @param[in,out] right JSON value to exchange the contents with
22464
22465
    @complexity Constant.
22466
22467
    @liveexample{The example below shows how JSON values can be swapped with
22468
    `swap()`.,swap__reference}
22469
22470
    @since version 1.0.0
22471
    */
22472
    friend void swap(reference left, reference right) noexcept (
22473
        std::is_nothrow_move_constructible<value_t>::value&&
22474
        std::is_nothrow_move_assignable<value_t>::value&&
22475
        std::is_nothrow_move_constructible<json_value>::value&&
22476
        std::is_nothrow_move_assignable<json_value>::value
22477
    )
22478
    {
22479
        left.swap(right);
22480
    }
22481
22482
    /*!
22483
    @brief exchanges the values
22484
22485
    Exchanges the contents of a JSON array with those of @a other. Does not
22486
    invoke any move, copy, or swap operations on individual elements. All
22487
    iterators and references remain valid. The past-the-end iterator is
22488
    invalidated.
22489
22490
    @param[in,out] other array to exchange the contents with
22491
22492
    @throw type_error.310 when JSON value is not an array; example: `"cannot
22493
    use swap() with string"`
22494
22495
    @complexity Constant.
22496
22497
    @liveexample{The example below shows how arrays can be swapped with
22498
    `swap()`.,swap__array_t}
22499
22500
    @since version 1.0.0
22501
    */
22502
    void swap(array_t& other)
22503
    {
22504
        // swap only works for arrays
22505
        if (JSON_HEDLEY_LIKELY(is_array()))
22506
        {
22507
            std::swap(*(m_value.array), other);
22508
        }
22509
        else
22510
        {
22511
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22512
        }
22513
    }
22514
22515
    /*!
22516
    @brief exchanges the values
22517
22518
    Exchanges the contents of a JSON object with those of @a other. Does not
22519
    invoke any move, copy, or swap operations on individual elements. All
22520
    iterators and references remain valid. The past-the-end iterator is
22521
    invalidated.
22522
22523
    @param[in,out] other object to exchange the contents with
22524
22525
    @throw type_error.310 when JSON value is not an object; example:
22526
    `"cannot use swap() with string"`
22527
22528
    @complexity Constant.
22529
22530
    @liveexample{The example below shows how objects can be swapped with
22531
    `swap()`.,swap__object_t}
22532
22533
    @since version 1.0.0
22534
    */
22535
    void swap(object_t& other)
22536
    {
22537
        // swap only works for objects
22538
        if (JSON_HEDLEY_LIKELY(is_object()))
22539
        {
22540
            std::swap(*(m_value.object), other);
22541
        }
22542
        else
22543
        {
22544
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22545
        }
22546
    }
22547
22548
    /*!
22549
    @brief exchanges the values
22550
22551
    Exchanges the contents of a JSON string with those of @a other. Does not
22552
    invoke any move, copy, or swap operations on individual elements. All
22553
    iterators and references remain valid. The past-the-end iterator is
22554
    invalidated.
22555
22556
    @param[in,out] other string to exchange the contents with
22557
22558
    @throw type_error.310 when JSON value is not a string; example: `"cannot
22559
    use swap() with boolean"`
22560
22561
    @complexity Constant.
22562
22563
    @liveexample{The example below shows how strings can be swapped with
22564
    `swap()`.,swap__string_t}
22565
22566
    @since version 1.0.0
22567
    */
22568
    void swap(string_t& other)
22569
    {
22570
        // swap only works for strings
22571
        if (JSON_HEDLEY_LIKELY(is_string()))
22572
        {
22573
            std::swap(*(m_value.string), other);
22574
        }
22575
        else
22576
        {
22577
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22578
        }
22579
    }
22580
22581
    /*!
22582
    @brief exchanges the values
22583
22584
    Exchanges the contents of a JSON string with those of @a other. Does not
22585
    invoke any move, copy, or swap operations on individual elements. All
22586
    iterators and references remain valid. The past-the-end iterator is
22587
    invalidated.
22588
22589
    @param[in,out] other binary to exchange the contents with
22590
22591
    @throw type_error.310 when JSON value is not a string; example: `"cannot
22592
    use swap() with boolean"`
22593
22594
    @complexity Constant.
22595
22596
    @liveexample{The example below shows how strings can be swapped with
22597
    `swap()`.,swap__binary_t}
22598
22599
    @since version 3.8.0
22600
    */
22601
    void swap(binary_t& other)
22602
    {
22603
        // swap only works for strings
22604
        if (JSON_HEDLEY_LIKELY(is_binary()))
22605
        {
22606
            std::swap(*(m_value.binary), other);
22607
        }
22608
        else
22609
        {
22610
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22611
        }
22612
    }
22613
22614
    /// @copydoc swap(binary_t)
22615
    void swap(typename binary_t::container_type& other)
22616
    {
22617
        // swap only works for strings
22618
        if (JSON_HEDLEY_LIKELY(is_binary()))
22619
        {
22620
            std::swap(*(m_value.binary), other);
22621
        }
22622
        else
22623
        {
22624
            JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22625
        }
22626
    }
22627
22628
    /// @}
22629
22630
  public:
22631
    //////////////////////////////////////////
22632
    // lexicographical comparison operators //
22633
    //////////////////////////////////////////
22634
22635
    /// @name lexicographical comparison operators
22636
    /// @{
22637
22638
    /*!
22639
    @brief comparison: equal
22640
22641
    Compares two JSON values for equality according to the following rules:
22642
    - Two JSON values are equal if (1) they are from the same type and (2)
22643
      their stored values are the same according to their respective
22644
      `operator==`.
22645
    - Integer and floating-point numbers are automatically converted before
22646
      comparison. Note that two NaN values are always treated as unequal.
22647
    - Two JSON null values are equal.
22648
22649
    @note Floating-point inside JSON values numbers are compared with
22650
    `json::number_float_t::operator==` which is `double::operator==` by
22651
    default. To compare floating-point while respecting an epsilon, an alternative
22652
    [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
22653
    could be used, for instance
22654
    @code {.cpp}
22655
    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
22656
    inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
22657
    {
22658
        return std::abs(a - b) <= epsilon;
22659
    }
22660
    @endcode
22661
    Or you can self-defined operator equal function like this:
22662
    @code {.cpp}
22663
    bool my_equal(const_reference lhs, const_reference rhs) {
22664
    const auto lhs_type lhs.type();
22665
    const auto rhs_type rhs.type();
22666
    if (lhs_type == rhs_type) {
22667
        switch(lhs_type)
22668
            // self_defined case
22669
            case value_t::number_float:
22670
                return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
22671
            // other cases remain the same with the original
22672
            ...
22673
    }
22674
    ...
22675
    }
22676
    @endcode
22677
22678
    @note NaN values never compare equal to themselves or to other NaN values.
22679
22680
    @param[in] lhs  first JSON value to consider
22681
    @param[in] rhs  second JSON value to consider
22682
    @return whether the values @a lhs and @a rhs are equal
22683
22684
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
22685
22686
    @complexity Linear.
22687
22688
    @liveexample{The example demonstrates comparing several JSON
22689
    types.,operator__equal}
22690
22691
    @since version 1.0.0
22692
    */
22693
    friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22694
0
    {
22695
0
        const auto lhs_type = lhs.type();
22696
0
        const auto rhs_type = rhs.type();
22697
22698
0
        if (lhs_type == rhs_type)
22699
0
        {
22700
0
            switch (lhs_type)
22701
0
            {
22702
0
                case value_t::array:
22703
0
                    return *lhs.m_value.array == *rhs.m_value.array;
22704
22705
0
                case value_t::object:
22706
0
                    return *lhs.m_value.object == *rhs.m_value.object;
22707
22708
0
                case value_t::null:
22709
0
                    return true;
22710
22711
0
                case value_t::string:
22712
0
                    return *lhs.m_value.string == *rhs.m_value.string;
22713
22714
0
                case value_t::boolean:
22715
0
                    return lhs.m_value.boolean == rhs.m_value.boolean;
22716
22717
0
                case value_t::number_integer:
22718
0
                    return lhs.m_value.number_integer == rhs.m_value.number_integer;
22719
22720
0
                case value_t::number_unsigned:
22721
0
                    return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22722
22723
0
                case value_t::number_float:
22724
0
                    return lhs.m_value.number_float == rhs.m_value.number_float;
22725
22726
0
                case value_t::binary:
22727
0
                    return *lhs.m_value.binary == *rhs.m_value.binary;
22728
22729
0
                default:
22730
0
                    return false;
22731
0
            }
22732
0
        }
22733
0
        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22734
0
        {
22735
0
            return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22736
0
        }
22737
0
        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22738
0
        {
22739
0
            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22740
0
        }
22741
0
        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22742
0
        {
22743
0
            return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22744
0
        }
22745
0
        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22746
0
        {
22747
0
            return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22748
0
        }
22749
0
        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22750
0
        {
22751
0
            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22752
0
        }
22753
0
        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22754
0
        {
22755
0
            return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22756
0
        }
22757
22758
0
        return false;
22759
0
    }
22760
22761
    /*!
22762
    @brief comparison: equal
22763
    @copydoc operator==(const_reference, const_reference)
22764
    */
22765
    template<typename ScalarType, typename std::enable_if<
22766
                 std::is_scalar<ScalarType>::value, int>::type = 0>
22767
    friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22768
    {
22769
        return lhs == basic_json(rhs);
22770
    }
22771
22772
    /*!
22773
    @brief comparison: equal
22774
    @copydoc operator==(const_reference, const_reference)
22775
    */
22776
    template<typename ScalarType, typename std::enable_if<
22777
                 std::is_scalar<ScalarType>::value, int>::type = 0>
22778
    friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22779
    {
22780
        return basic_json(lhs) == rhs;
22781
    }
22782
22783
    /*!
22784
    @brief comparison: not equal
22785
22786
    Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
22787
22788
    @param[in] lhs  first JSON value to consider
22789
    @param[in] rhs  second JSON value to consider
22790
    @return whether the values @a lhs and @a rhs are not equal
22791
22792
    @complexity Linear.
22793
22794
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
22795
22796
    @liveexample{The example demonstrates comparing several JSON
22797
    types.,operator__notequal}
22798
22799
    @since version 1.0.0
22800
    */
22801
    friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22802
0
    {
22803
0
        return !(lhs == rhs);
22804
0
    }
22805
22806
    /*!
22807
    @brief comparison: not equal
22808
    @copydoc operator!=(const_reference, const_reference)
22809
    */
22810
    template<typename ScalarType, typename std::enable_if<
22811
                 std::is_scalar<ScalarType>::value, int>::type = 0>
22812
    friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22813
    {
22814
        return lhs != basic_json(rhs);
22815
    }
22816
22817
    /*!
22818
    @brief comparison: not equal
22819
    @copydoc operator!=(const_reference, const_reference)
22820
    */
22821
    template<typename ScalarType, typename std::enable_if<
22822
                 std::is_scalar<ScalarType>::value, int>::type = 0>
22823
    friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22824
    {
22825
        return basic_json(lhs) != rhs;
22826
    }
22827
22828
    /*!
22829
    @brief comparison: less than
22830
22831
    Compares whether one JSON value @a lhs is less than another JSON value @a
22832
    rhs according to the following rules:
22833
    - If @a lhs and @a rhs have the same type, the values are compared using
22834
      the default `<` operator.
22835
    - Integer and floating-point numbers are automatically converted before
22836
      comparison
22837
    - In case @a lhs and @a rhs have different types, the values are ignored
22838
      and the order of the types is considered, see
22839
      @ref operator<(const value_t, const value_t).
22840
22841
    @param[in] lhs  first JSON value to consider
22842
    @param[in] rhs  second JSON value to consider
22843
    @return whether @a lhs is less than @a rhs
22844
22845
    @complexity Linear.
22846
22847
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
22848
22849
    @liveexample{The example demonstrates comparing several JSON
22850
    types.,operator__less}
22851
22852
    @since version 1.0.0
22853
    */
22854
    friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22855
    {
22856
        const auto lhs_type = lhs.type();
22857
        const auto rhs_type = rhs.type();
22858
22859
        if (lhs_type == rhs_type)
22860
        {
22861
            switch (lhs_type)
22862
            {
22863
                case value_t::array:
22864
                    // note parentheses are necessary, see
22865
                    // https://github.com/nlohmann/json/issues/1530
22866
                    return (*lhs.m_value.array) < (*rhs.m_value.array);
22867
22868
                case value_t::object:
22869
                    return (*lhs.m_value.object) < (*rhs.m_value.object);
22870
22871
                case value_t::null:
22872
                    return false;
22873
22874
                case value_t::string:
22875
                    return (*lhs.m_value.string) < (*rhs.m_value.string);
22876
22877
                case value_t::boolean:
22878
                    return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22879
22880
                case value_t::number_integer:
22881
                    return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22882
22883
                case value_t::number_unsigned:
22884
                    return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22885
22886
                case value_t::number_float:
22887
                    return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22888
22889
                case value_t::binary:
22890
                    return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22891
22892
                default:
22893
                    return false;
22894
            }
22895
        }
22896
        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22897
        {
22898
            return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22899
        }
22900
        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22901
        {
22902
            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22903
        }
22904
        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22905
        {
22906
            return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22907
        }
22908
        else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22909
        {
22910
            return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22911
        }
22912
        else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22913
        {
22914
            return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22915
        }
22916
        else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22917
        {
22918
            return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22919
        }
22920
22921
        // We only reach this line if we cannot compare values. In that case,
22922
        // we compare types. Note we have to call the operator explicitly,
22923
        // because MSVC has problems otherwise.
22924
        return operator<(lhs_type, rhs_type);
22925
    }
22926
22927
    /*!
22928
    @brief comparison: less than
22929
    @copydoc operator<(const_reference, const_reference)
22930
    */
22931
    template<typename ScalarType, typename std::enable_if<
22932
                 std::is_scalar<ScalarType>::value, int>::type = 0>
22933
    friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22934
    {
22935
        return lhs < basic_json(rhs);
22936
    }
22937
22938
    /*!
22939
    @brief comparison: less than
22940
    @copydoc operator<(const_reference, const_reference)
22941
    */
22942
    template<typename ScalarType, typename std::enable_if<
22943
                 std::is_scalar<ScalarType>::value, int>::type = 0>
22944
    friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22945
    {
22946
        return basic_json(lhs) < rhs;
22947
    }
22948
22949
    /*!
22950
    @brief comparison: less than or equal
22951
22952
    Compares whether one JSON value @a lhs is less than or equal to another
22953
    JSON value by calculating `not (rhs < lhs)`.
22954
22955
    @param[in] lhs  first JSON value to consider
22956
    @param[in] rhs  second JSON value to consider
22957
    @return whether @a lhs is less than or equal to @a rhs
22958
22959
    @complexity Linear.
22960
22961
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
22962
22963
    @liveexample{The example demonstrates comparing several JSON
22964
    types.,operator__greater}
22965
22966
    @since version 1.0.0
22967
    */
22968
    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22969
    {
22970
        return !(rhs < lhs);
22971
    }
22972
22973
    /*!
22974
    @brief comparison: less than or equal
22975
    @copydoc operator<=(const_reference, const_reference)
22976
    */
22977
    template<typename ScalarType, typename std::enable_if<
22978
                 std::is_scalar<ScalarType>::value, int>::type = 0>
22979
    friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22980
    {
22981
        return lhs <= basic_json(rhs);
22982
    }
22983
22984
    /*!
22985
    @brief comparison: less than or equal
22986
    @copydoc operator<=(const_reference, const_reference)
22987
    */
22988
    template<typename ScalarType, typename std::enable_if<
22989
                 std::is_scalar<ScalarType>::value, int>::type = 0>
22990
    friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22991
    {
22992
        return basic_json(lhs) <= rhs;
22993
    }
22994
22995
    /*!
22996
    @brief comparison: greater than
22997
22998
    Compares whether one JSON value @a lhs is greater than another
22999
    JSON value by calculating `not (lhs <= rhs)`.
23000
23001
    @param[in] lhs  first JSON value to consider
23002
    @param[in] rhs  second JSON value to consider
23003
    @return whether @a lhs is greater than to @a rhs
23004
23005
    @complexity Linear.
23006
23007
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
23008
23009
    @liveexample{The example demonstrates comparing several JSON
23010
    types.,operator__lessequal}
23011
23012
    @since version 1.0.0
23013
    */
23014
    friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23015
    {
23016
        return !(lhs <= rhs);
23017
    }
23018
23019
    /*!
23020
    @brief comparison: greater than
23021
    @copydoc operator>(const_reference, const_reference)
23022
    */
23023
    template<typename ScalarType, typename std::enable_if<
23024
                 std::is_scalar<ScalarType>::value, int>::type = 0>
23025
    friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
23026
    {
23027
        return lhs > basic_json(rhs);
23028
    }
23029
23030
    /*!
23031
    @brief comparison: greater than
23032
    @copydoc operator>(const_reference, const_reference)
23033
    */
23034
    template<typename ScalarType, typename std::enable_if<
23035
                 std::is_scalar<ScalarType>::value, int>::type = 0>
23036
    friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
23037
    {
23038
        return basic_json(lhs) > rhs;
23039
    }
23040
23041
    /*!
23042
    @brief comparison: greater than or equal
23043
23044
    Compares whether one JSON value @a lhs is greater than or equal to another
23045
    JSON value by calculating `not (lhs < rhs)`.
23046
23047
    @param[in] lhs  first JSON value to consider
23048
    @param[in] rhs  second JSON value to consider
23049
    @return whether @a lhs is greater than or equal to @a rhs
23050
23051
    @complexity Linear.
23052
23053
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
23054
23055
    @liveexample{The example demonstrates comparing several JSON
23056
    types.,operator__greaterequal}
23057
23058
    @since version 1.0.0
23059
    */
23060
    friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23061
    {
23062
        return !(lhs < rhs);
23063
    }
23064
23065
    /*!
23066
    @brief comparison: greater than or equal
23067
    @copydoc operator>=(const_reference, const_reference)
23068
    */
23069
    template<typename ScalarType, typename std::enable_if<
23070
                 std::is_scalar<ScalarType>::value, int>::type = 0>
23071
    friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
23072
    {
23073
        return lhs >= basic_json(rhs);
23074
    }
23075
23076
    /*!
23077
    @brief comparison: greater than or equal
23078
    @copydoc operator>=(const_reference, const_reference)
23079
    */
23080
    template<typename ScalarType, typename std::enable_if<
23081
                 std::is_scalar<ScalarType>::value, int>::type = 0>
23082
    friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
23083
    {
23084
        return basic_json(lhs) >= rhs;
23085
    }
23086
23087
    /// @}
23088
23089
    ///////////////////
23090
    // serialization //
23091
    ///////////////////
23092
23093
    /// @name serialization
23094
    /// @{
23095
23096
    /*!
23097
    @brief serialize to stream
23098
23099
    Serialize the given JSON value @a j to the output stream @a o. The JSON
23100
    value will be serialized using the @ref dump member function.
23101
23102
    - The indentation of the output can be controlled with the member variable
23103
      `width` of the output stream @a o. For instance, using the manipulator
23104
      `std::setw(4)` on @a o sets the indentation level to `4` and the
23105
      serialization result is the same as calling `dump(4)`.
23106
23107
    - The indentation character can be controlled with the member variable
23108
      `fill` of the output stream @a o. For instance, the manipulator
23109
      `std::setfill('\\t')` sets indentation to use a tab character rather than
23110
      the default space character.
23111
23112
    @param[in,out] o  stream to serialize to
23113
    @param[in] j  JSON value to serialize
23114
23115
    @return the stream @a o
23116
23117
    @throw type_error.316 if a string stored inside the JSON value is not
23118
                          UTF-8 encoded
23119
23120
    @complexity Linear.
23121
23122
    @liveexample{The example below shows the serialization with different
23123
    parameters to `width` to adjust the indentation level.,operator_serialize}
23124
23125
    @since version 1.0.0; indentation character added in version 3.0.0
23126
    */
23127
    friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23128
0
    {
23129
        // read width member and use it as indentation parameter if nonzero
23130
0
        const bool pretty_print = o.width() > 0;
23131
0
        const auto indentation = pretty_print ? o.width() : 0;
23132
23133
        // reset width to 0 for subsequent calls to this stream
23134
0
        o.width(0);
23135
23136
        // do the actual serialization
23137
0
        serializer s(detail::output_adapter<char>(o), o.fill());
23138
0
        s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23139
0
        return o;
23140
0
    }
23141
23142
    /*!
23143
    @brief serialize to stream
23144
    @deprecated This stream operator is deprecated and will be removed in
23145
                future 4.0.0 of the library. Please use
23146
                @ref operator<<(std::ostream&, const basic_json&)
23147
                instead; that is, replace calls like `j >> o;` with `o << j;`.
23148
    @since version 1.0.0; deprecated since version 3.0.0
23149
    */
23150
    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23151
    friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23152
    {
23153
        return o << j;
23154
    }
23155
23156
    /// @}
23157
23158
23159
    /////////////////////
23160
    // deserialization //
23161
    /////////////////////
23162
23163
    /// @name deserialization
23164
    /// @{
23165
23166
    /*!
23167
    @brief deserialize from a compatible input
23168
23169
    @tparam InputType A compatible input, for instance
23170
    - an std::istream object
23171
    - a FILE pointer
23172
    - a C-style array of characters
23173
    - a pointer to a null-terminated string of single byte characters
23174
    - an object obj for which begin(obj) and end(obj) produces a valid pair of
23175
      iterators.
23176
23177
    @param[in] i  input to read from
23178
    @param[in] cb  a parser callback function of type @ref parser_callback_t
23179
    which is used to control the deserialization by filtering unwanted values
23180
    (optional)
23181
    @param[in] allow_exceptions  whether to throw exceptions in case of a
23182
    parse error (optional, true by default)
23183
    @param[in] ignore_comments  whether comments should be ignored and treated
23184
    like whitespace (true) or yield a parse error (true); (optional, false by
23185
    default)
23186
23187
    @return deserialized JSON value; in case of a parse error and
23188
            @a allow_exceptions set to `false`, the return value will be
23189
            value_t::discarded.
23190
23191
    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23192
    of input; expected string literal""`
23193
    @throw parse_error.102 if to_unicode fails or surrogate error
23194
    @throw parse_error.103 if to_unicode fails
23195
23196
    @complexity Linear in the length of the input. The parser is a predictive
23197
    LL(1) parser. The complexity can be higher if the parser callback function
23198
    @a cb or reading from the input @a i has a super-linear complexity.
23199
23200
    @note A UTF-8 byte order mark is silently ignored.
23201
23202
    @liveexample{The example below demonstrates the `parse()` function reading
23203
    from an array.,parse__array__parser_callback_t}
23204
23205
    @liveexample{The example below demonstrates the `parse()` function with
23206
    and without callback function.,parse__string__parser_callback_t}
23207
23208
    @liveexample{The example below demonstrates the `parse()` function with
23209
    and without callback function.,parse__istream__parser_callback_t}
23210
23211
    @liveexample{The example below demonstrates the `parse()` function reading
23212
    from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
23213
23214
    @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
23215
    ignore comments.
23216
    */
23217
    template<typename InputType>
23218
    JSON_HEDLEY_WARN_UNUSED_RESULT
23219
    static basic_json parse(InputType&& i,
23220
                            const parser_callback_t cb = nullptr,
23221
                            const bool allow_exceptions = true,
23222
                            const bool ignore_comments = false)
23223
    {
23224
        basic_json result;
23225
        parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23226
        return result;
23227
    }
23228
23229
    /*!
23230
    @brief deserialize from a pair of character iterators
23231
23232
    The value_type of the iterator must be a integral type with size of 1, 2 or
23233
    4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
23234
23235
    @param[in] first iterator to start of character range
23236
    @param[in] last  iterator to end of character range
23237
    @param[in] cb  a parser callback function of type @ref parser_callback_t
23238
    which is used to control the deserialization by filtering unwanted values
23239
    (optional)
23240
    @param[in] allow_exceptions  whether to throw exceptions in case of a
23241
    parse error (optional, true by default)
23242
    @param[in] ignore_comments  whether comments should be ignored and treated
23243
    like whitespace (true) or yield a parse error (true); (optional, false by
23244
    default)
23245
23246
    @return deserialized JSON value; in case of a parse error and
23247
            @a allow_exceptions set to `false`, the return value will be
23248
            value_t::discarded.
23249
23250
    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23251
    of input; expected string literal""`
23252
    @throw parse_error.102 if to_unicode fails or surrogate error
23253
    @throw parse_error.103 if to_unicode fails
23254
    */
23255
    template<typename IteratorType>
23256
    JSON_HEDLEY_WARN_UNUSED_RESULT
23257
    static basic_json parse(IteratorType first,
23258
                            IteratorType last,
23259
                            const parser_callback_t cb = nullptr,
23260
                            const bool allow_exceptions = true,
23261
                            const bool ignore_comments = false)
23262
0
    {
23263
0
        basic_json result;
23264
0
        parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23265
0
        return result;
23266
0
    }
23267
23268
    JSON_HEDLEY_WARN_UNUSED_RESULT
23269
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23270
    static basic_json parse(detail::span_input_adapter&& i,
23271
                            const parser_callback_t cb = nullptr,
23272
                            const bool allow_exceptions = true,
23273
                            const bool ignore_comments = false)
23274
    {
23275
        basic_json result;
23276
        parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23277
        return result;
23278
    }
23279
23280
    /*!
23281
    @brief check if the input is valid JSON
23282
23283
    Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
23284
    function, this function neither throws an exception in case of invalid JSON
23285
    input (i.e., a parse error) nor creates diagnostic information.
23286
23287
    @tparam InputType A compatible input, for instance
23288
    - an std::istream object
23289
    - a FILE pointer
23290
    - a C-style array of characters
23291
    - a pointer to a null-terminated string of single byte characters
23292
    - an object obj for which begin(obj) and end(obj) produces a valid pair of
23293
      iterators.
23294
23295
    @param[in] i input to read from
23296
    @param[in] ignore_comments  whether comments should be ignored and treated
23297
    like whitespace (true) or yield a parse error (true); (optional, false by
23298
    default)
23299
23300
    @return Whether the input read from @a i is valid JSON.
23301
23302
    @complexity Linear in the length of the input. The parser is a predictive
23303
    LL(1) parser.
23304
23305
    @note A UTF-8 byte order mark is silently ignored.
23306
23307
    @liveexample{The example below demonstrates the `accept()` function reading
23308
    from a string.,accept__string}
23309
    */
23310
    template<typename InputType>
23311
    static bool accept(InputType&& i,
23312
                       const bool ignore_comments = false)
23313
    {
23314
        return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23315
    }
23316
23317
    template<typename IteratorType>
23318
    static bool accept(IteratorType first, IteratorType last,
23319
                       const bool ignore_comments = false)
23320
    {
23321
        return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23322
    }
23323
23324
    JSON_HEDLEY_WARN_UNUSED_RESULT
23325
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23326
    static bool accept(detail::span_input_adapter&& i,
23327
                       const bool ignore_comments = false)
23328
    {
23329
        return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23330
    }
23331
23332
    /*!
23333
    @brief generate SAX events
23334
23335
    The SAX event lister must follow the interface of @ref json_sax.
23336
23337
    This function reads from a compatible input. Examples are:
23338
    - an std::istream object
23339
    - a FILE pointer
23340
    - a C-style array of characters
23341
    - a pointer to a null-terminated string of single byte characters
23342
    - an object obj for which begin(obj) and end(obj) produces a valid pair of
23343
      iterators.
23344
23345
    @param[in] i  input to read from
23346
    @param[in,out] sax  SAX event listener
23347
    @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
23348
    @param[in] strict  whether the input has to be consumed completely
23349
    @param[in] ignore_comments  whether comments should be ignored and treated
23350
    like whitespace (true) or yield a parse error (true); (optional, false by
23351
    default); only applies to the JSON file format.
23352
23353
    @return return value of the last processed SAX event
23354
23355
    @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23356
    of input; expected string literal""`
23357
    @throw parse_error.102 if to_unicode fails or surrogate error
23358
    @throw parse_error.103 if to_unicode fails
23359
23360
    @complexity Linear in the length of the input. The parser is a predictive
23361
    LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
23362
    a super-linear complexity.
23363
23364
    @note A UTF-8 byte order mark is silently ignored.
23365
23366
    @liveexample{The example below demonstrates the `sax_parse()` function
23367
    reading from string and processing the events with a user-defined SAX
23368
    event consumer.,sax_parse}
23369
23370
    @since version 3.2.0
23371
    */
23372
    template <typename InputType, typename SAX>
23373
    JSON_HEDLEY_NON_NULL(2)
23374
    static bool sax_parse(InputType&& i, SAX* sax,
23375
                          input_format_t format = input_format_t::json,
23376
                          const bool strict = true,
23377
                          const bool ignore_comments = false)
23378
    {
23379
        auto ia = detail::input_adapter(std::forward<InputType>(i));
23380
        return format == input_format_t::json
23381
               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23382
               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23383
    }
23384
23385
    template<class IteratorType, class SAX>
23386
    JSON_HEDLEY_NON_NULL(3)
23387
    static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23388
                          input_format_t format = input_format_t::json,
23389
                          const bool strict = true,
23390
                          const bool ignore_comments = false)
23391
    {
23392
        auto ia = detail::input_adapter(std::move(first), std::move(last));
23393
        return format == input_format_t::json
23394
               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23395
               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23396
    }
23397
23398
    template <typename SAX>
23399
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23400
    JSON_HEDLEY_NON_NULL(2)
23401
    static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23402
                          input_format_t format = input_format_t::json,
23403
                          const bool strict = true,
23404
                          const bool ignore_comments = false)
23405
    {
23406
        auto ia = i.get();
23407
        return format == input_format_t::json
23408
               ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23409
               : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23410
    }
23411
23412
    /*!
23413
    @brief deserialize from stream
23414
    @deprecated This stream operator is deprecated and will be removed in
23415
                version 4.0.0 of the library. Please use
23416
                @ref operator>>(std::istream&, basic_json&)
23417
                instead; that is, replace calls like `j << i;` with `i >> j;`.
23418
    @since version 1.0.0; deprecated since version 3.0.0
23419
    */
23420
    JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23421
    friend std::istream& operator<<(basic_json& j, std::istream& i)
23422
    {
23423
        return operator>>(i, j);
23424
    }
23425
23426
    /*!
23427
    @brief deserialize from stream
23428
23429
    Deserializes an input stream to a JSON value.
23430
23431
    @param[in,out] i  input stream to read a serialized JSON value from
23432
    @param[in,out] j  JSON value to write the deserialized input to
23433
23434
    @throw parse_error.101 in case of an unexpected token
23435
    @throw parse_error.102 if to_unicode fails or surrogate error
23436
    @throw parse_error.103 if to_unicode fails
23437
23438
    @complexity Linear in the length of the input. The parser is a predictive
23439
    LL(1) parser.
23440
23441
    @note A UTF-8 byte order mark is silently ignored.
23442
23443
    @liveexample{The example below shows how a JSON value is constructed by
23444
    reading a serialization from a stream.,operator_deserialize}
23445
23446
    @sa parse(std::istream&, const parser_callback_t) for a variant with a
23447
    parser callback function to filter values while parsing
23448
23449
    @since version 1.0.0
23450
    */
23451
    friend std::istream& operator>>(std::istream& i, basic_json& j)
23452
0
    {
23453
0
        parser(detail::input_adapter(i)).parse(false, j);
23454
0
        return i;
23455
0
    }
23456
23457
    /// @}
23458
23459
    ///////////////////////////
23460
    // convenience functions //
23461
    ///////////////////////////
23462
23463
    /*!
23464
    @brief return the type as string
23465
23466
    Returns the type name as string to be used in error messages - usually to
23467
    indicate that a function was called on a wrong JSON type.
23468
23469
    @return a string representation of a the @a m_type member:
23470
            Value type  | return value
23471
            ----------- | -------------
23472
            null        | `"null"`
23473
            boolean     | `"boolean"`
23474
            string      | `"string"`
23475
            number      | `"number"` (for all number types)
23476
            object      | `"object"`
23477
            array       | `"array"`
23478
            binary      | `"binary"`
23479
            discarded   | `"discarded"`
23480
23481
    @exceptionsafety No-throw guarantee: this function never throws exceptions.
23482
23483
    @complexity Constant.
23484
23485
    @liveexample{The following code exemplifies `type_name()` for all JSON
23486
    types.,type_name}
23487
23488
    @sa @ref type() -- return the type of the JSON value
23489
    @sa @ref operator value_t() -- return the type of the JSON value (implicit)
23490
23491
    @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
23492
    since 3.0.0
23493
    */
23494
    JSON_HEDLEY_RETURNS_NON_NULL
23495
    const char* type_name() const noexcept
23496
0
    {
23497
0
        {
23498
0
            switch (m_type)
23499
0
            {
23500
0
                case value_t::null:
23501
0
                    return "null";
23502
0
                case value_t::object:
23503
0
                    return "object";
23504
0
                case value_t::array:
23505
0
                    return "array";
23506
0
                case value_t::string:
23507
0
                    return "string";
23508
0
                case value_t::boolean:
23509
0
                    return "boolean";
23510
0
                case value_t::binary:
23511
0
                    return "binary";
23512
0
                case value_t::discarded:
23513
0
                    return "discarded";
23514
0
                default:
23515
0
                    return "number";
23516
0
            }
23517
0
        }
23518
0
    }
23519
23520
23521
  JSON_PRIVATE_UNLESS_TESTED:
23522
    //////////////////////
23523
    // member variables //
23524
    //////////////////////
23525
23526
    /// the type of the current element
23527
    value_t m_type = value_t::null;
23528
23529
    /// the value of the current element
23530
    json_value m_value = {};
23531
23532
    //////////////////////////////////////////
23533
    // binary serialization/deserialization //
23534
    //////////////////////////////////////////
23535
23536
    /// @name binary serialization/deserialization support
23537
    /// @{
23538
23539
  public:
23540
    /*!
23541
    @brief create a CBOR serialization of a given JSON value
23542
23543
    Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
23544
    Binary Object Representation) serialization format. CBOR is a binary
23545
    serialization format which aims to be more compact than JSON itself, yet
23546
    more efficient to parse.
23547
23548
    The library uses the following mapping from JSON values types to
23549
    CBOR types according to the CBOR specification (RFC 7049):
23550
23551
    JSON value type | value/range                                | CBOR type                          | first byte
23552
    --------------- | ------------------------------------------ | ---------------------------------- | ---------------
23553
    null            | `null`                                     | Null                               | 0xF6
23554
    boolean         | `true`                                     | True                               | 0xF5
23555
    boolean         | `false`                                    | False                              | 0xF4
23556
    number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
23557
    number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
23558
    number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
23559
    number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
23560
    number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
23561
    number_integer  | 0..23                                      | Integer                            | 0x00..0x17
23562
    number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
23563
    number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
23564
    number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
23565
    number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
23566
    number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
23567
    number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
23568
    number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
23569
    number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
23570
    number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
23571
    number_float    | *any value representable by a float*       | Single-Precision Float             | 0xFA
23572
    number_float    | *any value NOT representable by a float*   | Double-Precision Float             | 0xFB
23573
    string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
23574
    string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
23575
    string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
23576
    string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
23577
    string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
23578
    array           | *size*: 0..23                              | array                              | 0x80..0x97
23579
    array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
23580
    array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
23581
    array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
23582
    array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
23583
    object          | *size*: 0..23                              | map                                | 0xA0..0xB7
23584
    object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
23585
    object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
23586
    object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
23587
    object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
23588
    binary          | *size*: 0..23                              | byte string                        | 0x40..0x57
23589
    binary          | *size*: 23..255                            | byte string (1 byte follow)        | 0x58
23590
    binary          | *size*: 256..65535                         | byte string (2 bytes follow)       | 0x59
23591
    binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)       | 0x5A
23592
    binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)       | 0x5B
23593
23594
    @note The mapping is **complete** in the sense that any JSON value type
23595
          can be converted to a CBOR value.
23596
23597
    @note If NaN or Infinity are stored inside a JSON number, they are
23598
          serialized properly. This behavior differs from the @ref dump()
23599
          function which serializes NaN or Infinity to `null`.
23600
23601
    @note The following CBOR types are not used in the conversion:
23602
          - UTF-8 strings terminated by "break" (0x7F)
23603
          - arrays terminated by "break" (0x9F)
23604
          - maps terminated by "break" (0xBF)
23605
          - byte strings terminated by "break" (0x5F)
23606
          - date/time (0xC0..0xC1)
23607
          - bignum (0xC2..0xC3)
23608
          - decimal fraction (0xC4)
23609
          - bigfloat (0xC5)
23610
          - expected conversions (0xD5..0xD7)
23611
          - simple values (0xE0..0xF3, 0xF8)
23612
          - undefined (0xF7)
23613
          - half-precision floats (0xF9)
23614
          - break (0xFF)
23615
23616
    @param[in] j  JSON value to serialize
23617
    @return CBOR serialization as byte vector
23618
23619
    @complexity Linear in the size of the JSON value @a j.
23620
23621
    @liveexample{The example shows the serialization of a JSON value to a byte
23622
    vector in CBOR format.,to_cbor}
23623
23624
    @sa http://cbor.io
23625
    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
23626
        analogous deserialization
23627
    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23628
    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23629
             related UBJSON format
23630
23631
    @since version 2.0.9; compact representation of floating-point numbers
23632
           since version 3.8.0
23633
    */
23634
    static std::vector<uint8_t> to_cbor(const basic_json& j)
23635
    {
23636
        std::vector<uint8_t> result;
23637
        to_cbor(j, result);
23638
        return result;
23639
    }
23640
23641
    static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
23642
    {
23643
        binary_writer<uint8_t>(o).write_cbor(j);
23644
    }
23645
23646
    static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23647
    {
23648
        binary_writer<char>(o).write_cbor(j);
23649
    }
23650
23651
    /*!
23652
    @brief create a MessagePack serialization of a given JSON value
23653
23654
    Serializes a given JSON value @a j to a byte vector using the MessagePack
23655
    serialization format. MessagePack is a binary serialization format which
23656
    aims to be more compact than JSON itself, yet more efficient to parse.
23657
23658
    The library uses the following mapping from JSON values types to
23659
    MessagePack types according to the MessagePack specification:
23660
23661
    JSON value type | value/range                       | MessagePack type | first byte
23662
    --------------- | --------------------------------- | ---------------- | ----------
23663
    null            | `null`                            | nil              | 0xC0
23664
    boolean         | `true`                            | true             | 0xC3
23665
    boolean         | `false`                           | false            | 0xC2
23666
    number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
23667
    number_integer  | -2147483648..-32769               | int32            | 0xD2
23668
    number_integer  | -32768..-129                      | int16            | 0xD1
23669
    number_integer  | -128..-33                         | int8             | 0xD0
23670
    number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
23671
    number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
23672
    number_integer  | 128..255                          | uint 8           | 0xCC
23673
    number_integer  | 256..65535                        | uint 16          | 0xCD
23674
    number_integer  | 65536..4294967295                 | uint 32          | 0xCE
23675
    number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
23676
    number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
23677
    number_unsigned | 128..255                          | uint 8           | 0xCC
23678
    number_unsigned | 256..65535                        | uint 16          | 0xCD
23679
    number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
23680
    number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
23681
    number_float    | *any value representable by a float*     | float 32 | 0xCA
23682
    number_float    | *any value NOT representable by a float* | float 64 | 0xCB
23683
    string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
23684
    string          | *length*: 32..255                 | str 8            | 0xD9
23685
    string          | *length*: 256..65535              | str 16           | 0xDA
23686
    string          | *length*: 65536..4294967295       | str 32           | 0xDB
23687
    array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
23688
    array           | *size*: 16..65535                 | array 16         | 0xDC
23689
    array           | *size*: 65536..4294967295         | array 32         | 0xDD
23690
    object          | *size*: 0..15                     | fix map          | 0x80..0x8F
23691
    object          | *size*: 16..65535                 | map 16           | 0xDE
23692
    object          | *size*: 65536..4294967295         | map 32           | 0xDF
23693
    binary          | *size*: 0..255                    | bin 8            | 0xC4
23694
    binary          | *size*: 256..65535                | bin 16           | 0xC5
23695
    binary          | *size*: 65536..4294967295         | bin 32           | 0xC6
23696
23697
    @note The mapping is **complete** in the sense that any JSON value type
23698
          can be converted to a MessagePack value.
23699
23700
    @note The following values can **not** be converted to a MessagePack value:
23701
          - strings with more than 4294967295 bytes
23702
          - byte strings with more than 4294967295 bytes
23703
          - arrays with more than 4294967295 elements
23704
          - objects with more than 4294967295 elements
23705
23706
    @note Any MessagePack output created @ref to_msgpack can be successfully
23707
          parsed by @ref from_msgpack.
23708
23709
    @note If NaN or Infinity are stored inside a JSON number, they are
23710
          serialized properly. This behavior differs from the @ref dump()
23711
          function which serializes NaN or Infinity to `null`.
23712
23713
    @param[in] j  JSON value to serialize
23714
    @return MessagePack serialization as byte vector
23715
23716
    @complexity Linear in the size of the JSON value @a j.
23717
23718
    @liveexample{The example shows the serialization of a JSON value to a byte
23719
    vector in MessagePack format.,to_msgpack}
23720
23721
    @sa http://msgpack.org
23722
    @sa @ref from_msgpack for the analogous deserialization
23723
    @sa @ref to_cbor(const basic_json& for the related CBOR format
23724
    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23725
             related UBJSON format
23726
23727
    @since version 2.0.9
23728
    */
23729
    static std::vector<uint8_t> to_msgpack(const basic_json& j)
23730
    {
23731
        std::vector<uint8_t> result;
23732
        to_msgpack(j, result);
23733
        return result;
23734
    }
23735
23736
    static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
23737
    {
23738
        binary_writer<uint8_t>(o).write_msgpack(j);
23739
    }
23740
23741
    static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23742
    {
23743
        binary_writer<char>(o).write_msgpack(j);
23744
    }
23745
23746
    /*!
23747
    @brief create a UBJSON serialization of a given JSON value
23748
23749
    Serializes a given JSON value @a j to a byte vector using the UBJSON
23750
    (Universal Binary JSON) serialization format. UBJSON aims to be more compact
23751
    than JSON itself, yet more efficient to parse.
23752
23753
    The library uses the following mapping from JSON values types to
23754
    UBJSON types according to the UBJSON specification:
23755
23756
    JSON value type | value/range                       | UBJSON type | marker
23757
    --------------- | --------------------------------- | ----------- | ------
23758
    null            | `null`                            | null        | `Z`
23759
    boolean         | `true`                            | true        | `T`
23760
    boolean         | `false`                           | false       | `F`
23761
    number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
23762
    number_integer  | -2147483648..-32769               | int32       | `l`
23763
    number_integer  | -32768..-129                      | int16       | `I`
23764
    number_integer  | -128..127                         | int8        | `i`
23765
    number_integer  | 128..255                          | uint8       | `U`
23766
    number_integer  | 256..32767                        | int16       | `I`
23767
    number_integer  | 32768..2147483647                 | int32       | `l`
23768
    number_integer  | 2147483648..9223372036854775807   | int64       | `L`
23769
    number_unsigned | 0..127                            | int8        | `i`
23770
    number_unsigned | 128..255                          | uint8       | `U`
23771
    number_unsigned | 256..32767                        | int16       | `I`
23772
    number_unsigned | 32768..2147483647                 | int32       | `l`
23773
    number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
23774
    number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`
23775
    number_float    | *any value*                       | float64     | `D`
23776
    string          | *with shortest length indicator*  | string      | `S`
23777
    array           | *see notes on optimized format*   | array       | `[`
23778
    object          | *see notes on optimized format*   | map         | `{`
23779
23780
    @note The mapping is **complete** in the sense that any JSON value type
23781
          can be converted to a UBJSON value.
23782
23783
    @note The following values can **not** be converted to a UBJSON value:
23784
          - strings with more than 9223372036854775807 bytes (theoretical)
23785
23786
    @note The following markers are not used in the conversion:
23787
          - `Z`: no-op values are not created.
23788
          - `C`: single-byte strings are serialized with `S` markers.
23789
23790
    @note Any UBJSON output created @ref to_ubjson can be successfully parsed
23791
          by @ref from_ubjson.
23792
23793
    @note If NaN or Infinity are stored inside a JSON number, they are
23794
          serialized properly. This behavior differs from the @ref dump()
23795
          function which serializes NaN or Infinity to `null`.
23796
23797
    @note The optimized formats for containers are supported: Parameter
23798
          @a use_size adds size information to the beginning of a container and
23799
          removes the closing marker. Parameter @a use_type further checks
23800
          whether all elements of a container have the same type and adds the
23801
          type marker to the beginning of the container. The @a use_type
23802
          parameter must only be used together with @a use_size = true. Note
23803
          that @a use_size = true alone may result in larger representations -
23804
          the benefit of this parameter is that the receiving side is
23805
          immediately informed on the number of elements of the container.
23806
23807
    @note If the JSON data contains the binary type, the value stored is a list
23808
          of integers, as suggested by the UBJSON documentation.  In particular,
23809
          this means that serialization and the deserialization of a JSON
23810
          containing binary values into UBJSON and back will result in a
23811
          different JSON object.
23812
23813
    @param[in] j  JSON value to serialize
23814
    @param[in] use_size  whether to add size annotations to container types
23815
    @param[in] use_type  whether to add type annotations to container types
23816
                         (must be combined with @a use_size = true)
23817
    @return UBJSON serialization as byte vector
23818
23819
    @complexity Linear in the size of the JSON value @a j.
23820
23821
    @liveexample{The example shows the serialization of a JSON value to a byte
23822
    vector in UBJSON format.,to_ubjson}
23823
23824
    @sa http://ubjson.org
23825
    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
23826
        analogous deserialization
23827
    @sa @ref to_cbor(const basic_json& for the related CBOR format
23828
    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23829
23830
    @since version 3.1.0
23831
    */
23832
    static std::vector<uint8_t> to_ubjson(const basic_json& j,
23833
                                          const bool use_size = false,
23834
                                          const bool use_type = false)
23835
    {
23836
        std::vector<uint8_t> result;
23837
        to_ubjson(j, result, use_size, use_type);
23838
        return result;
23839
    }
23840
23841
    static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23842
                          const bool use_size = false, const bool use_type = false)
23843
    {
23844
        binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23845
    }
23846
23847
    static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23848
                          const bool use_size = false, const bool use_type = false)
23849
    {
23850
        binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23851
    }
23852
23853
23854
    /*!
23855
    @brief Serializes the given JSON object `j` to BSON and returns a vector
23856
           containing the corresponding BSON-representation.
23857
23858
    BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
23859
    stored as a single entity (a so-called document).
23860
23861
    The library uses the following mapping from JSON values types to BSON types:
23862
23863
    JSON value type | value/range                       | BSON type   | marker
23864
    --------------- | --------------------------------- | ----------- | ------
23865
    null            | `null`                            | null        | 0x0A
23866
    boolean         | `true`, `false`                   | boolean     | 0x08
23867
    number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
23868
    number_integer  | -2147483648..2147483647           | int32       | 0x10
23869
    number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
23870
    number_unsigned | 0..2147483647                     | int32       | 0x10
23871
    number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
23872
    number_unsigned | 9223372036854775808..18446744073709551615| --   | --
23873
    number_float    | *any value*                       | double      | 0x01
23874
    string          | *any value*                       | string      | 0x02
23875
    array           | *any value*                       | document    | 0x04
23876
    object          | *any value*                       | document    | 0x03
23877
    binary          | *any value*                       | binary      | 0x05
23878
23879
    @warning The mapping is **incomplete**, since only JSON-objects (and things
23880
    contained therein) can be serialized to BSON.
23881
    Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
23882
    and the keys may not contain U+0000, since they are serialized a
23883
    zero-terminated c-strings.
23884
23885
    @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
23886
    @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
23887
    @throw type_error.317    if `!j.is_object()`
23888
23889
    @pre The input `j` is required to be an object: `j.is_object() == true`.
23890
23891
    @note Any BSON output created via @ref to_bson can be successfully parsed
23892
          by @ref from_bson.
23893
23894
    @param[in] j  JSON value to serialize
23895
    @return BSON serialization as byte vector
23896
23897
    @complexity Linear in the size of the JSON value @a j.
23898
23899
    @liveexample{The example shows the serialization of a JSON value to a byte
23900
    vector in BSON format.,to_bson}
23901
23902
    @sa http://bsonspec.org/spec.html
23903
    @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
23904
        analogous deserialization
23905
    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23906
             related UBJSON format
23907
    @sa @ref to_cbor(const basic_json&) for the related CBOR format
23908
    @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23909
    */
23910
    static std::vector<uint8_t> to_bson(const basic_json& j)
23911
    {
23912
        std::vector<uint8_t> result;
23913
        to_bson(j, result);
23914
        return result;
23915
    }
23916
23917
    /*!
23918
    @brief Serializes the given JSON object `j` to BSON and forwards the
23919
           corresponding BSON-representation to the given output_adapter `o`.
23920
    @param j The JSON object to convert to BSON.
23921
    @param o The output adapter that receives the binary BSON representation.
23922
    @pre The input `j` shall be an object: `j.is_object() == true`
23923
    @sa @ref to_bson(const basic_json&)
23924
    */
23925
    static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23926
    {
23927
        binary_writer<uint8_t>(o).write_bson(j);
23928
    }
23929
23930
    /*!
23931
    @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
23932
    */
23933
    static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23934
    {
23935
        binary_writer<char>(o).write_bson(j);
23936
    }
23937
23938
23939
    /*!
23940
    @brief create a JSON value from an input in CBOR format
23941
23942
    Deserializes a given input @a i to a JSON value using the CBOR (Concise
23943
    Binary Object Representation) serialization format.
23944
23945
    The library maps CBOR types to JSON value types as follows:
23946
23947
    CBOR type              | JSON value type | first byte
23948
    ---------------------- | --------------- | ----------
23949
    Integer                | number_unsigned | 0x00..0x17
23950
    Unsigned integer       | number_unsigned | 0x18
23951
    Unsigned integer       | number_unsigned | 0x19
23952
    Unsigned integer       | number_unsigned | 0x1A
23953
    Unsigned integer       | number_unsigned | 0x1B
23954
    Negative integer       | number_integer  | 0x20..0x37
23955
    Negative integer       | number_integer  | 0x38
23956
    Negative integer       | number_integer  | 0x39
23957
    Negative integer       | number_integer  | 0x3A
23958
    Negative integer       | number_integer  | 0x3B
23959
    Byte string            | binary          | 0x40..0x57
23960
    Byte string            | binary          | 0x58
23961
    Byte string            | binary          | 0x59
23962
    Byte string            | binary          | 0x5A
23963
    Byte string            | binary          | 0x5B
23964
    UTF-8 string           | string          | 0x60..0x77
23965
    UTF-8 string           | string          | 0x78
23966
    UTF-8 string           | string          | 0x79
23967
    UTF-8 string           | string          | 0x7A
23968
    UTF-8 string           | string          | 0x7B
23969
    UTF-8 string           | string          | 0x7F
23970
    array                  | array           | 0x80..0x97
23971
    array                  | array           | 0x98
23972
    array                  | array           | 0x99
23973
    array                  | array           | 0x9A
23974
    array                  | array           | 0x9B
23975
    array                  | array           | 0x9F
23976
    map                    | object          | 0xA0..0xB7
23977
    map                    | object          | 0xB8
23978
    map                    | object          | 0xB9
23979
    map                    | object          | 0xBA
23980
    map                    | object          | 0xBB
23981
    map                    | object          | 0xBF
23982
    False                  | `false`         | 0xF4
23983
    True                   | `true`          | 0xF5
23984
    Null                   | `null`          | 0xF6
23985
    Half-Precision Float   | number_float    | 0xF9
23986
    Single-Precision Float | number_float    | 0xFA
23987
    Double-Precision Float | number_float    | 0xFB
23988
23989
    @warning The mapping is **incomplete** in the sense that not all CBOR
23990
             types can be converted to a JSON value. The following CBOR types
23991
             are not supported and will yield parse errors (parse_error.112):
23992
             - date/time (0xC0..0xC1)
23993
             - bignum (0xC2..0xC3)
23994
             - decimal fraction (0xC4)
23995
             - bigfloat (0xC5)
23996
             - expected conversions (0xD5..0xD7)
23997
             - simple values (0xE0..0xF3, 0xF8)
23998
             - undefined (0xF7)
23999
24000
    @warning CBOR allows map keys of any type, whereas JSON only allows
24001
             strings as keys in object values. Therefore, CBOR maps with keys
24002
             other than UTF-8 strings are rejected (parse_error.113).
24003
24004
    @note Any CBOR output created @ref to_cbor can be successfully parsed by
24005
          @ref from_cbor.
24006
24007
    @param[in] i  an input in CBOR format convertible to an input adapter
24008
    @param[in] strict  whether to expect the input to be consumed until EOF
24009
                       (true by default)
24010
    @param[in] allow_exceptions  whether to throw exceptions in case of a
24011
    parse error (optional, true by default)
24012
    @param[in] tag_handler how to treat CBOR tags (optional, error by default)
24013
24014
    @return deserialized JSON value; in case of a parse error and
24015
            @a allow_exceptions set to `false`, the return value will be
24016
            value_t::discarded.
24017
24018
    @throw parse_error.110 if the given input ends prematurely or the end of
24019
    file was not reached when @a strict was set to true
24020
    @throw parse_error.112 if unsupported features from CBOR were
24021
    used in the given input @a v or if the input is not valid CBOR
24022
    @throw parse_error.113 if a string was expected as map key, but not found
24023
24024
    @complexity Linear in the size of the input @a i.
24025
24026
    @liveexample{The example shows the deserialization of a byte vector in CBOR
24027
    format to a JSON value.,from_cbor}
24028
24029
    @sa http://cbor.io
24030
    @sa @ref to_cbor(const basic_json&) for the analogous serialization
24031
    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
24032
        related MessagePack format
24033
    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
24034
        related UBJSON format
24035
24036
    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
24037
           consume input adapters, removed start_index parameter, and added
24038
           @a strict parameter since 3.0.0; added @a allow_exceptions parameter
24039
           since 3.2.0; added @a tag_handler parameter since 3.9.0.
24040
    */
24041
    template<typename InputType>
24042
    JSON_HEDLEY_WARN_UNUSED_RESULT
24043
    static basic_json from_cbor(InputType&& i,
24044
                                const bool strict = true,
24045
                                const bool allow_exceptions = true,
24046
                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24047
    {
24048
        basic_json result;
24049
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24050
        auto ia = detail::input_adapter(std::forward<InputType>(i));
24051
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24052
        return res ? result : basic_json(value_t::discarded);
24053
    }
24054
24055
    /*!
24056
    @copydoc from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t)
24057
    */
24058
    template<typename IteratorType>
24059
    JSON_HEDLEY_WARN_UNUSED_RESULT
24060
    static basic_json from_cbor(IteratorType first, IteratorType last,
24061
                                const bool strict = true,
24062
                                const bool allow_exceptions = true,
24063
                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24064
    {
24065
        basic_json result;
24066
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24067
        auto ia = detail::input_adapter(std::move(first), std::move(last));
24068
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24069
        return res ? result : basic_json(value_t::discarded);
24070
    }
24071
24072
    template<typename T>
24073
    JSON_HEDLEY_WARN_UNUSED_RESULT
24074
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24075
    static basic_json from_cbor(const T* ptr, std::size_t len,
24076
                                const bool strict = true,
24077
                                const bool allow_exceptions = true,
24078
                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24079
    {
24080
        return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24081
    }
24082
24083
24084
    JSON_HEDLEY_WARN_UNUSED_RESULT
24085
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24086
    static basic_json from_cbor(detail::span_input_adapter&& i,
24087
                                const bool strict = true,
24088
                                const bool allow_exceptions = true,
24089
                                const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24090
    {
24091
        basic_json result;
24092
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24093
        auto ia = i.get();
24094
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24095
        return res ? result : basic_json(value_t::discarded);
24096
    }
24097
24098
    /*!
24099
    @brief create a JSON value from an input in MessagePack format
24100
24101
    Deserializes a given input @a i to a JSON value using the MessagePack
24102
    serialization format.
24103
24104
    The library maps MessagePack types to JSON value types as follows:
24105
24106
    MessagePack type | JSON value type | first byte
24107
    ---------------- | --------------- | ----------
24108
    positive fixint  | number_unsigned | 0x00..0x7F
24109
    fixmap           | object          | 0x80..0x8F
24110
    fixarray         | array           | 0x90..0x9F
24111
    fixstr           | string          | 0xA0..0xBF
24112
    nil              | `null`          | 0xC0
24113
    false            | `false`         | 0xC2
24114
    true             | `true`          | 0xC3
24115
    float 32         | number_float    | 0xCA
24116
    float 64         | number_float    | 0xCB
24117
    uint 8           | number_unsigned | 0xCC
24118
    uint 16          | number_unsigned | 0xCD
24119
    uint 32          | number_unsigned | 0xCE
24120
    uint 64          | number_unsigned | 0xCF
24121
    int 8            | number_integer  | 0xD0
24122
    int 16           | number_integer  | 0xD1
24123
    int 32           | number_integer  | 0xD2
24124
    int 64           | number_integer  | 0xD3
24125
    str 8            | string          | 0xD9
24126
    str 16           | string          | 0xDA
24127
    str 32           | string          | 0xDB
24128
    array 16         | array           | 0xDC
24129
    array 32         | array           | 0xDD
24130
    map 16           | object          | 0xDE
24131
    map 32           | object          | 0xDF
24132
    bin 8            | binary          | 0xC4
24133
    bin 16           | binary          | 0xC5
24134
    bin 32           | binary          | 0xC6
24135
    ext 8            | binary          | 0xC7
24136
    ext 16           | binary          | 0xC8
24137
    ext 32           | binary          | 0xC9
24138
    fixext 1         | binary          | 0xD4
24139
    fixext 2         | binary          | 0xD5
24140
    fixext 4         | binary          | 0xD6
24141
    fixext 8         | binary          | 0xD7
24142
    fixext 16        | binary          | 0xD8
24143
    negative fixint  | number_integer  | 0xE0-0xFF
24144
24145
    @note Any MessagePack output created @ref to_msgpack can be successfully
24146
          parsed by @ref from_msgpack.
24147
24148
    @param[in] i  an input in MessagePack format convertible to an input
24149
                  adapter
24150
    @param[in] strict  whether to expect the input to be consumed until EOF
24151
                       (true by default)
24152
    @param[in] allow_exceptions  whether to throw exceptions in case of a
24153
    parse error (optional, true by default)
24154
24155
    @return deserialized JSON value; in case of a parse error and
24156
            @a allow_exceptions set to `false`, the return value will be
24157
            value_t::discarded.
24158
24159
    @throw parse_error.110 if the given input ends prematurely or the end of
24160
    file was not reached when @a strict was set to true
24161
    @throw parse_error.112 if unsupported features from MessagePack were
24162
    used in the given input @a i or if the input is not valid MessagePack
24163
    @throw parse_error.113 if a string was expected as map key, but not found
24164
24165
    @complexity Linear in the size of the input @a i.
24166
24167
    @liveexample{The example shows the deserialization of a byte vector in
24168
    MessagePack format to a JSON value.,from_msgpack}
24169
24170
    @sa http://msgpack.org
24171
    @sa @ref to_msgpack(const basic_json&) for the analogous serialization
24172
    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24173
        related CBOR format
24174
    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
24175
        the related UBJSON format
24176
    @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
24177
        the related BSON format
24178
24179
    @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
24180
           consume input adapters, removed start_index parameter, and added
24181
           @a strict parameter since 3.0.0; added @a allow_exceptions parameter
24182
           since 3.2.0
24183
    */
24184
    template<typename InputType>
24185
    JSON_HEDLEY_WARN_UNUSED_RESULT
24186
    static basic_json from_msgpack(InputType&& i,
24187
                                   const bool strict = true,
24188
                                   const bool allow_exceptions = true)
24189
    {
24190
        basic_json result;
24191
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24192
        auto ia = detail::input_adapter(std::forward<InputType>(i));
24193
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24194
        return res ? result : basic_json(value_t::discarded);
24195
    }
24196
24197
    /*!
24198
    @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
24199
    */
24200
    template<typename IteratorType>
24201
    JSON_HEDLEY_WARN_UNUSED_RESULT
24202
    static basic_json from_msgpack(IteratorType first, IteratorType last,
24203
                                   const bool strict = true,
24204
                                   const bool allow_exceptions = true)
24205
    {
24206
        basic_json result;
24207
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24208
        auto ia = detail::input_adapter(std::move(first), std::move(last));
24209
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24210
        return res ? result : basic_json(value_t::discarded);
24211
    }
24212
24213
24214
    template<typename T>
24215
    JSON_HEDLEY_WARN_UNUSED_RESULT
24216
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24217
    static basic_json from_msgpack(const T* ptr, std::size_t len,
24218
                                   const bool strict = true,
24219
                                   const bool allow_exceptions = true)
24220
    {
24221
        return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24222
    }
24223
24224
    JSON_HEDLEY_WARN_UNUSED_RESULT
24225
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24226
    static basic_json from_msgpack(detail::span_input_adapter&& i,
24227
                                   const bool strict = true,
24228
                                   const bool allow_exceptions = true)
24229
    {
24230
        basic_json result;
24231
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24232
        auto ia = i.get();
24233
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24234
        return res ? result : basic_json(value_t::discarded);
24235
    }
24236
24237
24238
    /*!
24239
    @brief create a JSON value from an input in UBJSON format
24240
24241
    Deserializes a given input @a i to a JSON value using the UBJSON (Universal
24242
    Binary JSON) serialization format.
24243
24244
    The library maps UBJSON types to JSON value types as follows:
24245
24246
    UBJSON type | JSON value type                         | marker
24247
    ----------- | --------------------------------------- | ------
24248
    no-op       | *no value, next value is read*          | `N`
24249
    null        | `null`                                  | `Z`
24250
    false       | `false`                                 | `F`
24251
    true        | `true`                                  | `T`
24252
    float32     | number_float                            | `d`
24253
    float64     | number_float                            | `D`
24254
    uint8       | number_unsigned                         | `U`
24255
    int8        | number_integer                          | `i`
24256
    int16       | number_integer                          | `I`
24257
    int32       | number_integer                          | `l`
24258
    int64       | number_integer                          | `L`
24259
    high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
24260
    string      | string                                  | `S`
24261
    char        | string                                  | `C`
24262
    array       | array (optimized values are supported)  | `[`
24263
    object      | object (optimized values are supported) | `{`
24264
24265
    @note The mapping is **complete** in the sense that any UBJSON value can
24266
          be converted to a JSON value.
24267
24268
    @param[in] i  an input in UBJSON format convertible to an input adapter
24269
    @param[in] strict  whether to expect the input to be consumed until EOF
24270
                       (true by default)
24271
    @param[in] allow_exceptions  whether to throw exceptions in case of a
24272
    parse error (optional, true by default)
24273
24274
    @return deserialized JSON value; in case of a parse error and
24275
            @a allow_exceptions set to `false`, the return value will be
24276
            value_t::discarded.
24277
24278
    @throw parse_error.110 if the given input ends prematurely or the end of
24279
    file was not reached when @a strict was set to true
24280
    @throw parse_error.112 if a parse error occurs
24281
    @throw parse_error.113 if a string could not be parsed successfully
24282
24283
    @complexity Linear in the size of the input @a i.
24284
24285
    @liveexample{The example shows the deserialization of a byte vector in
24286
    UBJSON format to a JSON value.,from_ubjson}
24287
24288
    @sa http://ubjson.org
24289
    @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
24290
             analogous serialization
24291
    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24292
        related CBOR format
24293
    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
24294
        the related MessagePack format
24295
    @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
24296
        the related BSON format
24297
24298
    @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
24299
    */
24300
    template<typename InputType>
24301
    JSON_HEDLEY_WARN_UNUSED_RESULT
24302
    static basic_json from_ubjson(InputType&& i,
24303
                                  const bool strict = true,
24304
                                  const bool allow_exceptions = true)
24305
    {
24306
        basic_json result;
24307
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24308
        auto ia = detail::input_adapter(std::forward<InputType>(i));
24309
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24310
        return res ? result : basic_json(value_t::discarded);
24311
    }
24312
24313
    /*!
24314
    @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
24315
    */
24316
    template<typename IteratorType>
24317
    JSON_HEDLEY_WARN_UNUSED_RESULT
24318
    static basic_json from_ubjson(IteratorType first, IteratorType last,
24319
                                  const bool strict = true,
24320
                                  const bool allow_exceptions = true)
24321
    {
24322
        basic_json result;
24323
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24324
        auto ia = detail::input_adapter(std::move(first), std::move(last));
24325
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24326
        return res ? result : basic_json(value_t::discarded);
24327
    }
24328
24329
    template<typename T>
24330
    JSON_HEDLEY_WARN_UNUSED_RESULT
24331
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24332
    static basic_json from_ubjson(const T* ptr, std::size_t len,
24333
                                  const bool strict = true,
24334
                                  const bool allow_exceptions = true)
24335
    {
24336
        return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24337
    }
24338
24339
    JSON_HEDLEY_WARN_UNUSED_RESULT
24340
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24341
    static basic_json from_ubjson(detail::span_input_adapter&& i,
24342
                                  const bool strict = true,
24343
                                  const bool allow_exceptions = true)
24344
    {
24345
        basic_json result;
24346
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24347
        auto ia = i.get();
24348
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24349
        return res ? result : basic_json(value_t::discarded);
24350
    }
24351
24352
24353
    /*!
24354
    @brief Create a JSON value from an input in BSON format
24355
24356
    Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
24357
    serialization format.
24358
24359
    The library maps BSON record types to JSON value types as follows:
24360
24361
    BSON type       | BSON marker byte | JSON value type
24362
    --------------- | ---------------- | ---------------------------
24363
    double          | 0x01             | number_float
24364
    string          | 0x02             | string
24365
    document        | 0x03             | object
24366
    array           | 0x04             | array
24367
    binary          | 0x05             | binary
24368
    undefined       | 0x06             | still unsupported
24369
    ObjectId        | 0x07             | still unsupported
24370
    boolean         | 0x08             | boolean
24371
    UTC Date-Time   | 0x09             | still unsupported
24372
    null            | 0x0A             | null
24373
    Regular Expr.   | 0x0B             | still unsupported
24374
    DB Pointer      | 0x0C             | still unsupported
24375
    JavaScript Code | 0x0D             | still unsupported
24376
    Symbol          | 0x0E             | still unsupported
24377
    JavaScript Code | 0x0F             | still unsupported
24378
    int32           | 0x10             | number_integer
24379
    Timestamp       | 0x11             | still unsupported
24380
    128-bit decimal float | 0x13       | still unsupported
24381
    Max Key         | 0x7F             | still unsupported
24382
    Min Key         | 0xFF             | still unsupported
24383
24384
    @warning The mapping is **incomplete**. The unsupported mappings
24385
             are indicated in the table above.
24386
24387
    @param[in] i  an input in BSON format convertible to an input adapter
24388
    @param[in] strict  whether to expect the input to be consumed until EOF
24389
                       (true by default)
24390
    @param[in] allow_exceptions  whether to throw exceptions in case of a
24391
    parse error (optional, true by default)
24392
24393
    @return deserialized JSON value; in case of a parse error and
24394
            @a allow_exceptions set to `false`, the return value will be
24395
            value_t::discarded.
24396
24397
    @throw parse_error.114 if an unsupported BSON record type is encountered
24398
24399
    @complexity Linear in the size of the input @a i.
24400
24401
    @liveexample{The example shows the deserialization of a byte vector in
24402
    BSON format to a JSON value.,from_bson}
24403
24404
    @sa http://bsonspec.org/spec.html
24405
    @sa @ref to_bson(const basic_json&) for the analogous serialization
24406
    @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24407
        related CBOR format
24408
    @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
24409
        the related MessagePack format
24410
    @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
24411
        related UBJSON format
24412
    */
24413
    template<typename InputType>
24414
    JSON_HEDLEY_WARN_UNUSED_RESULT
24415
    static basic_json from_bson(InputType&& i,
24416
                                const bool strict = true,
24417
                                const bool allow_exceptions = true)
24418
    {
24419
        basic_json result;
24420
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24421
        auto ia = detail::input_adapter(std::forward<InputType>(i));
24422
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24423
        return res ? result : basic_json(value_t::discarded);
24424
    }
24425
24426
    /*!
24427
    @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
24428
    */
24429
    template<typename IteratorType>
24430
    JSON_HEDLEY_WARN_UNUSED_RESULT
24431
    static basic_json from_bson(IteratorType first, IteratorType last,
24432
                                const bool strict = true,
24433
                                const bool allow_exceptions = true)
24434
    {
24435
        basic_json result;
24436
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24437
        auto ia = detail::input_adapter(std::move(first), std::move(last));
24438
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24439
        return res ? result : basic_json(value_t::discarded);
24440
    }
24441
24442
    template<typename T>
24443
    JSON_HEDLEY_WARN_UNUSED_RESULT
24444
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24445
    static basic_json from_bson(const T* ptr, std::size_t len,
24446
                                const bool strict = true,
24447
                                const bool allow_exceptions = true)
24448
    {
24449
        return from_bson(ptr, ptr + len, strict, allow_exceptions);
24450
    }
24451
24452
    JSON_HEDLEY_WARN_UNUSED_RESULT
24453
    JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24454
    static basic_json from_bson(detail::span_input_adapter&& i,
24455
                                const bool strict = true,
24456
                                const bool allow_exceptions = true)
24457
    {
24458
        basic_json result;
24459
        detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24460
        auto ia = i.get();
24461
        const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24462
        return res ? result : basic_json(value_t::discarded);
24463
    }
24464
    /// @}
24465
24466
    //////////////////////////
24467
    // JSON Pointer support //
24468
    //////////////////////////
24469
24470
    /// @name JSON Pointer functions
24471
    /// @{
24472
24473
    /*!
24474
    @brief access specified element via JSON Pointer
24475
24476
    Uses a JSON pointer to retrieve a reference to the respective JSON value.
24477
    No bound checking is performed. Similar to @ref operator[](const typename
24478
    object_t::key_type&), `null` values are created in arrays and objects if
24479
    necessary.
24480
24481
    In particular:
24482
    - If the JSON pointer points to an object key that does not exist, it
24483
      is created an filled with a `null` value before a reference to it
24484
      is returned.
24485
    - If the JSON pointer points to an array index that does not exist, it
24486
      is created an filled with a `null` value before a reference to it
24487
      is returned. All indices between the current maximum and the given
24488
      index are also filled with `null`.
24489
    - The special value `-` is treated as a synonym for the index past the
24490
      end.
24491
24492
    @param[in] ptr  a JSON pointer
24493
24494
    @return reference to the element pointed to by @a ptr
24495
24496
    @complexity Constant.
24497
24498
    @throw parse_error.106   if an array index begins with '0'
24499
    @throw parse_error.109   if an array index was not a number
24500
    @throw out_of_range.404  if the JSON pointer can not be resolved
24501
24502
    @liveexample{The behavior is shown in the example.,operatorjson_pointer}
24503
24504
    @since version 2.0.0
24505
    */
24506
    reference operator[](const json_pointer& ptr)
24507
    {
24508
        return ptr.get_unchecked(this);
24509
    }
24510
24511
    /*!
24512
    @brief access specified element via JSON Pointer
24513
24514
    Uses a JSON pointer to retrieve a reference to the respective JSON value.
24515
    No bound checking is performed. The function does not change the JSON
24516
    value; no `null` values are created. In particular, the special value
24517
    `-` yields an exception.
24518
24519
    @param[in] ptr  JSON pointer to the desired element
24520
24521
    @return const reference to the element pointed to by @a ptr
24522
24523
    @complexity Constant.
24524
24525
    @throw parse_error.106   if an array index begins with '0'
24526
    @throw parse_error.109   if an array index was not a number
24527
    @throw out_of_range.402  if the array index '-' is used
24528
    @throw out_of_range.404  if the JSON pointer can not be resolved
24529
24530
    @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
24531
24532
    @since version 2.0.0
24533
    */
24534
    const_reference operator[](const json_pointer& ptr) const
24535
    {
24536
        return ptr.get_unchecked(this);
24537
    }
24538
24539
    /*!
24540
    @brief access specified element via JSON Pointer
24541
24542
    Returns a reference to the element at with specified JSON pointer @a ptr,
24543
    with bounds checking.
24544
24545
    @param[in] ptr  JSON pointer to the desired element
24546
24547
    @return reference to the element pointed to by @a ptr
24548
24549
    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
24550
    begins with '0'. See example below.
24551
24552
    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
24553
    is not a number. See example below.
24554
24555
    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
24556
    is out of range. See example below.
24557
24558
    @throw out_of_range.402 if the array index '-' is used in the passed JSON
24559
    pointer @a ptr. As `at` provides checked access (and no elements are
24560
    implicitly inserted), the index '-' is always invalid. See example below.
24561
24562
    @throw out_of_range.403 if the JSON pointer describes a key of an object
24563
    which cannot be found. See example below.
24564
24565
    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
24566
    See example below.
24567
24568
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
24569
    changes in the JSON value.
24570
24571
    @complexity Constant.
24572
24573
    @since version 2.0.0
24574
24575
    @liveexample{The behavior is shown in the example.,at_json_pointer}
24576
    */
24577
    reference at(const json_pointer& ptr)
24578
    {
24579
        return ptr.get_checked(this);
24580
    }
24581
24582
    /*!
24583
    @brief access specified element via JSON Pointer
24584
24585
    Returns a const reference to the element at with specified JSON pointer @a
24586
    ptr, with bounds checking.
24587
24588
    @param[in] ptr  JSON pointer to the desired element
24589
24590
    @return reference to the element pointed to by @a ptr
24591
24592
    @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
24593
    begins with '0'. See example below.
24594
24595
    @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
24596
    is not a number. See example below.
24597
24598
    @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
24599
    is out of range. See example below.
24600
24601
    @throw out_of_range.402 if the array index '-' is used in the passed JSON
24602
    pointer @a ptr. As `at` provides checked access (and no elements are
24603
    implicitly inserted), the index '-' is always invalid. See example below.
24604
24605
    @throw out_of_range.403 if the JSON pointer describes a key of an object
24606
    which cannot be found. See example below.
24607
24608
    @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
24609
    See example below.
24610
24611
    @exceptionsafety Strong guarantee: if an exception is thrown, there are no
24612
    changes in the JSON value.
24613
24614
    @complexity Constant.
24615
24616
    @since version 2.0.0
24617
24618
    @liveexample{The behavior is shown in the example.,at_json_pointer_const}
24619
    */
24620
    const_reference at(const json_pointer& ptr) const
24621
    {
24622
        return ptr.get_checked(this);
24623
    }
24624
24625
    /*!
24626
    @brief return flattened JSON value
24627
24628
    The function creates a JSON object whose keys are JSON pointers (see [RFC
24629
    6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
24630
    primitive. The original JSON value can be restored using the @ref
24631
    unflatten() function.
24632
24633
    @return an object that maps JSON pointers to primitive values
24634
24635
    @note Empty objects and arrays are flattened to `null` and will not be
24636
          reconstructed correctly by the @ref unflatten() function.
24637
24638
    @complexity Linear in the size the JSON value.
24639
24640
    @liveexample{The following code shows how a JSON object is flattened to an
24641
    object whose keys consist of JSON pointers.,flatten}
24642
24643
    @sa @ref unflatten() for the reverse function
24644
24645
    @since version 2.0.0
24646
    */
24647
    basic_json flatten() const
24648
    {
24649
        basic_json result(value_t::object);
24650
        json_pointer::flatten("", *this, result);
24651
        return result;
24652
    }
24653
24654
    /*!
24655
    @brief unflatten a previously flattened JSON value
24656
24657
    The function restores the arbitrary nesting of a JSON value that has been
24658
    flattened before using the @ref flatten() function. The JSON value must
24659
    meet certain constraints:
24660
    1. The value must be an object.
24661
    2. The keys must be JSON pointers (see
24662
       [RFC 6901](https://tools.ietf.org/html/rfc6901))
24663
    3. The mapped values must be primitive JSON types.
24664
24665
    @return the original JSON from a flattened version
24666
24667
    @note Empty objects and arrays are flattened by @ref flatten() to `null`
24668
          values and can not unflattened to their original type. Apart from
24669
          this example, for a JSON value `j`, the following is always true:
24670
          `j == j.flatten().unflatten()`.
24671
24672
    @complexity Linear in the size the JSON value.
24673
24674
    @throw type_error.314  if value is not an object
24675
    @throw type_error.315  if object values are not primitive
24676
24677
    @liveexample{The following code shows how a flattened JSON object is
24678
    unflattened into the original nested JSON object.,unflatten}
24679
24680
    @sa @ref flatten() for the reverse function
24681
24682
    @since version 2.0.0
24683
    */
24684
    basic_json unflatten() const
24685
    {
24686
        return json_pointer::unflatten(*this);
24687
    }
24688
24689
    /// @}
24690
24691
    //////////////////////////
24692
    // JSON Patch functions //
24693
    //////////////////////////
24694
24695
    /// @name JSON Patch functions
24696
    /// @{
24697
24698
    /*!
24699
    @brief applies a JSON patch
24700
24701
    [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
24702
    expressing a sequence of operations to apply to a JSON) document. With
24703
    this function, a JSON Patch is applied to the current JSON value by
24704
    executing all operations from the patch.
24705
24706
    @param[in] json_patch  JSON patch document
24707
    @return patched document
24708
24709
    @note The application of a patch is atomic: Either all operations succeed
24710
          and the patched document is returned or an exception is thrown. In
24711
          any case, the original value is not changed: the patch is applied
24712
          to a copy of the value.
24713
24714
    @throw parse_error.104 if the JSON patch does not consist of an array of
24715
    objects
24716
24717
    @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
24718
    attributes are missing); example: `"operation add must have member path"`
24719
24720
    @throw out_of_range.401 if an array index is out of range.
24721
24722
    @throw out_of_range.403 if a JSON pointer inside the patch could not be
24723
    resolved successfully in the current JSON value; example: `"key baz not
24724
    found"`
24725
24726
    @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
24727
    "move")
24728
24729
    @throw other_error.501 if "test" operation was unsuccessful
24730
24731
    @complexity Linear in the size of the JSON value and the length of the
24732
    JSON patch. As usually only a fraction of the JSON value is affected by
24733
    the patch, the complexity can usually be neglected.
24734
24735
    @liveexample{The following code shows how a JSON patch is applied to a
24736
    value.,patch}
24737
24738
    @sa @ref diff -- create a JSON patch by comparing two JSON values
24739
24740
    @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
24741
    @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
24742
24743
    @since version 2.0.0
24744
    */
24745
    basic_json patch(const basic_json& json_patch) const
24746
    {
24747
        // make a working copy to apply the patch to
24748
        basic_json result = *this;
24749
24750
        // the valid JSON Patch operations
24751
        enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24752
24753
        const auto get_op = [](const std::string & op)
24754
        {
24755
            if (op == "add")
24756
            {
24757
                return patch_operations::add;
24758
            }
24759
            if (op == "remove")
24760
            {
24761
                return patch_operations::remove;
24762
            }
24763
            if (op == "replace")
24764
            {
24765
                return patch_operations::replace;
24766
            }
24767
            if (op == "move")
24768
            {
24769
                return patch_operations::move;
24770
            }
24771
            if (op == "copy")
24772
            {
24773
                return patch_operations::copy;
24774
            }
24775
            if (op == "test")
24776
            {
24777
                return patch_operations::test;
24778
            }
24779
24780
            return patch_operations::invalid;
24781
        };
24782
24783
        // wrapper for "add" operation; add value at ptr
24784
        const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24785
        {
24786
            // adding to the root of the target document means replacing it
24787
            if (ptr.empty())
24788
            {
24789
                result = val;
24790
                return;
24791
            }
24792
24793
            // make sure the top element of the pointer exists
24794
            json_pointer top_pointer = ptr.top();
24795
            if (top_pointer != ptr)
24796
            {
24797
                result.at(top_pointer);
24798
            }
24799
24800
            // get reference to parent of JSON pointer ptr
24801
            const auto last_path = ptr.back();
24802
            ptr.pop_back();
24803
            basic_json& parent = result[ptr];
24804
24805
            switch (parent.m_type)
24806
            {
24807
                case value_t::null:
24808
                case value_t::object:
24809
                {
24810
                    // use operator[] to add value
24811
                    parent[last_path] = val;
24812
                    break;
24813
                }
24814
24815
                case value_t::array:
24816
                {
24817
                    if (last_path == "-")
24818
                    {
24819
                        // special case: append to back
24820
                        parent.push_back(val);
24821
                    }
24822
                    else
24823
                    {
24824
                        const auto idx = json_pointer::array_index(last_path);
24825
                        if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24826
                        {
24827
                            // avoid undefined behavior
24828
                            JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24829
                        }
24830
24831
                        // default case: insert add offset
24832
                        parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24833
                    }
24834
                    break;
24835
                }
24836
24837
                // if there exists a parent it cannot be primitive
24838
                default:            // LCOV_EXCL_LINE
24839
                    JSON_ASSERT(false);  // LCOV_EXCL_LINE
24840
            }
24841
        };
24842
24843
        // wrapper for "remove" operation; remove value at ptr
24844
        const auto operation_remove = [&result](json_pointer & ptr)
24845
        {
24846
            // get reference to parent of JSON pointer ptr
24847
            const auto last_path = ptr.back();
24848
            ptr.pop_back();
24849
            basic_json& parent = result.at(ptr);
24850
24851
            // remove child
24852
            if (parent.is_object())
24853
            {
24854
                // perform range check
24855
                auto it = parent.find(last_path);
24856
                if (JSON_HEDLEY_LIKELY(it != parent.end()))
24857
                {
24858
                    parent.erase(it);
24859
                }
24860
                else
24861
                {
24862
                    JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24863
                }
24864
            }
24865
            else if (parent.is_array())
24866
            {
24867
                // note erase performs range check
24868
                parent.erase(json_pointer::array_index(last_path));
24869
            }
24870
        };
24871
24872
        // type check: top level value must be an array
24873
        if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24874
        {
24875
            JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24876
        }
24877
24878
        // iterate and apply the operations
24879
        for (const auto& val : json_patch)
24880
        {
24881
            // wrapper to get a value for an operation
24882
            const auto get_value = [&val](const std::string & op,
24883
                                          const std::string & member,
24884
                                          bool string_type) -> basic_json &
24885
            {
24886
                // find value
24887
                auto it = val.m_value.object->find(member);
24888
24889
                // context-sensitive error message
24890
                const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24891
24892
                // check if desired value is present
24893
                if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24894
                {
24895
                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24896
                }
24897
24898
                // check if result is of type string
24899
                if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24900
                {
24901
                    JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24902
                }
24903
24904
                // no error: return value
24905
                return it->second;
24906
            };
24907
24908
            // type check: every element of the array must be an object
24909
            if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24910
            {
24911
                JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24912
            }
24913
24914
            // collect mandatory members
24915
            const auto op = get_value("op", "op", true).template get<std::string>();
24916
            const auto path = get_value(op, "path", true).template get<std::string>();
24917
            json_pointer ptr(path);
24918
24919
            switch (get_op(op))
24920
            {
24921
                case patch_operations::add:
24922
                {
24923
                    operation_add(ptr, get_value("add", "value", false));
24924
                    break;
24925
                }
24926
24927
                case patch_operations::remove:
24928
                {
24929
                    operation_remove(ptr);
24930
                    break;
24931
                }
24932
24933
                case patch_operations::replace:
24934
                {
24935
                    // the "path" location must exist - use at()
24936
                    result.at(ptr) = get_value("replace", "value", false);
24937
                    break;
24938
                }
24939
24940
                case patch_operations::move:
24941
                {
24942
                    const auto from_path = get_value("move", "from", true).template get<std::string>();
24943
                    json_pointer from_ptr(from_path);
24944
24945
                    // the "from" location must exist - use at()
24946
                    basic_json v = result.at(from_ptr);
24947
24948
                    // The move operation is functionally identical to a
24949
                    // "remove" operation on the "from" location, followed
24950
                    // immediately by an "add" operation at the target
24951
                    // location with the value that was just removed.
24952
                    operation_remove(from_ptr);
24953
                    operation_add(ptr, v);
24954
                    break;
24955
                }
24956
24957
                case patch_operations::copy:
24958
                {
24959
                    const auto from_path = get_value("copy", "from", true).template get<std::string>();
24960
                    const json_pointer from_ptr(from_path);
24961
24962
                    // the "from" location must exist - use at()
24963
                    basic_json v = result.at(from_ptr);
24964
24965
                    // The copy is functionally identical to an "add"
24966
                    // operation at the target location using the value
24967
                    // specified in the "from" member.
24968
                    operation_add(ptr, v);
24969
                    break;
24970
                }
24971
24972
                case patch_operations::test:
24973
                {
24974
                    bool success = false;
24975
                    JSON_TRY
24976
                    {
24977
                        // check if "value" matches the one at "path"
24978
                        // the "path" location must exist - use at()
24979
                        success = (result.at(ptr) == get_value("test", "value", false));
24980
                    }
24981
                    JSON_INTERNAL_CATCH (out_of_range&)
24982
                    {
24983
                        // ignore out of range errors: success remains false
24984
                    }
24985
24986
                    // throw an exception if test fails
24987
                    if (JSON_HEDLEY_UNLIKELY(!success))
24988
                    {
24989
                        JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24990
                    }
24991
24992
                    break;
24993
                }
24994
24995
                default:
24996
                {
24997
                    // op must be "add", "remove", "replace", "move", "copy", or
24998
                    // "test"
24999
                    JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
25000
                }
25001
            }
25002
        }
25003
25004
        return result;
25005
    }
25006
25007
    /*!
25008
    @brief creates a diff as a JSON patch
25009
25010
    Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
25011
    be changed into the value @a target by calling @ref patch function.
25012
25013
    @invariant For two JSON values @a source and @a target, the following code
25014
    yields always `true`:
25015
    @code {.cpp}
25016
    source.patch(diff(source, target)) == target;
25017
    @endcode
25018
25019
    @note Currently, only `remove`, `add`, and `replace` operations are
25020
          generated.
25021
25022
    @param[in] source  JSON value to compare from
25023
    @param[in] target  JSON value to compare against
25024
    @param[in] path    helper value to create JSON pointers
25025
25026
    @return a JSON patch to convert the @a source to @a target
25027
25028
    @complexity Linear in the lengths of @a source and @a target.
25029
25030
    @liveexample{The following code shows how a JSON patch is created as a
25031
    diff for two JSON values.,diff}
25032
25033
    @sa @ref patch -- apply a JSON patch
25034
    @sa @ref merge_patch -- apply a JSON Merge Patch
25035
25036
    @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
25037
25038
    @since version 2.0.0
25039
    */
25040
    JSON_HEDLEY_WARN_UNUSED_RESULT
25041
    static basic_json diff(const basic_json& source, const basic_json& target,
25042
                           const std::string& path = "")
25043
    {
25044
        // the patch
25045
        basic_json result(value_t::array);
25046
25047
        // if the values are the same, return empty patch
25048
        if (source == target)
25049
        {
25050
            return result;
25051
        }
25052
25053
        if (source.type() != target.type())
25054
        {
25055
            // different types: replace value
25056
            result.push_back(
25057
            {
25058
                {"op", "replace"}, {"path", path}, {"value", target}
25059
            });
25060
            return result;
25061
        }
25062
25063
        switch (source.type())
25064
        {
25065
            case value_t::array:
25066
            {
25067
                // first pass: traverse common elements
25068
                std::size_t i = 0;
25069
                while (i < source.size() && i < target.size())
25070
                {
25071
                    // recursive call to compare array values at index i
25072
                    auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
25073
                    result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25074
                    ++i;
25075
                }
25076
25077
                // i now reached the end of at least one array
25078
                // in a second pass, traverse the remaining elements
25079
25080
                // remove my remaining elements
25081
                const auto end_index = static_cast<difference_type>(result.size());
25082
                while (i < source.size())
25083
                {
25084
                    // add operations in reverse order to avoid invalid
25085
                    // indices
25086
                    result.insert(result.begin() + end_index, object(
25087
                    {
25088
                        {"op", "remove"},
25089
                        {"path", path + "/" + std::to_string(i)}
25090
                    }));
25091
                    ++i;
25092
                }
25093
25094
                // add other remaining elements
25095
                while (i < target.size())
25096
                {
25097
                    result.push_back(
25098
                    {
25099
                        {"op", "add"},
25100
                        {"path", path + "/-"},
25101
                        {"value", target[i]}
25102
                    });
25103
                    ++i;
25104
                }
25105
25106
                break;
25107
            }
25108
25109
            case value_t::object:
25110
            {
25111
                // first pass: traverse this object's elements
25112
                for (auto it = source.cbegin(); it != source.cend(); ++it)
25113
                {
25114
                    // escape the key name to be used in a JSON patch
25115
                    const auto key = json_pointer::escape(it.key());
25116
25117
                    if (target.find(it.key()) != target.end())
25118
                    {
25119
                        // recursive call to compare object values at key it
25120
                        auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
25121
                        result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25122
                    }
25123
                    else
25124
                    {
25125
                        // found a key that is not in o -> remove it
25126
                        result.push_back(object(
25127
                        {
25128
                            {"op", "remove"}, {"path", path + "/" + key}
25129
                        }));
25130
                    }
25131
                }
25132
25133
                // second pass: traverse other object's elements
25134
                for (auto it = target.cbegin(); it != target.cend(); ++it)
25135
                {
25136
                    if (source.find(it.key()) == source.end())
25137
                    {
25138
                        // found a key that is not in this -> add it
25139
                        const auto key = json_pointer::escape(it.key());
25140
                        result.push_back(
25141
                        {
25142
                            {"op", "add"}, {"path", path + "/" + key},
25143
                            {"value", it.value()}
25144
                        });
25145
                    }
25146
                }
25147
25148
                break;
25149
            }
25150
25151
            default:
25152
            {
25153
                // both primitive type: replace value
25154
                result.push_back(
25155
                {
25156
                    {"op", "replace"}, {"path", path}, {"value", target}
25157
                });
25158
                break;
25159
            }
25160
        }
25161
25162
        return result;
25163
    }
25164
25165
    /// @}
25166
25167
    ////////////////////////////////
25168
    // JSON Merge Patch functions //
25169
    ////////////////////////////////
25170
25171
    /// @name JSON Merge Patch functions
25172
    /// @{
25173
25174
    /*!
25175
    @brief applies a JSON Merge Patch
25176
25177
    The merge patch format is primarily intended for use with the HTTP PATCH
25178
    method as a means of describing a set of modifications to a target
25179
    resource's content. This function applies a merge patch to the current
25180
    JSON value.
25181
25182
    The function implements the following algorithm from Section 2 of
25183
    [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
25184
25185
    ```
25186
    define MergePatch(Target, Patch):
25187
      if Patch is an Object:
25188
        if Target is not an Object:
25189
          Target = {} // Ignore the contents and set it to an empty Object
25190
        for each Name/Value pair in Patch:
25191
          if Value is null:
25192
            if Name exists in Target:
25193
              remove the Name/Value pair from Target
25194
          else:
25195
            Target[Name] = MergePatch(Target[Name], Value)
25196
        return Target
25197
      else:
25198
        return Patch
25199
    ```
25200
25201
    Thereby, `Target` is the current object; that is, the patch is applied to
25202
    the current value.
25203
25204
    @param[in] apply_patch  the patch to apply
25205
25206
    @complexity Linear in the lengths of @a patch.
25207
25208
    @liveexample{The following code shows how a JSON Merge Patch is applied to
25209
    a JSON document.,merge_patch}
25210
25211
    @sa @ref patch -- apply a JSON patch
25212
    @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
25213
25214
    @since version 3.0.0
25215
    */
25216
    void merge_patch(const basic_json& apply_patch)
25217
    {
25218
        if (apply_patch.is_object())
25219
        {
25220
            if (!is_object())
25221
            {
25222
                *this = object();
25223
            }
25224
            for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25225
            {
25226
                if (it.value().is_null())
25227
                {
25228
                    erase(it.key());
25229
                }
25230
                else
25231
                {
25232
                    operator[](it.key()).merge_patch(it.value());
25233
                }
25234
            }
25235
        }
25236
        else
25237
        {
25238
            *this = apply_patch;
25239
        }
25240
    }
25241
25242
    /// @}
25243
};
25244
25245
/*!
25246
@brief user-defined to_string function for JSON values
25247
25248
This function implements a user-defined to_string  for JSON objects.
25249
25250
@param[in] j  a JSON object
25251
@return a std::string object
25252
*/
25253
25254
NLOHMANN_BASIC_JSON_TPL_DECLARATION
25255
std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25256
{
25257
    return j.dump();
25258
}
25259
} // namespace nlohmann
25260
25261
///////////////////////
25262
// nonmember support //
25263
///////////////////////
25264
25265
// specialization of std::swap, and std::hash
25266
namespace std
25267
{
25268
25269
/// hash value for JSON objects
25270
template<>
25271
struct hash<nlohmann::json>
25272
{
25273
    /*!
25274
    @brief return a hash value for a JSON object
25275
25276
    @since version 1.0.0
25277
    */
25278
    std::size_t operator()(const nlohmann::json& j) const
25279
0
    {
25280
0
        return nlohmann::detail::hash(j);
25281
0
    }
25282
};
25283
25284
/// specialization for std::less<value_t>
25285
/// @note: do not remove the space after '<',
25286
///        see https://github.com/nlohmann/json/pull/679
25287
template<>
25288
struct less<::nlohmann::detail::value_t>
25289
{
25290
    /*!
25291
    @brief compare two value_t enum values
25292
    @since version 3.0.0
25293
    */
25294
    bool operator()(nlohmann::detail::value_t lhs,
25295
                    nlohmann::detail::value_t rhs) const noexcept
25296
0
    {
25297
0
        return nlohmann::detail::operator<(lhs, rhs);
25298
0
    }
25299
};
25300
25301
// C++20 prohibit function specialization in the std namespace.
25302
#ifndef JSON_HAS_CPP_20
25303
25304
/*!
25305
@brief exchanges the values of two JSON objects
25306
25307
@since version 1.0.0
25308
*/
25309
template<>
25310
inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25311
    is_nothrow_move_constructible<nlohmann::json>::value&&
25312
    is_nothrow_move_assignable<nlohmann::json>::value
25313
                              )
25314
0
{
25315
0
    j1.swap(j2);
25316
0
}
25317
25318
#endif
25319
25320
} // namespace std
25321
25322
/*!
25323
@brief user-defined string literal for JSON values
25324
25325
This operator implements a user-defined string literal for JSON objects. It
25326
can be used by adding `"_json"` to a string literal and returns a JSON object
25327
if no parse error occurred.
25328
25329
@param[in] s  a string representation of a JSON object
25330
@param[in] n  the length of string @a s
25331
@return a JSON object
25332
25333
@since version 1.0.0
25334
*/
25335
JSON_HEDLEY_NON_NULL(1)
25336
inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25337
0
{
25338
0
    return nlohmann::json::parse(s, s + n);
25339
0
}
25340
25341
/*!
25342
@brief user-defined string literal for JSON pointer
25343
25344
This operator implements a user-defined string literal for JSON Pointers. It
25345
can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
25346
object if no parse error occurred.
25347
25348
@param[in] s  a string representation of a JSON Pointer
25349
@param[in] n  the length of string @a s
25350
@return a JSON pointer object
25351
25352
@since version 2.0.0
25353
*/
25354
JSON_HEDLEY_NON_NULL(1)
25355
inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25356
0
{
25357
0
    return nlohmann::json::json_pointer(std::string(s, n));
25358
0
}
25359
25360
// #include <nlohmann/detail/macro_unscope.hpp>
25361
25362
25363
// restore GCC/clang diagnostic settings
25364
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25365
    #pragma GCC diagnostic pop
25366
#endif
25367
#if defined(__clang__)
25368
    #pragma GCC diagnostic pop
25369
#endif
25370
25371
// clean up
25372
#undef JSON_ASSERT
25373
#undef JSON_INTERNAL_CATCH
25374
#undef JSON_CATCH
25375
#undef JSON_THROW
25376
#undef JSON_TRY
25377
#undef JSON_PRIVATE_UNLESS_TESTED
25378
#undef JSON_HAS_CPP_14
25379
#undef JSON_HAS_CPP_17
25380
#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25381
#undef NLOHMANN_BASIC_JSON_TPL
25382
#undef JSON_EXPLICIT
25383
25384
// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25385
#undef JSON_HEDLEY_ALWAYS_INLINE
25386
#undef JSON_HEDLEY_ARM_VERSION
25387
#undef JSON_HEDLEY_ARM_VERSION_CHECK
25388
#undef JSON_HEDLEY_ARRAY_PARAM
25389
#undef JSON_HEDLEY_ASSUME
25390
#undef JSON_HEDLEY_BEGIN_C_DECLS
25391
#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25392
#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25393
#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25394
#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25395
#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25396
#undef JSON_HEDLEY_CLANG_HAS_FEATURE
25397
#undef JSON_HEDLEY_CLANG_HAS_WARNING
25398
#undef JSON_HEDLEY_COMPCERT_VERSION
25399
#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25400
#undef JSON_HEDLEY_CONCAT
25401
#undef JSON_HEDLEY_CONCAT3
25402
#undef JSON_HEDLEY_CONCAT3_EX
25403
#undef JSON_HEDLEY_CONCAT_EX
25404
#undef JSON_HEDLEY_CONST
25405
#undef JSON_HEDLEY_CONSTEXPR
25406
#undef JSON_HEDLEY_CONST_CAST
25407
#undef JSON_HEDLEY_CPP_CAST
25408
#undef JSON_HEDLEY_CRAY_VERSION
25409
#undef JSON_HEDLEY_CRAY_VERSION_CHECK
25410
#undef JSON_HEDLEY_C_DECL
25411
#undef JSON_HEDLEY_DEPRECATED
25412
#undef JSON_HEDLEY_DEPRECATED_FOR
25413
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25414
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25415
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25416
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25417
#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25418
#undef JSON_HEDLEY_DIAGNOSTIC_POP
25419
#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25420
#undef JSON_HEDLEY_DMC_VERSION
25421
#undef JSON_HEDLEY_DMC_VERSION_CHECK
25422
#undef JSON_HEDLEY_EMPTY_BASES
25423
#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25424
#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25425
#undef JSON_HEDLEY_END_C_DECLS
25426
#undef JSON_HEDLEY_FLAGS
25427
#undef JSON_HEDLEY_FLAGS_CAST
25428
#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25429
#undef JSON_HEDLEY_GCC_HAS_BUILTIN
25430
#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25431
#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25432
#undef JSON_HEDLEY_GCC_HAS_EXTENSION
25433
#undef JSON_HEDLEY_GCC_HAS_FEATURE
25434
#undef JSON_HEDLEY_GCC_HAS_WARNING
25435
#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25436
#undef JSON_HEDLEY_GCC_VERSION
25437
#undef JSON_HEDLEY_GCC_VERSION_CHECK
25438
#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25439
#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25440
#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25441
#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25442
#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25443
#undef JSON_HEDLEY_GNUC_HAS_FEATURE
25444
#undef JSON_HEDLEY_GNUC_HAS_WARNING
25445
#undef JSON_HEDLEY_GNUC_VERSION
25446
#undef JSON_HEDLEY_GNUC_VERSION_CHECK
25447
#undef JSON_HEDLEY_HAS_ATTRIBUTE
25448
#undef JSON_HEDLEY_HAS_BUILTIN
25449
#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25450
#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25451
#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25452
#undef JSON_HEDLEY_HAS_EXTENSION
25453
#undef JSON_HEDLEY_HAS_FEATURE
25454
#undef JSON_HEDLEY_HAS_WARNING
25455
#undef JSON_HEDLEY_IAR_VERSION
25456
#undef JSON_HEDLEY_IAR_VERSION_CHECK
25457
#undef JSON_HEDLEY_IBM_VERSION
25458
#undef JSON_HEDLEY_IBM_VERSION_CHECK
25459
#undef JSON_HEDLEY_IMPORT
25460
#undef JSON_HEDLEY_INLINE
25461
#undef JSON_HEDLEY_INTEL_CL_VERSION
25462
#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
25463
#undef JSON_HEDLEY_INTEL_VERSION
25464
#undef JSON_HEDLEY_INTEL_VERSION_CHECK
25465
#undef JSON_HEDLEY_IS_CONSTANT
25466
#undef JSON_HEDLEY_IS_CONSTEXPR_
25467
#undef JSON_HEDLEY_LIKELY
25468
#undef JSON_HEDLEY_MALLOC
25469
#undef JSON_HEDLEY_MESSAGE
25470
#undef JSON_HEDLEY_MSVC_VERSION
25471
#undef JSON_HEDLEY_MSVC_VERSION_CHECK
25472
#undef JSON_HEDLEY_NEVER_INLINE
25473
#undef JSON_HEDLEY_NON_NULL
25474
#undef JSON_HEDLEY_NO_ESCAPE
25475
#undef JSON_HEDLEY_NO_RETURN
25476
#undef JSON_HEDLEY_NO_THROW
25477
#undef JSON_HEDLEY_NULL
25478
#undef JSON_HEDLEY_PELLES_VERSION
25479
#undef JSON_HEDLEY_PELLES_VERSION_CHECK
25480
#undef JSON_HEDLEY_PGI_VERSION
25481
#undef JSON_HEDLEY_PGI_VERSION_CHECK
25482
#undef JSON_HEDLEY_PREDICT
25483
#undef JSON_HEDLEY_PRINTF_FORMAT
25484
#undef JSON_HEDLEY_PRIVATE
25485
#undef JSON_HEDLEY_PUBLIC
25486
#undef JSON_HEDLEY_PURE
25487
#undef JSON_HEDLEY_REINTERPRET_CAST
25488
#undef JSON_HEDLEY_REQUIRE
25489
#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25490
#undef JSON_HEDLEY_REQUIRE_MSG
25491
#undef JSON_HEDLEY_RESTRICT
25492
#undef JSON_HEDLEY_RETURNS_NON_NULL
25493
#undef JSON_HEDLEY_SENTINEL
25494
#undef JSON_HEDLEY_STATIC_ASSERT
25495
#undef JSON_HEDLEY_STATIC_CAST
25496
#undef JSON_HEDLEY_STRINGIFY
25497
#undef JSON_HEDLEY_STRINGIFY_EX
25498
#undef JSON_HEDLEY_SUNPRO_VERSION
25499
#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25500
#undef JSON_HEDLEY_TINYC_VERSION
25501
#undef JSON_HEDLEY_TINYC_VERSION_CHECK
25502
#undef JSON_HEDLEY_TI_ARMCL_VERSION
25503
#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25504
#undef JSON_HEDLEY_TI_CL2000_VERSION
25505
#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25506
#undef JSON_HEDLEY_TI_CL430_VERSION
25507
#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25508
#undef JSON_HEDLEY_TI_CL6X_VERSION
25509
#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25510
#undef JSON_HEDLEY_TI_CL7X_VERSION
25511
#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25512
#undef JSON_HEDLEY_TI_CLPRU_VERSION
25513
#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25514
#undef JSON_HEDLEY_TI_VERSION
25515
#undef JSON_HEDLEY_TI_VERSION_CHECK
25516
#undef JSON_HEDLEY_UNAVAILABLE
25517
#undef JSON_HEDLEY_UNLIKELY
25518
#undef JSON_HEDLEY_UNPREDICTABLE
25519
#undef JSON_HEDLEY_UNREACHABLE
25520
#undef JSON_HEDLEY_UNREACHABLE_RETURN
25521
#undef JSON_HEDLEY_VERSION
25522
#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25523
#undef JSON_HEDLEY_VERSION_DECODE_MINOR
25524
#undef JSON_HEDLEY_VERSION_DECODE_REVISION
25525
#undef JSON_HEDLEY_VERSION_ENCODE
25526
#undef JSON_HEDLEY_WARNING
25527
#undef JSON_HEDLEY_WARN_UNUSED_RESULT
25528
#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
25529
#undef JSON_HEDLEY_FALL_THROUGH
25530
25531
25532
25533
#endif  // INCLUDE_NLOHMANN_JSON_HPP_