Unreal SDK  v1.3.0
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1// __ _____ _____ _____
2// __| | __| | | | JSON for Modern C++
3// | | |__ | | | | | | version 3.11.2
4// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9/****************************************************************************\
10 * Note on documentation: The source files contain links to the online *
11 * documentation of the public API at https://json.nlohmann.me. This URL *
12 * contains the most recent documentation and should also be applicable to *
13 * previous versions; documentation for deprecated functions is not *
14 * removed, but marked deprecated. See "Generate documentation" section in *
15 * file docs/README.md. *
16\****************************************************************************/
17
18#ifndef INCLUDE_NLOHMANN_JSON_HPP_
19#define INCLUDE_NLOHMANN_JSON_HPP_
20
21#include <algorithm> // all_of, find, for_each
22#include <cstddef> // nullptr_t, ptrdiff_t, size_t
23#include <functional> // hash, less
24#include <initializer_list> // initializer_list
25#ifndef JSON_NO_IO
26 #include <iosfwd> // istream, ostream
27#endif // JSON_NO_IO
28#include <iterator> // random_access_iterator_tag
29#include <memory> // unique_ptr
30#include <numeric> // accumulate
31#include <string> // string, stoi, to_string
32#include <utility> // declval, forward, move, pair, swap
33#include <vector> // vector
34
35// #include <nlohmann/adl_serializer.hpp>
36// __ _____ _____ _____
37// __| | __| | | | JSON for Modern C++
38// | | |__ | | | | | | version 3.11.2
39// |_____|_____|_____|_|___| https://github.com/nlohmann/json
40//
41// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
42// SPDX-License-Identifier: MIT
43
44
45
46#include <utility>
47
48// #include <nlohmann/detail/abi_macros.hpp>
49// __ _____ _____ _____
50// __| | __| | | | JSON for Modern C++
51// | | |__ | | | | | | version 3.11.2
52// |_____|_____|_____|_|___| https://github.com/nlohmann/json
53//
54// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
55// SPDX-License-Identifier: MIT
56
57
58
59// This file contains all macro definitions affecting or depending on the ABI
60
61#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
62 #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
63 #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2
64 #warning "Already included a different version of the library!"
65 #endif
66 #endif
67#endif
68
69#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
70#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)
71#define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum)
72
73#ifndef JSON_DIAGNOSTICS
74 #define JSON_DIAGNOSTICS 0
75#endif
76
77#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
78 #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
79#endif
80
81#if JSON_DIAGNOSTICS
82 #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
83#else
84 #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
85#endif
86
87#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
88 #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
89#else
90 #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
91#endif
92
93#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
94 #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
95#endif
96
97// Construct the namespace ABI tags component
98#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
99#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
100 NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
101
102#define NLOHMANN_JSON_ABI_TAGS \
103 NLOHMANN_JSON_ABI_TAGS_CONCAT( \
104 NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
105 NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
106
107// Construct the namespace version component
108#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
109 _v ## major ## _ ## minor ## _ ## patch
110#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
111 NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
112
113#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
114#define NLOHMANN_JSON_NAMESPACE_VERSION
115#else
116#define NLOHMANN_JSON_NAMESPACE_VERSION \
117 NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
118 NLOHMANN_JSON_VERSION_MINOR, \
119 NLOHMANN_JSON_VERSION_PATCH)
120#endif
121
122// Combine namespace components
123#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
124#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
125 NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
126
127#ifndef NLOHMANN_JSON_NAMESPACE
128#define NLOHMANN_JSON_NAMESPACE \
129 nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
130 NLOHMANN_JSON_ABI_TAGS, \
131 NLOHMANN_JSON_NAMESPACE_VERSION)
132#endif
133
134#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
135#define NLOHMANN_JSON_NAMESPACE_BEGIN \
136 namespace nlohmann \
137 { \
138 inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
139 NLOHMANN_JSON_ABI_TAGS, \
140 NLOHMANN_JSON_NAMESPACE_VERSION) \
141 {
142#endif
143
144#ifndef NLOHMANN_JSON_NAMESPACE_END
145#define NLOHMANN_JSON_NAMESPACE_END \
146 } /* namespace (inline namespace) NOLINT(readability/namespace) */ \
147 } // namespace nlohmann
148#endif
149
150// #include <nlohmann/detail/conversions/from_json.hpp>
151// __ _____ _____ _____
152// __| | __| | | | JSON for Modern C++
153// | | |__ | | | | | | version 3.11.2
154// |_____|_____|_____|_|___| https://github.com/nlohmann/json
155//
156// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
157// SPDX-License-Identifier: MIT
158
159
160
161#include <algorithm> // transform
162#include <array> // array
163#include <forward_list> // forward_list
164#include <iterator> // inserter, front_inserter, end
165#include <map> // map
166#include <string> // string
167#include <tuple> // tuple, make_tuple
168#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
169#include <unordered_map> // unordered_map
170#include <utility> // pair, declval
171#include <valarray> // valarray
172
173// #include <nlohmann/detail/exceptions.hpp>
174// __ _____ _____ _____
175// __| | __| | | | JSON for Modern C++
176// | | |__ | | | | | | version 3.11.2
177// |_____|_____|_____|_|___| https://github.com/nlohmann/json
178//
179// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
180// SPDX-License-Identifier: MIT
181
182
183
184#include <cstddef> // nullptr_t
185#include <exception> // exception
186#include <stdexcept> // runtime_error
187#include <string> // to_string
188#include <vector> // vector
189
190// #include <nlohmann/detail/value_t.hpp>
191// __ _____ _____ _____
192// __| | __| | | | JSON for Modern C++
193// | | |__ | | | | | | version 3.11.2
194// |_____|_____|_____|_|___| https://github.com/nlohmann/json
195//
196// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
197// SPDX-License-Identifier: MIT
198
199
200
201#include <array> // array
202#include <cstddef> // size_t
203#include <cstdint> // uint8_t
204#include <string> // string
205
206// #include <nlohmann/detail/macro_scope.hpp>
207// __ _____ _____ _____
208// __| | __| | | | JSON for Modern C++
209// | | |__ | | | | | | version 3.11.2
210// |_____|_____|_____|_|___| https://github.com/nlohmann/json
211//
212// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
213// SPDX-License-Identifier: MIT
214
215
216
217#include <utility> // declval, pair
218// #include <nlohmann/detail/meta/detected.hpp>
219// __ _____ _____ _____
220// __| | __| | | | JSON for Modern C++
221// | | |__ | | | | | | version 3.11.2
222// |_____|_____|_____|_|___| https://github.com/nlohmann/json
223//
224// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
225// SPDX-License-Identifier: MIT
226
227
228
229#include <type_traits>
230
231// #include <nlohmann/detail/meta/void_t.hpp>
232// __ _____ _____ _____
233// __| | __| | | | JSON for Modern C++
234// | | |__ | | | | | | version 3.11.2
235// |_____|_____|_____|_|___| https://github.com/nlohmann/json
236//
237// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
238// SPDX-License-Identifier: MIT
239
240
241
242// #include <nlohmann/detail/abi_macros.hpp>
243
244
246namespace detail
247{
248
249template<typename ...Ts> struct make_void
250{
251 using type = void;
252};
253template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
254
255} // namespace detail
257
258
260namespace detail
261{
262
263// https://en.cppreference.com/w/cpp/experimental/is_detected
265{
266 nonesuch() = delete;
267 ~nonesuch() = delete;
268 nonesuch(nonesuch const&) = delete;
269 nonesuch(nonesuch const&&) = delete;
270 void operator=(nonesuch const&) = delete;
271 void operator=(nonesuch&&) = delete;
272};
273
274template<class Default,
275 class AlwaysVoid,
276 template<class...> class Op,
277 class... Args>
279{
280 using value_t = std::false_type;
281 using type = Default;
282};
283
284template<class Default, template<class...> class Op, class... Args>
285struct detector<Default, void_t<Op<Args...>>, Op, Args...>
286{
287 using value_t = std::true_type;
288 using type = Op<Args...>;
289};
290
291template<template<class...> class Op, class... Args>
292using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
293
294template<template<class...> class Op, class... Args>
295struct is_detected_lazy : is_detected<Op, Args...> { };
296
297template<template<class...> class Op, class... Args>
298using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
299
300template<class Default, template<class...> class Op, class... Args>
301using detected_or = detector<Default, void, Op, Args...>;
302
303template<class Default, template<class...> class Op, class... Args>
304using detected_or_t = typename detected_or<Default, Op, Args...>::type;
305
306template<class Expected, template<class...> class Op, class... Args>
307using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
308
309template<class To, template<class...> class Op, class... Args>
311 std::is_convertible<detected_t<Op, Args...>, To>;
312
313} // namespace detail
315
316// #include <nlohmann/thirdparty/hedley/hedley.hpp>
317
318
319// __ _____ _____ _____
320// __| | __| | | | JSON for Modern C++
321// | | |__ | | | | | | version 3.11.2
322// |_____|_____|_____|_|___| https://github.com/nlohmann/json
323//
324// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
325// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
326// SPDX-License-Identifier: MIT
327
328/* Hedley - https://nemequ.github.io/hedley
329 * Created by Evan Nemerson <evan@nemerson.com>
330 */
331
332#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
333#if defined(JSON_HEDLEY_VERSION)
334 #undef JSON_HEDLEY_VERSION
335#endif
336#define JSON_HEDLEY_VERSION 15
337
338#if defined(JSON_HEDLEY_STRINGIFY_EX)
339 #undef JSON_HEDLEY_STRINGIFY_EX
340#endif
341#define JSON_HEDLEY_STRINGIFY_EX(x) #x
342
343#if defined(JSON_HEDLEY_STRINGIFY)
344 #undef JSON_HEDLEY_STRINGIFY
345#endif
346#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
347
348#if defined(JSON_HEDLEY_CONCAT_EX)
349 #undef JSON_HEDLEY_CONCAT_EX
350#endif
351#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
352
353#if defined(JSON_HEDLEY_CONCAT)
354 #undef JSON_HEDLEY_CONCAT
355#endif
356#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
357
358#if defined(JSON_HEDLEY_CONCAT3_EX)
359 #undef JSON_HEDLEY_CONCAT3_EX
360#endif
361#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
362
363#if defined(JSON_HEDLEY_CONCAT3)
364 #undef JSON_HEDLEY_CONCAT3
365#endif
366#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
367
368#if defined(JSON_HEDLEY_VERSION_ENCODE)
369 #undef JSON_HEDLEY_VERSION_ENCODE
370#endif
371#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
372
373#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
374 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
375#endif
376#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
377
378#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
379 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
380#endif
381#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
382
383#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
384 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
385#endif
386#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
387
388#if defined(JSON_HEDLEY_GNUC_VERSION)
389 #undef JSON_HEDLEY_GNUC_VERSION
390#endif
391#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
392 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
393#elif defined(__GNUC__)
394 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
395#endif
396
397#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
398 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
399#endif
400#if defined(JSON_HEDLEY_GNUC_VERSION)
401 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
402#else
403 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
404#endif
405
406#if defined(JSON_HEDLEY_MSVC_VERSION)
407 #undef JSON_HEDLEY_MSVC_VERSION
408#endif
409#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
410 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
411#elif defined(_MSC_FULL_VER) && !defined(__ICL)
412 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
413#elif defined(_MSC_VER) && !defined(__ICL)
414 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
415#endif
416
417#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
418 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
419#endif
420#if !defined(JSON_HEDLEY_MSVC_VERSION)
421 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
422#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
423 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
424#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
425 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
426#else
427 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
428#endif
429
430#if defined(JSON_HEDLEY_INTEL_VERSION)
431 #undef JSON_HEDLEY_INTEL_VERSION
432#endif
433#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
434 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
435#elif defined(__INTEL_COMPILER) && !defined(__ICL)
436 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
437#endif
438
439#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
440 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
441#endif
442#if defined(JSON_HEDLEY_INTEL_VERSION)
443 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
444#else
445 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
446#endif
447
448#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
449 #undef JSON_HEDLEY_INTEL_CL_VERSION
450#endif
451#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
452 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
453#endif
454
455#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
456 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
457#endif
458#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
459 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
460#else
461 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
462#endif
463
464#if defined(JSON_HEDLEY_PGI_VERSION)
465 #undef JSON_HEDLEY_PGI_VERSION
466#endif
467#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
468 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
469#endif
470
471#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
472 #undef JSON_HEDLEY_PGI_VERSION_CHECK
473#endif
474#if defined(JSON_HEDLEY_PGI_VERSION)
475 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
476#else
477 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
478#endif
479
480#if defined(JSON_HEDLEY_SUNPRO_VERSION)
481 #undef JSON_HEDLEY_SUNPRO_VERSION
482#endif
483#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
484 #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)
485#elif defined(__SUNPRO_C)
486 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
487#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
488 #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)
489#elif defined(__SUNPRO_CC)
490 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
491#endif
492
493#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
494 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
495#endif
496#if defined(JSON_HEDLEY_SUNPRO_VERSION)
497 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
498#else
499 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
500#endif
501
502#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
503 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
504#endif
505#if defined(__EMSCRIPTEN__)
506 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
507#endif
508
509#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
510 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
511#endif
512#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
513 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
514#else
515 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
516#endif
517
518#if defined(JSON_HEDLEY_ARM_VERSION)
519 #undef JSON_HEDLEY_ARM_VERSION
520#endif
521#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
522 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
523#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
524 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
525#endif
526
527#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
528 #undef JSON_HEDLEY_ARM_VERSION_CHECK
529#endif
530#if defined(JSON_HEDLEY_ARM_VERSION)
531 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
532#else
533 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
534#endif
535
536#if defined(JSON_HEDLEY_IBM_VERSION)
537 #undef JSON_HEDLEY_IBM_VERSION
538#endif
539#if defined(__ibmxl__)
540 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
541#elif defined(__xlC__) && defined(__xlC_ver__)
542 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
543#elif defined(__xlC__)
544 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
545#endif
546
547#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
548 #undef JSON_HEDLEY_IBM_VERSION_CHECK
549#endif
550#if defined(JSON_HEDLEY_IBM_VERSION)
551 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
552#else
553 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
554#endif
555
556#if defined(JSON_HEDLEY_TI_VERSION)
557 #undef JSON_HEDLEY_TI_VERSION
558#endif
559#if \
560 defined(__TI_COMPILER_VERSION__) && \
561 ( \
562 defined(__TMS470__) || defined(__TI_ARM__) || \
563 defined(__MSP430__) || \
564 defined(__TMS320C2000__) \
565 )
566#if (__TI_COMPILER_VERSION__ >= 16000000)
567 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
568#endif
569#endif
570
571#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
572 #undef JSON_HEDLEY_TI_VERSION_CHECK
573#endif
574#if defined(JSON_HEDLEY_TI_VERSION)
575 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
576#else
577 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
578#endif
579
580#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
581 #undef JSON_HEDLEY_TI_CL2000_VERSION
582#endif
583#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
584 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
585#endif
586
587#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
588 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
589#endif
590#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
591 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
592#else
593 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
594#endif
595
596#if defined(JSON_HEDLEY_TI_CL430_VERSION)
597 #undef JSON_HEDLEY_TI_CL430_VERSION
598#endif
599#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
600 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
601#endif
602
603#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
604 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
605#endif
606#if defined(JSON_HEDLEY_TI_CL430_VERSION)
607 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
608#else
609 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
610#endif
611
612#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
613 #undef JSON_HEDLEY_TI_ARMCL_VERSION
614#endif
615#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
616 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
617#endif
618
619#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
620 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
621#endif
622#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
623 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
624#else
625 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
626#endif
627
628#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
629 #undef JSON_HEDLEY_TI_CL6X_VERSION
630#endif
631#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
632 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
633#endif
634
635#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
636 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
637#endif
638#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
639 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
640#else
641 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
642#endif
643
644#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
645 #undef JSON_HEDLEY_TI_CL7X_VERSION
646#endif
647#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
648 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
649#endif
650
651#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
652 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
653#endif
654#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
655 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
656#else
657 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
658#endif
659
660#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
661 #undef JSON_HEDLEY_TI_CLPRU_VERSION
662#endif
663#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
664 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
665#endif
666
667#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
668 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
669#endif
670#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
671 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
672#else
673 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
674#endif
675
676#if defined(JSON_HEDLEY_CRAY_VERSION)
677 #undef JSON_HEDLEY_CRAY_VERSION
678#endif
679#if defined(_CRAYC)
680 #if defined(_RELEASE_PATCHLEVEL)
681 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
682 #else
683 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
684 #endif
685#endif
686
687#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
688 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
689#endif
690#if defined(JSON_HEDLEY_CRAY_VERSION)
691 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
692#else
693 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
694#endif
695
696#if defined(JSON_HEDLEY_IAR_VERSION)
697 #undef JSON_HEDLEY_IAR_VERSION
698#endif
699#if defined(__IAR_SYSTEMS_ICC__)
700 #if __VER__ > 1000
701 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
702 #else
703 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
704 #endif
705#endif
706
707#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
708 #undef JSON_HEDLEY_IAR_VERSION_CHECK
709#endif
710#if defined(JSON_HEDLEY_IAR_VERSION)
711 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
712#else
713 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
714#endif
715
716#if defined(JSON_HEDLEY_TINYC_VERSION)
717 #undef JSON_HEDLEY_TINYC_VERSION
718#endif
719#if defined(__TINYC__)
720 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
721#endif
722
723#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
724 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
725#endif
726#if defined(JSON_HEDLEY_TINYC_VERSION)
727 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
728#else
729 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
730#endif
731
732#if defined(JSON_HEDLEY_DMC_VERSION)
733 #undef JSON_HEDLEY_DMC_VERSION
734#endif
735#if defined(__DMC__)
736 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
737#endif
738
739#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
740 #undef JSON_HEDLEY_DMC_VERSION_CHECK
741#endif
742#if defined(JSON_HEDLEY_DMC_VERSION)
743 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
744#else
745 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
746#endif
747
748#if defined(JSON_HEDLEY_COMPCERT_VERSION)
749 #undef JSON_HEDLEY_COMPCERT_VERSION
750#endif
751#if defined(__COMPCERT_VERSION__)
752 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
753#endif
754
755#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
756 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
757#endif
758#if defined(JSON_HEDLEY_COMPCERT_VERSION)
759 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
760#else
761 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
762#endif
763
764#if defined(JSON_HEDLEY_PELLES_VERSION)
765 #undef JSON_HEDLEY_PELLES_VERSION
766#endif
767#if defined(__POCC__)
768 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
769#endif
770
771#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
772 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
773#endif
774#if defined(JSON_HEDLEY_PELLES_VERSION)
775 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
776#else
777 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
778#endif
779
780#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
781 #undef JSON_HEDLEY_MCST_LCC_VERSION
782#endif
783#if defined(__LCC__) && defined(__LCC_MINOR__)
784 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
785#endif
786
787#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
788 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
789#endif
790#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
791 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
792#else
793 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
794#endif
795
796#if defined(JSON_HEDLEY_GCC_VERSION)
797 #undef JSON_HEDLEY_GCC_VERSION
798#endif
799#if \
800 defined(JSON_HEDLEY_GNUC_VERSION) && \
801 !defined(__clang__) && \
802 !defined(JSON_HEDLEY_INTEL_VERSION) && \
803 !defined(JSON_HEDLEY_PGI_VERSION) && \
804 !defined(JSON_HEDLEY_ARM_VERSION) && \
805 !defined(JSON_HEDLEY_CRAY_VERSION) && \
806 !defined(JSON_HEDLEY_TI_VERSION) && \
807 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
808 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
809 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
810 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
811 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
812 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
813 !defined(__COMPCERT__) && \
814 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
815 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
816#endif
817
818#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
819 #undef JSON_HEDLEY_GCC_VERSION_CHECK
820#endif
821#if defined(JSON_HEDLEY_GCC_VERSION)
822 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
823#else
824 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
825#endif
826
827#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
828 #undef JSON_HEDLEY_HAS_ATTRIBUTE
829#endif
830#if \
831 defined(__has_attribute) && \
832 ( \
833 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
834 )
835# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
836#else
837# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
838#endif
839
840#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
841 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
842#endif
843#if defined(__has_attribute)
844 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
845#else
846 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
847#endif
848
849#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
850 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
851#endif
852#if defined(__has_attribute)
853 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
854#else
855 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
856#endif
857
858#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
859 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
860#endif
861#if \
862 defined(__has_cpp_attribute) && \
863 defined(__cplusplus) && \
864 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
865 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
866#else
867 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
868#endif
869
870#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
871 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
872#endif
873#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
874 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
875#elif \
876 !defined(JSON_HEDLEY_PGI_VERSION) && \
877 !defined(JSON_HEDLEY_IAR_VERSION) && \
878 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
879 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
880 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
881#else
882 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
883#endif
884
885#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
886 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
887#endif
888#if defined(__has_cpp_attribute) && defined(__cplusplus)
889 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
890#else
891 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
892#endif
893
894#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
895 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
896#endif
897#if defined(__has_cpp_attribute) && defined(__cplusplus)
898 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
899#else
900 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
901#endif
902
903#if defined(JSON_HEDLEY_HAS_BUILTIN)
904 #undef JSON_HEDLEY_HAS_BUILTIN
905#endif
906#if defined(__has_builtin)
907 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
908#else
909 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
910#endif
911
912#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
913 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
914#endif
915#if defined(__has_builtin)
916 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
917#else
918 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
919#endif
920
921#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
922 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
923#endif
924#if defined(__has_builtin)
925 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
926#else
927 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
928#endif
929
930#if defined(JSON_HEDLEY_HAS_FEATURE)
931 #undef JSON_HEDLEY_HAS_FEATURE
932#endif
933#if defined(__has_feature)
934 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
935#else
936 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
937#endif
938
939#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
940 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
941#endif
942#if defined(__has_feature)
943 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
944#else
945 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
946#endif
947
948#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
949 #undef JSON_HEDLEY_GCC_HAS_FEATURE
950#endif
951#if defined(__has_feature)
952 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
953#else
954 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
955#endif
956
957#if defined(JSON_HEDLEY_HAS_EXTENSION)
958 #undef JSON_HEDLEY_HAS_EXTENSION
959#endif
960#if defined(__has_extension)
961 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
962#else
963 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
964#endif
965
966#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
967 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
968#endif
969#if defined(__has_extension)
970 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
971#else
972 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
973#endif
974
975#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
976 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
977#endif
978#if defined(__has_extension)
979 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
980#else
981 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
982#endif
983
984#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
985 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
986#endif
987#if defined(__has_declspec_attribute)
988 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
989#else
990 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
991#endif
992
993#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
994 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
995#endif
996#if defined(__has_declspec_attribute)
997 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
998#else
999 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1000#endif
1001
1002#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
1003 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
1004#endif
1005#if defined(__has_declspec_attribute)
1006 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1007#else
1008 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1009#endif
1010
1011#if defined(JSON_HEDLEY_HAS_WARNING)
1012 #undef JSON_HEDLEY_HAS_WARNING
1013#endif
1014#if defined(__has_warning)
1015 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
1016#else
1017 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
1018#endif
1019
1020#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1021 #undef JSON_HEDLEY_GNUC_HAS_WARNING
1022#endif
1023#if defined(__has_warning)
1024 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1025#else
1026 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1027#endif
1028
1029#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1030 #undef JSON_HEDLEY_GCC_HAS_WARNING
1031#endif
1032#if defined(__has_warning)
1033 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1034#else
1035 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1036#endif
1037
1038#if \
1039 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1040 defined(__clang__) || \
1041 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1042 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1043 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1044 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1045 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1046 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1047 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1048 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1049 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1050 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1051 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1052 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1053 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1054 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1055 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1056 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1057 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1058#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1059 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1060#else
1061 #define JSON_HEDLEY_PRAGMA(value)
1062#endif
1063
1064#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1065 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1066#endif
1067#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1068 #undef JSON_HEDLEY_DIAGNOSTIC_POP
1069#endif
1070#if defined(__clang__)
1071 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1072 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1073#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1074 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1075 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1076#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1077 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1078 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1079#elif \
1080 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1081 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1082 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1083 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1084#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1085 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1086 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1087#elif \
1088 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1089 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1090 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1091 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1092 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1093 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1094 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1095 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1096#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1097 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1098 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1099#else
1100 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
1101 #define JSON_HEDLEY_DIAGNOSTIC_POP
1102#endif
1103
1104/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1105 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1106#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1107 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1108#endif
1109#if defined(__cplusplus)
1110# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1111# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1112# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1113# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1114 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1115 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1116 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1117 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1118 xpr \
1119 JSON_HEDLEY_DIAGNOSTIC_POP
1120# else
1121# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1122 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1123 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1124 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1125 xpr \
1126 JSON_HEDLEY_DIAGNOSTIC_POP
1127# endif
1128# else
1129# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1130 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1131 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1132 xpr \
1133 JSON_HEDLEY_DIAGNOSTIC_POP
1134# endif
1135# endif
1136#endif
1137#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1138 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1139#endif
1140
1141#if defined(JSON_HEDLEY_CONST_CAST)
1142 #undef JSON_HEDLEY_CONST_CAST
1143#endif
1144#if defined(__cplusplus)
1145# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1146#elif \
1147 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1148 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1149 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1150# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1151 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1152 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1153 ((T) (expr)); \
1154 JSON_HEDLEY_DIAGNOSTIC_POP \
1155 }))
1156#else
1157# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1158#endif
1159
1160#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1161 #undef JSON_HEDLEY_REINTERPRET_CAST
1162#endif
1163#if defined(__cplusplus)
1164 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1165#else
1166 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1167#endif
1168
1169#if defined(JSON_HEDLEY_STATIC_CAST)
1170 #undef JSON_HEDLEY_STATIC_CAST
1171#endif
1172#if defined(__cplusplus)
1173 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1174#else
1175 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1176#endif
1177
1178#if defined(JSON_HEDLEY_CPP_CAST)
1179 #undef JSON_HEDLEY_CPP_CAST
1180#endif
1181#if defined(__cplusplus)
1182# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1183# define JSON_HEDLEY_CPP_CAST(T, expr) \
1184 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1185 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1186 ((T) (expr)) \
1187 JSON_HEDLEY_DIAGNOSTIC_POP
1188# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1189# define JSON_HEDLEY_CPP_CAST(T, expr) \
1190 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1191 _Pragma("diag_suppress=Pe137") \
1192 JSON_HEDLEY_DIAGNOSTIC_POP
1193# else
1194# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1195# endif
1196#else
1197# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1198#endif
1199
1200#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1201 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1202#endif
1203#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1204 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1205#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1206 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1207#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1208 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1209#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1210 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1211#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1212 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1213#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1214 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1215#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1216 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1217#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1218 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1219#elif \
1220 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1221 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1222 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1223 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1225 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1227 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1229 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1230 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1231 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1232#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1233 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1234#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1235 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1236#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1237 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1238#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1239 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1240#else
1241 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1242#endif
1243
1244#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1245 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1246#endif
1247#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1248 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1249#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1250 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1251#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1252 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1253#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1254 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1255#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1256 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1257#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1258 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1259#elif \
1260 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1261 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1262 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1263 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1264 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1265#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1266 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1267#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1268 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1269#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1270 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1271#else
1272 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1273#endif
1274
1275#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1276 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1277#endif
1278#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1279 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1280#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1281 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1282#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1283 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1284#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1285 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1286#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1287 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1288#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1289 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1290#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1291 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1292#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1293 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1294#elif \
1295 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1296 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1297 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1298 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1299#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1300 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1301#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1302 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1303#else
1304 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1305#endif
1306
1307#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1308 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1309#endif
1310#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1311 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1312#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1313 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1314#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1315 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1316#else
1317 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1318#endif
1319
1320#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1321 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1322#endif
1323#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1324 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1325#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1326 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1327#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1328 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1329#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1330 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1331#else
1332 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1333#endif
1334
1335#if defined(JSON_HEDLEY_DEPRECATED)
1336 #undef JSON_HEDLEY_DEPRECATED
1337#endif
1338#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1339 #undef JSON_HEDLEY_DEPRECATED_FOR
1340#endif
1341#if \
1342 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1343 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1344 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1345 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1346#elif \
1347 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1348 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1349 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1350 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1351 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1352 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1353 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1354 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1355 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1356 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1357 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1358 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1359 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1360 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1361#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1362 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1363 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1364#elif \
1365 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1366 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1367 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1368 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1369 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1370 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1371 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1372 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1373 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1374 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1375 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1376 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1377 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1378 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1379 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1380 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1381 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1382 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1383#elif \
1384 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1385 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1386 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1387 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1388 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1389#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1390 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1391 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1392#else
1393 #define JSON_HEDLEY_DEPRECATED(since)
1394 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1395#endif
1396
1397#if defined(JSON_HEDLEY_UNAVAILABLE)
1398 #undef JSON_HEDLEY_UNAVAILABLE
1399#endif
1400#if \
1401 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1402 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1403 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1404 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1405 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1406#else
1407 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1408#endif
1409
1410#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1411 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1412#endif
1413#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1414 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1415#endif
1416#if \
1417 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1418 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1419 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1420 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1421 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1422 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1423 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1424 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1425 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1426 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1427 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1428 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1429 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1430 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1431 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1432 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1433 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1434 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1435 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1436#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1437 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1438 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1439#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1440 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1441 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1442#elif defined(_Check_return_) /* SAL */
1443 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1444 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1445#else
1446 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1447 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1448#endif
1449
1450#if defined(JSON_HEDLEY_SENTINEL)
1451 #undef JSON_HEDLEY_SENTINEL
1452#endif
1453#if \
1454 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1455 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1456 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1457 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1458 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1459 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1460#else
1461 #define JSON_HEDLEY_SENTINEL(position)
1462#endif
1463
1464#if defined(JSON_HEDLEY_NO_RETURN)
1465 #undef JSON_HEDLEY_NO_RETURN
1466#endif
1467#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1468 #define JSON_HEDLEY_NO_RETURN __noreturn
1469#elif \
1470 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1471 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1472 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1473#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1474 #define JSON_HEDLEY_NO_RETURN _Noreturn
1475#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1476 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1477#elif \
1478 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1479 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1480 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1481 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1482 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1483 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1484 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1485 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1486 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1488 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1490 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1492 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1493 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1494 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1495 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1496#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1497 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1498#elif \
1499 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1500 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1501 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1502#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1503 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1504#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1505 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1506#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1507 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1508#else
1509 #define JSON_HEDLEY_NO_RETURN
1510#endif
1511
1512#if defined(JSON_HEDLEY_NO_ESCAPE)
1513 #undef JSON_HEDLEY_NO_ESCAPE
1514#endif
1515#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1516 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1517#else
1518 #define JSON_HEDLEY_NO_ESCAPE
1519#endif
1520
1521#if defined(JSON_HEDLEY_UNREACHABLE)
1522 #undef JSON_HEDLEY_UNREACHABLE
1523#endif
1524#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1525 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1526#endif
1527#if defined(JSON_HEDLEY_ASSUME)
1528 #undef JSON_HEDLEY_ASSUME
1529#endif
1530#if \
1531 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1532 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1533 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1534 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1535#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1536 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1537#elif \
1538 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1539 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1540 #if defined(__cplusplus)
1541 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1542 #else
1543 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1544 #endif
1545#endif
1546#if \
1547 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1548 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1549 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1550 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1551 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1552 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1553 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1554 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1555#elif defined(JSON_HEDLEY_ASSUME)
1556 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1557#endif
1558#if !defined(JSON_HEDLEY_ASSUME)
1559 #if defined(JSON_HEDLEY_UNREACHABLE)
1560 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1561 #else
1562 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1563 #endif
1564#endif
1565#if defined(JSON_HEDLEY_UNREACHABLE)
1566 #if \
1567 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1568 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1569 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1570 #else
1571 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1572 #endif
1573#else
1574 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1575#endif
1576#if !defined(JSON_HEDLEY_UNREACHABLE)
1577 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1578#endif
1579
1581#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1582 #pragma clang diagnostic ignored "-Wpedantic"
1583#endif
1584#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1585 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1586#endif
1587#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1588 #if defined(__clang__)
1589 #pragma clang diagnostic ignored "-Wvariadic-macros"
1590 #elif defined(JSON_HEDLEY_GCC_VERSION)
1591 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1592 #endif
1593#endif
1594#if defined(JSON_HEDLEY_NON_NULL)
1595 #undef JSON_HEDLEY_NON_NULL
1596#endif
1597#if \
1598 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1599 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1600 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1601 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1602 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1603#else
1604 #define JSON_HEDLEY_NON_NULL(...)
1605#endif
1607
1608#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1609 #undef JSON_HEDLEY_PRINTF_FORMAT
1610#endif
1611#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1612 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1613#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1614 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1615#elif \
1616 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1617 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1618 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1619 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1620 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1621 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1622 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1624 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1625 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1626 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1627 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1628 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1629 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1630 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1631 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1632 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1633 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1634#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1635 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1636#else
1637 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1638#endif
1639
1640#if defined(JSON_HEDLEY_CONSTEXPR)
1641 #undef JSON_HEDLEY_CONSTEXPR
1642#endif
1643#if defined(__cplusplus)
1644 #if __cplusplus >= 201103L
1645 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1646 #endif
1647#endif
1648#if !defined(JSON_HEDLEY_CONSTEXPR)
1649 #define JSON_HEDLEY_CONSTEXPR
1650#endif
1651
1652#if defined(JSON_HEDLEY_PREDICT)
1653 #undef JSON_HEDLEY_PREDICT
1654#endif
1655#if defined(JSON_HEDLEY_LIKELY)
1656 #undef JSON_HEDLEY_LIKELY
1657#endif
1658#if defined(JSON_HEDLEY_UNLIKELY)
1659 #undef JSON_HEDLEY_UNLIKELY
1660#endif
1661#if defined(JSON_HEDLEY_UNPREDICTABLE)
1662 #undef JSON_HEDLEY_UNPREDICTABLE
1663#endif
1664#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1665 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1666#endif
1667#if \
1668 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1669 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1670 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1671# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1672# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1673# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1674# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1675# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1676#elif \
1677 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1678 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1679 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1680 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1681 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1682 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1683 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1684 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1685 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1686 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1687 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1688 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1689 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1690 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1691 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1692 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1693# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1694 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1695# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1696 (__extension__ ({ \
1697 double hedley_probability_ = (probability); \
1698 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1699 }))
1700# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1701 (__extension__ ({ \
1702 double hedley_probability_ = (probability); \
1703 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1704 }))
1705# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1706# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1707#else
1708# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1709# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1710# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1711# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1712# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1713#endif
1714#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1715 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1716#endif
1717
1718#if defined(JSON_HEDLEY_MALLOC)
1719 #undef JSON_HEDLEY_MALLOC
1720#endif
1721#if \
1722 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1723 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1724 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1725 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1726 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1727 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1728 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1729 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1730 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1731 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1732 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1733 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1734 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1735 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1736 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1737 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1738 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1739 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1740 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1741#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1742 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1743#elif \
1744 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1745 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1746 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1747#else
1748 #define JSON_HEDLEY_MALLOC
1749#endif
1750
1751#if defined(JSON_HEDLEY_PURE)
1752 #undef JSON_HEDLEY_PURE
1753#endif
1754#if \
1755 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1756 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1757 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1758 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1759 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1760 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1761 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1762 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1763 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1764 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1765 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1766 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1767 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1768 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1769 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1770 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1771 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1772 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1773 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1774# define JSON_HEDLEY_PURE __attribute__((__pure__))
1775#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1776# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1777#elif defined(__cplusplus) && \
1778 ( \
1779 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1780 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1781 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1782 )
1783# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1784#else
1785# define JSON_HEDLEY_PURE
1786#endif
1787
1788#if defined(JSON_HEDLEY_CONST)
1789 #undef JSON_HEDLEY_CONST
1790#endif
1791#if \
1792 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1793 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1794 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1795 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1796 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1797 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1798 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1799 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1800 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1801 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1802 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1803 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1804 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1805 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1806 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1807 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1808 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1809 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1810 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1811 #define JSON_HEDLEY_CONST __attribute__((__const__))
1812#elif \
1813 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1814 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1815#else
1816 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1817#endif
1818
1819#if defined(JSON_HEDLEY_RESTRICT)
1820 #undef JSON_HEDLEY_RESTRICT
1821#endif
1822#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1823 #define JSON_HEDLEY_RESTRICT restrict
1824#elif \
1825 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1826 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1827 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1828 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1829 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1830 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1831 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1832 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1833 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1834 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1835 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1836 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1837 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1838 defined(__clang__) || \
1839 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1840 #define JSON_HEDLEY_RESTRICT __restrict
1841#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1842 #define JSON_HEDLEY_RESTRICT _Restrict
1843#else
1844 #define JSON_HEDLEY_RESTRICT
1845#endif
1846
1847#if defined(JSON_HEDLEY_INLINE)
1848 #undef JSON_HEDLEY_INLINE
1849#endif
1850#if \
1851 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1852 (defined(__cplusplus) && (__cplusplus >= 199711L))
1853 #define JSON_HEDLEY_INLINE inline
1854#elif \
1855 defined(JSON_HEDLEY_GCC_VERSION) || \
1856 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1857 #define JSON_HEDLEY_INLINE __inline__
1858#elif \
1859 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1860 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1861 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1862 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1863 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1864 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1865 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1866 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1867 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1868 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1869 #define JSON_HEDLEY_INLINE __inline
1870#else
1871 #define JSON_HEDLEY_INLINE
1872#endif
1873
1874#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1875 #undef JSON_HEDLEY_ALWAYS_INLINE
1876#endif
1877#if \
1878 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1879 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1880 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1881 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1882 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1883 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1884 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1885 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1886 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1887 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1888 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1889 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1890 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1891 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1892 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1893 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1894 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1895 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1896 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1897# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1898#elif \
1899 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1900 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1901# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1902#elif defined(__cplusplus) && \
1903 ( \
1904 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1905 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1906 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1907 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1908 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1909 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1910 )
1911# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1912#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1913# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1914#else
1915# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1916#endif
1917
1918#if defined(JSON_HEDLEY_NEVER_INLINE)
1919 #undef JSON_HEDLEY_NEVER_INLINE
1920#endif
1921#if \
1922 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1923 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1924 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1925 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1926 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1927 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1928 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1929 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1930 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1931 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1932 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1933 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1934 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1935 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1936 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1937 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1938 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1939 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1940 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1941 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1942#elif \
1943 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1944 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1945 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1946#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1947 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1948#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1949 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1950#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1951 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1952#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1953 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1954#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1955 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1956#else
1957 #define JSON_HEDLEY_NEVER_INLINE
1958#endif
1959
1960#if defined(JSON_HEDLEY_PRIVATE)
1961 #undef JSON_HEDLEY_PRIVATE
1962#endif
1963#if defined(JSON_HEDLEY_PUBLIC)
1964 #undef JSON_HEDLEY_PUBLIC
1965#endif
1966#if defined(JSON_HEDLEY_IMPORT)
1967 #undef JSON_HEDLEY_IMPORT
1968#endif
1969#if defined(_WIN32) || defined(__CYGWIN__)
1970# define JSON_HEDLEY_PRIVATE
1971# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1972# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1973#else
1974# if \
1975 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1976 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1977 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1978 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1979 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1980 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1981 ( \
1982 defined(__TI_EABI__) && \
1983 ( \
1984 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1985 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1986 ) \
1987 ) || \
1988 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1989# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1990# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1991# else
1992# define JSON_HEDLEY_PRIVATE
1993# define JSON_HEDLEY_PUBLIC
1994# endif
1995# define JSON_HEDLEY_IMPORT extern
1996#endif
1997
1998#if defined(JSON_HEDLEY_NO_THROW)
1999 #undef JSON_HEDLEY_NO_THROW
2000#endif
2001#if \
2002 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2003 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2004 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2005 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2006 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2007#elif \
2008 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2009 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
2010 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2011 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2012#else
2013 #define JSON_HEDLEY_NO_THROW
2014#endif
2015
2016#if defined(JSON_HEDLEY_FALL_THROUGH)
2017 #undef JSON_HEDLEY_FALL_THROUGH
2018#endif
2019#if \
2020 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2021 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2022 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2023 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2024#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2025 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2026#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2027 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2028#elif defined(__fallthrough) /* SAL */
2029 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
2030#else
2031 #define JSON_HEDLEY_FALL_THROUGH
2032#endif
2033
2034#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2035 #undef JSON_HEDLEY_RETURNS_NON_NULL
2036#endif
2037#if \
2038 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2039 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2040 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2041 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2042#elif defined(_Ret_notnull_) /* SAL */
2043 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2044#else
2045 #define JSON_HEDLEY_RETURNS_NON_NULL
2046#endif
2047
2048#if defined(JSON_HEDLEY_ARRAY_PARAM)
2049 #undef JSON_HEDLEY_ARRAY_PARAM
2050#endif
2051#if \
2052 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2053 !defined(__STDC_NO_VLA__) && \
2054 !defined(__cplusplus) && \
2055 !defined(JSON_HEDLEY_PGI_VERSION) && \
2056 !defined(JSON_HEDLEY_TINYC_VERSION)
2057 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2058#else
2059 #define JSON_HEDLEY_ARRAY_PARAM(name)
2060#endif
2061
2062#if defined(JSON_HEDLEY_IS_CONSTANT)
2063 #undef JSON_HEDLEY_IS_CONSTANT
2064#endif
2065#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2066 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2067#endif
2068/* JSON_HEDLEY_IS_CONSTEXPR_ is for
2069 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2070#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2071 #undef JSON_HEDLEY_IS_CONSTEXPR_
2072#endif
2073#if \
2074 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2075 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2076 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2077 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2078 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2079 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2080 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2081 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2082 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2083 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2084 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2085#endif
2086#if !defined(__cplusplus)
2087# if \
2088 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2089 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2090 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2091 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2092 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2093 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2094 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2095#if defined(__INTPTR_TYPE__)
2096 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2097#else
2098 #include <stdint.h>
2099 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2100#endif
2101# elif \
2102 ( \
2103 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2104 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2105 !defined(JSON_HEDLEY_PGI_VERSION) && \
2106 !defined(JSON_HEDLEY_IAR_VERSION)) || \
2107 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2108 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2109 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2110 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2111 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2112#if defined(__INTPTR_TYPE__)
2113 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2114#else
2115 #include <stdint.h>
2116 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2117#endif
2118# elif \
2119 defined(JSON_HEDLEY_GCC_VERSION) || \
2120 defined(JSON_HEDLEY_INTEL_VERSION) || \
2121 defined(JSON_HEDLEY_TINYC_VERSION) || \
2122 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2123 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2124 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2125 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2126 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2127 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2128 defined(__clang__)
2129# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2130 sizeof(void) != \
2131 sizeof(*( \
2132 1 ? \
2133 ((void*) ((expr) * 0L) ) : \
2134((struct { char v[sizeof(void) * 2]; } *) 1) \
2135 ) \
2136 ) \
2137 )
2138# endif
2139#endif
2140#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2141 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2142 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2143 #endif
2144 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2145#else
2146 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2147 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2148 #endif
2149 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2150#endif
2151
2152#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2153 #undef JSON_HEDLEY_BEGIN_C_DECLS
2154#endif
2155#if defined(JSON_HEDLEY_END_C_DECLS)
2156 #undef JSON_HEDLEY_END_C_DECLS
2157#endif
2158#if defined(JSON_HEDLEY_C_DECL)
2159 #undef JSON_HEDLEY_C_DECL
2160#endif
2161#if defined(__cplusplus)
2162 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2163 #define JSON_HEDLEY_END_C_DECLS }
2164 #define JSON_HEDLEY_C_DECL extern "C"
2165#else
2166 #define JSON_HEDLEY_BEGIN_C_DECLS
2167 #define JSON_HEDLEY_END_C_DECLS
2168 #define JSON_HEDLEY_C_DECL
2169#endif
2170
2171#if defined(JSON_HEDLEY_STATIC_ASSERT)
2172 #undef JSON_HEDLEY_STATIC_ASSERT
2173#endif
2174#if \
2175 !defined(__cplusplus) && ( \
2176 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2177 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2178 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2179 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2180 defined(_Static_assert) \
2181 )
2182# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2183#elif \
2184 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2185 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2186 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2187# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2188#else
2189# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2190#endif
2191
2192#if defined(JSON_HEDLEY_NULL)
2193 #undef JSON_HEDLEY_NULL
2194#endif
2195#if defined(__cplusplus)
2196 #if __cplusplus >= 201103L
2197 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2198 #elif defined(NULL)
2199 #define JSON_HEDLEY_NULL NULL
2200 #else
2201 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2202 #endif
2203#elif defined(NULL)
2204 #define JSON_HEDLEY_NULL NULL
2205#else
2206 #define JSON_HEDLEY_NULL ((void*) 0)
2207#endif
2208
2209#if defined(JSON_HEDLEY_MESSAGE)
2210 #undef JSON_HEDLEY_MESSAGE
2211#endif
2212#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2213# define JSON_HEDLEY_MESSAGE(msg) \
2214 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2215 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2216 JSON_HEDLEY_PRAGMA(message msg) \
2217 JSON_HEDLEY_DIAGNOSTIC_POP
2218#elif \
2219 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2220 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2221# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2222#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2223# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2224#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2225# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2226#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2227# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2228#else
2229# define JSON_HEDLEY_MESSAGE(msg)
2230#endif
2231
2232#if defined(JSON_HEDLEY_WARNING)
2233 #undef JSON_HEDLEY_WARNING
2234#endif
2235#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2236# define JSON_HEDLEY_WARNING(msg) \
2237 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2238 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2239 JSON_HEDLEY_PRAGMA(clang warning msg) \
2240 JSON_HEDLEY_DIAGNOSTIC_POP
2241#elif \
2242 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2243 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2244 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2245# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2246#elif \
2247 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2248 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2249# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2250#else
2251# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2252#endif
2253
2254#if defined(JSON_HEDLEY_REQUIRE)
2255 #undef JSON_HEDLEY_REQUIRE
2256#endif
2257#if defined(JSON_HEDLEY_REQUIRE_MSG)
2258 #undef JSON_HEDLEY_REQUIRE_MSG
2259#endif
2260#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2261# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2262# define JSON_HEDLEY_REQUIRE(expr) \
2263 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2264 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2265 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2266 JSON_HEDLEY_DIAGNOSTIC_POP
2267# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2268 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2269 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2270 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2271 JSON_HEDLEY_DIAGNOSTIC_POP
2272# else
2273# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2274# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2275# endif
2276#else
2277# define JSON_HEDLEY_REQUIRE(expr)
2278# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2279#endif
2280
2281#if defined(JSON_HEDLEY_FLAGS)
2282 #undef JSON_HEDLEY_FLAGS
2283#endif
2284#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2285 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2286#else
2287 #define JSON_HEDLEY_FLAGS
2288#endif
2289
2290#if defined(JSON_HEDLEY_FLAGS_CAST)
2291 #undef JSON_HEDLEY_FLAGS_CAST
2292#endif
2293#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2294# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2295 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2296 _Pragma("warning(disable:188)") \
2297 ((T) (expr)); \
2298 JSON_HEDLEY_DIAGNOSTIC_POP \
2299 }))
2300#else
2301# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2302#endif
2303
2304#if defined(JSON_HEDLEY_EMPTY_BASES)
2305 #undef JSON_HEDLEY_EMPTY_BASES
2306#endif
2307#if \
2308 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2309 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2310 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2311#else
2312 #define JSON_HEDLEY_EMPTY_BASES
2313#endif
2314
2315/* Remaining macros are deprecated. */
2316
2317#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2318 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2319#endif
2320#if defined(__clang__)
2321 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2322#else
2323 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2324#endif
2325
2326#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2327 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2328#endif
2329#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2330
2331#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2332 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2333#endif
2334#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2335
2336#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2337 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2338#endif
2339#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2340
2341#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2342 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2343#endif
2344#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2345
2346#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2347 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2348#endif
2349#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2350
2351#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2352 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2353#endif
2354#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2355
2356#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2357 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2358#endif
2359#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2360
2361#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2362
2363
2364// This file contains all internal macro definitions (except those affecting ABI)
2365// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2366
2367// #include <nlohmann/detail/abi_macros.hpp>
2368
2369
2370// exclude unsupported compilers
2371#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2372 #if defined(__clang__)
2373 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2374 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2375 #endif
2376 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2377 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2378 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2379 #endif
2380 #endif
2381#endif
2382
2383// C++ language standard detection
2384// if the user manually specified the used c++ version this is skipped
2385#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2386 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2387 #define JSON_HAS_CPP_20
2388 #define JSON_HAS_CPP_17
2389 #define JSON_HAS_CPP_14
2390 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2391 #define JSON_HAS_CPP_17
2392 #define JSON_HAS_CPP_14
2393 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2394 #define JSON_HAS_CPP_14
2395 #endif
2396 // the cpp 11 flag is always specified because it is the minimal required version
2397 #define JSON_HAS_CPP_11
2398#endif
2399
2400#ifdef __has_include
2401 #if __has_include(<version>)
2402 #include <version>
2403 #endif
2404#endif
2405
2406#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2407 #ifdef JSON_HAS_CPP_17
2408 #if defined(__cpp_lib_filesystem)
2409 #define JSON_HAS_FILESYSTEM 1
2410 #elif defined(__cpp_lib_experimental_filesystem)
2411 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2412 #elif !defined(__has_include)
2413 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2414 #elif __has_include(<filesystem>)
2415 #define JSON_HAS_FILESYSTEM 1
2416 #elif __has_include(<experimental/filesystem>)
2417 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2418 #endif
2419
2420 // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2421 #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2422 #undef JSON_HAS_FILESYSTEM
2423 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2424 #endif
2425
2426 // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2427 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2428 #undef JSON_HAS_FILESYSTEM
2429 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2430 #endif
2431
2432 // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2433 #if defined(__clang_major__) && __clang_major__ < 7
2434 #undef JSON_HAS_FILESYSTEM
2435 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2436 #endif
2437
2438 // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2439 #if defined(_MSC_VER) && _MSC_VER < 1914
2440 #undef JSON_HAS_FILESYSTEM
2441 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2442 #endif
2443
2444 // no filesystem support before iOS 13
2445 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2446 #undef JSON_HAS_FILESYSTEM
2447 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2448 #endif
2449
2450 // no filesystem support before macOS Catalina
2451 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2452 #undef JSON_HAS_FILESYSTEM
2453 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2454 #endif
2455 #endif
2456#endif
2457
2458#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2459 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2460#endif
2461
2462#ifndef JSON_HAS_FILESYSTEM
2463 #define JSON_HAS_FILESYSTEM 0
2464#endif
2465
2466#ifndef JSON_HAS_THREE_WAY_COMPARISON
2467 #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2468 && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2469 #define JSON_HAS_THREE_WAY_COMPARISON 1
2470 #else
2471 #define JSON_HAS_THREE_WAY_COMPARISON 0
2472 #endif
2473#endif
2474
2475#ifndef JSON_HAS_RANGES
2476 // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2477 #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2478 #define JSON_HAS_RANGES 0
2479 #elif defined(__cpp_lib_ranges)
2480 #define JSON_HAS_RANGES 1
2481 #else
2482 #define JSON_HAS_RANGES 0
2483 #endif
2484#endif
2485
2486#ifdef JSON_HAS_CPP_17
2487 #define JSON_INLINE_VARIABLE inline
2488#else
2489 #define JSON_INLINE_VARIABLE
2490#endif
2491
2492#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2493 #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2494#else
2495 #define JSON_NO_UNIQUE_ADDRESS
2496#endif
2497
2498// disable documentation warnings on clang
2499#if defined(__clang__)
2500 #pragma clang diagnostic push
2501 #pragma clang diagnostic ignored "-Wdocumentation"
2502 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2503#endif
2504
2505// allow disabling exceptions
2506#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2507 #define JSON_THROW(exception) throw exception
2508 #define JSON_TRY try
2509 #define JSON_CATCH(exception) catch(exception)
2510 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2511#else
2512 #include <cstdlib>
2513 #define JSON_THROW(exception) std::abort()
2514 #define JSON_TRY if(true)
2515 #define JSON_CATCH(exception) if(false)
2516 #define JSON_INTERNAL_CATCH(exception) if(false)
2517#endif
2518
2519// override exception macros
2520#if defined(JSON_THROW_USER)
2521 #undef JSON_THROW
2522 #define JSON_THROW JSON_THROW_USER
2523#endif
2524#if defined(JSON_TRY_USER)
2525 #undef JSON_TRY
2526 #define JSON_TRY JSON_TRY_USER
2527#endif
2528#if defined(JSON_CATCH_USER)
2529 #undef JSON_CATCH
2530 #define JSON_CATCH JSON_CATCH_USER
2531 #undef JSON_INTERNAL_CATCH
2532 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2533#endif
2534#if defined(JSON_INTERNAL_CATCH_USER)
2535 #undef JSON_INTERNAL_CATCH
2536 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2537#endif
2538
2539// allow overriding assert
2540#if !defined(JSON_ASSERT)
2541 #include <cassert> // assert
2542 #define JSON_ASSERT(x) assert(x)
2543#endif
2544
2545// allow to access some private functions (needed by the test suite)
2546#if defined(JSON_TESTS_PRIVATE)
2547 #define JSON_PRIVATE_UNLESS_TESTED public
2548#else
2549 #define JSON_PRIVATE_UNLESS_TESTED private
2550#endif
2551
2557#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2558 template<typename BasicJsonType> \
2559 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2560 { \
2561 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2562 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2563 auto it = std::find_if(std::begin(m), std::end(m), \
2564 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2565 { \
2566 return ej_pair.first == e; \
2567 }); \
2568 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2569 } \
2570 template<typename BasicJsonType> \
2571 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2572 { \
2573 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2574 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2575 auto it = std::find_if(std::begin(m), std::end(m), \
2576 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2577 { \
2578 return ej_pair.second == j; \
2579 }); \
2580 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2581 }
2582
2583// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2584// may be removed in the future once the class is split.
2585
2586#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2587 template<template<typename, typename, typename...> class ObjectType, \
2588 template<typename, typename...> class ArrayType, \
2589 class StringType, class BooleanType, class NumberIntegerType, \
2590 class NumberUnsignedType, class NumberFloatType, \
2591 template<typename> class AllocatorType, \
2592 template<typename, typename = void> class JSONSerializer, \
2593 class BinaryType>
2594
2595#define NLOHMANN_BASIC_JSON_TPL \
2596 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2597 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2598 AllocatorType, JSONSerializer, BinaryType>
2599
2600// Macros to simplify conversion from/to types
2601
2602#define NLOHMANN_JSON_EXPAND( x ) x
2603#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
2604#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2605 NLOHMANN_JSON_PASTE64, \
2606 NLOHMANN_JSON_PASTE63, \
2607 NLOHMANN_JSON_PASTE62, \
2608 NLOHMANN_JSON_PASTE61, \
2609 NLOHMANN_JSON_PASTE60, \
2610 NLOHMANN_JSON_PASTE59, \
2611 NLOHMANN_JSON_PASTE58, \
2612 NLOHMANN_JSON_PASTE57, \
2613 NLOHMANN_JSON_PASTE56, \
2614 NLOHMANN_JSON_PASTE55, \
2615 NLOHMANN_JSON_PASTE54, \
2616 NLOHMANN_JSON_PASTE53, \
2617 NLOHMANN_JSON_PASTE52, \
2618 NLOHMANN_JSON_PASTE51, \
2619 NLOHMANN_JSON_PASTE50, \
2620 NLOHMANN_JSON_PASTE49, \
2621 NLOHMANN_JSON_PASTE48, \
2622 NLOHMANN_JSON_PASTE47, \
2623 NLOHMANN_JSON_PASTE46, \
2624 NLOHMANN_JSON_PASTE45, \
2625 NLOHMANN_JSON_PASTE44, \
2626 NLOHMANN_JSON_PASTE43, \
2627 NLOHMANN_JSON_PASTE42, \
2628 NLOHMANN_JSON_PASTE41, \
2629 NLOHMANN_JSON_PASTE40, \
2630 NLOHMANN_JSON_PASTE39, \
2631 NLOHMANN_JSON_PASTE38, \
2632 NLOHMANN_JSON_PASTE37, \
2633 NLOHMANN_JSON_PASTE36, \
2634 NLOHMANN_JSON_PASTE35, \
2635 NLOHMANN_JSON_PASTE34, \
2636 NLOHMANN_JSON_PASTE33, \
2637 NLOHMANN_JSON_PASTE32, \
2638 NLOHMANN_JSON_PASTE31, \
2639 NLOHMANN_JSON_PASTE30, \
2640 NLOHMANN_JSON_PASTE29, \
2641 NLOHMANN_JSON_PASTE28, \
2642 NLOHMANN_JSON_PASTE27, \
2643 NLOHMANN_JSON_PASTE26, \
2644 NLOHMANN_JSON_PASTE25, \
2645 NLOHMANN_JSON_PASTE24, \
2646 NLOHMANN_JSON_PASTE23, \
2647 NLOHMANN_JSON_PASTE22, \
2648 NLOHMANN_JSON_PASTE21, \
2649 NLOHMANN_JSON_PASTE20, \
2650 NLOHMANN_JSON_PASTE19, \
2651 NLOHMANN_JSON_PASTE18, \
2652 NLOHMANN_JSON_PASTE17, \
2653 NLOHMANN_JSON_PASTE16, \
2654 NLOHMANN_JSON_PASTE15, \
2655 NLOHMANN_JSON_PASTE14, \
2656 NLOHMANN_JSON_PASTE13, \
2657 NLOHMANN_JSON_PASTE12, \
2658 NLOHMANN_JSON_PASTE11, \
2659 NLOHMANN_JSON_PASTE10, \
2660 NLOHMANN_JSON_PASTE9, \
2661 NLOHMANN_JSON_PASTE8, \
2662 NLOHMANN_JSON_PASTE7, \
2663 NLOHMANN_JSON_PASTE6, \
2664 NLOHMANN_JSON_PASTE5, \
2665 NLOHMANN_JSON_PASTE4, \
2666 NLOHMANN_JSON_PASTE3, \
2667 NLOHMANN_JSON_PASTE2, \
2668 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2669#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2670#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2671#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2672#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2673#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2674#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)
2675#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)
2676#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)
2677#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)
2678#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)
2679#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)
2680#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)
2681#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)
2682#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)
2683#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)
2684#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)
2685#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)
2686#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)
2687#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)
2688#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)
2689#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)
2690#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)
2691#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)
2692#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)
2693#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)
2694#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)
2695#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)
2696#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)
2697#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)
2698#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)
2699#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)
2700#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)
2701#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)
2702#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)
2703#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)
2704#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)
2705#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)
2706#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)
2707#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)
2708#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)
2709#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)
2710#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)
2711#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)
2712#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)
2713#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)
2714#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)
2715#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)
2716#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)
2717#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)
2718#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)
2719#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)
2720#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)
2721#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)
2722#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)
2723#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)
2724#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)
2725#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)
2726#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)
2727#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)
2728#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)
2729#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)
2730#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)
2731#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)
2732
2733#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2734#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2735#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2736
2742#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2743 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__)) } \
2744 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__)) }
2745
2746#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2747 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__)) } \
2748 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2749
2755#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2756 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__)) } \
2757 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__)) }
2758
2759#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2760 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__)) } \
2761 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2762
2763
2764// inspired from https://stackoverflow.com/a/26745591
2765// allows to call any std function as if (e.g. with begin):
2766// using std::begin; begin(x);
2767//
2768// it allows using the detected idiom to retrieve the return type
2769// of such an expression
2770#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2771 namespace detail { \
2772 using std::std_name; \
2773 \
2774 template<typename... T> \
2775 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2776 } \
2777 \
2778 namespace detail2 { \
2779 struct std_name##_tag \
2780 { \
2781 }; \
2782 \
2783 template<typename... T> \
2784 std_name##_tag std_name(T&&...); \
2785 \
2786 template<typename... T> \
2787 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2788 \
2789 template<typename... T> \
2790 struct would_call_std_##std_name \
2791 { \
2792 static constexpr auto const value = ::nlohmann::detail:: \
2793 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2794 }; \
2795 } /* namespace detail2 */ \
2796 \
2797 template<typename... T> \
2798 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2799 { \
2800 }
2801
2802#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2803 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2804#endif
2805
2806#if JSON_USE_IMPLICIT_CONVERSIONS
2807 #define JSON_EXPLICIT
2808#else
2809 #define JSON_EXPLICIT explicit
2810#endif
2811
2812#ifndef JSON_DISABLE_ENUM_SERIALIZATION
2813 #define JSON_DISABLE_ENUM_SERIALIZATION 0
2814#endif
2815
2816#ifndef JSON_USE_GLOBAL_UDLS
2817 #define JSON_USE_GLOBAL_UDLS 1
2818#endif
2819
2820#if JSON_HAS_THREE_WAY_COMPARISON
2821 #include <compare> // partial_ordering
2822#endif
2823
2825namespace detail
2826{
2827
2829// JSON type enumeration //
2831
2856enum class value_t : std::uint8_t
2857{
2858 null,
2859 object,
2860 array,
2861 string,
2862 boolean,
2865 number_float,
2866 binary,
2867 discarded
2868};
2869
2883#if JSON_HAS_THREE_WAY_COMPARISON
2884 inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2885#else
2886 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2887#endif
2888{
2889 static constexpr std::array<std::uint8_t, 9> order = {{
2890 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2891 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2892 6 /* binary */
2893 }
2894 };
2895
2896 const auto l_index = static_cast<std::size_t>(lhs);
2897 const auto r_index = static_cast<std::size_t>(rhs);
2898#if JSON_HAS_THREE_WAY_COMPARISON
2899 if (l_index < order.size() && r_index < order.size())
2900 {
2901 return order[l_index] <=> order[r_index]; // *NOPAD*
2902 }
2903 return std::partial_ordering::unordered;
2904#else
2905 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2906#endif
2907}
2908
2909// GCC selects the built-in operator< over an operator rewritten from
2910// a user-defined spaceship operator
2911// Clang, MSVC, and ICC select the rewritten candidate
2912// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2913#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2914inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2915{
2916 return std::is_lt(lhs <=> rhs); // *NOPAD*
2917}
2918#endif
2919
2920} // namespace detail
2922
2923// #include <nlohmann/detail/string_escape.hpp>
2924// __ _____ _____ _____
2925// __| | __| | | | JSON for Modern C++
2926// | | |__ | | | | | | version 3.11.2
2927// |_____|_____|_____|_|___| https://github.com/nlohmann/json
2928//
2929// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
2930// SPDX-License-Identifier: MIT
2931
2932
2933
2934// #include <nlohmann/detail/abi_macros.hpp>
2935
2936
2938namespace detail
2939{
2940
2954template<typename StringType>
2955inline void replace_substring(StringType& s, const StringType& f,
2956 const StringType& t)
2957{
2958 JSON_ASSERT(!f.empty());
2959 for (auto pos = s.find(f); // find first occurrence of f
2960 pos != StringType::npos; // make sure f was found
2961 s.replace(pos, f.size(), t), // replace with t, and
2962 pos = s.find(f, pos + t.size())) // find next occurrence of f
2963 {}
2964}
2965
2973template<typename StringType>
2974inline StringType escape(StringType s)
2975{
2976 replace_substring(s, StringType{"~"}, StringType{"~0"});
2977 replace_substring(s, StringType{"/"}, StringType{"~1"});
2978 return s;
2979}
2980
2988template<typename StringType>
2989static void unescape(StringType& s)
2990{
2991 replace_substring(s, StringType{"~1"}, StringType{"/"});
2992 replace_substring(s, StringType{"~0"}, StringType{"~"});
2993}
2994
2995} // namespace detail
2997
2998// #include <nlohmann/detail/input/position_t.hpp>
2999// __ _____ _____ _____
3000// __| | __| | | | JSON for Modern C++
3001// | | |__ | | | | | | version 3.11.2
3002// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3003//
3004// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3005// SPDX-License-Identifier: MIT
3006
3007
3008
3009#include <cstddef> // size_t
3010
3011// #include <nlohmann/detail/abi_macros.hpp>
3012
3013
3015namespace detail
3016{
3017
3020{
3022 std::size_t chars_read_total = 0;
3026 std::size_t lines_read = 0;
3027
3029 constexpr operator size_t() const
3030 {
3031 return chars_read_total;
3032 }
3033};
3034
3035} // namespace detail
3037
3038// #include <nlohmann/detail/macro_scope.hpp>
3039
3040// #include <nlohmann/detail/meta/cpp_future.hpp>
3041// __ _____ _____ _____
3042// __| | __| | | | JSON for Modern C++
3043// | | |__ | | | | | | version 3.11.2
3044// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3045//
3046// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3047// SPDX-FileCopyrightText: 2018 The Abseil Authors
3048// SPDX-License-Identifier: MIT
3049
3050
3051
3052#include <array> // array
3053#include <cstddef> // size_t
3054#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3055#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3056
3057// #include <nlohmann/detail/macro_scope.hpp>
3058
3059
3061namespace detail
3062{
3063
3064template<typename T>
3065using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3066
3067#ifdef JSON_HAS_CPP_14
3068
3069// the following utilities are natively available in C++14
3070using std::enable_if_t;
3071using std::index_sequence;
3072using std::make_index_sequence;
3073using std::index_sequence_for;
3074
3075#else
3076
3077// alias templates to reduce boilerplate
3078template<bool B, typename T = void>
3079using enable_if_t = typename std::enable_if<B, T>::type;
3080
3081// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3082// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3083
3085
3086// integer_sequence
3087//
3088// Class template representing a compile-time integer sequence. An instantiation
3089// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3090// type through its template arguments (which is a common need when
3091// working with C++11 variadic templates). `absl::integer_sequence` is designed
3092// to be a drop-in replacement for C++14's `std::integer_sequence`.
3093//
3094// Example:
3095//
3096// template< class T, T... Ints >
3097// void user_function(integer_sequence<T, Ints...>);
3098//
3099// int main()
3100// {
3101// // user_function's `T` will be deduced to `int` and `Ints...`
3102// // will be deduced to `0, 1, 2, 3, 4`.
3103// user_function(make_integer_sequence<int, 5>());
3104// }
3105template <typename T, T... Ints>
3107{
3108 using value_type = T;
3109 static constexpr std::size_t size() noexcept
3110 {
3111 return sizeof...(Ints);
3112 }
3113};
3114
3115// index_sequence
3116//
3117// A helper template for an `integer_sequence` of `size_t`,
3118// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3119// `std::index_sequence`.
3120template <size_t... Ints>
3121using index_sequence = integer_sequence<size_t, Ints...>;
3122
3123namespace utility_internal
3124{
3125
3126template <typename Seq, size_t SeqSize, size_t Rem>
3127struct Extend;
3128
3129// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3130template <typename T, T... Ints, size_t SeqSize>
3131struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3132{
3133 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3134};
3135
3136template <typename T, T... Ints, size_t SeqSize>
3137struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3138{
3139 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3140};
3141
3142// Recursion helper for 'make_integer_sequence<T, N>'.
3143// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3144template <typename T, size_t N>
3145struct Gen
3146{
3147 using type =
3148 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3149};
3150
3151template <typename T>
3152struct Gen<T, 0>
3153{
3155};
3156
3157} // namespace utility_internal
3158
3159// Compile-time sequences of integers
3160
3161// make_integer_sequence
3162//
3163// This template alias is equivalent to
3164// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3165// replacement for C++14's `std::make_integer_sequence`.
3166template <typename T, T N>
3168
3169// make_index_sequence
3170//
3171// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3172// and is designed to be a drop-in replacement for C++14's
3173// `std::make_index_sequence`.
3174template <size_t N>
3176
3177// index_sequence_for
3178//
3179// Converts a typename pack into an index sequence of the same length, and
3180// is designed to be a drop-in replacement for C++14's
3181// `std::index_sequence_for()`
3182template <typename... Ts>
3184
3186
3187#endif
3188
3189// dispatch utility (taken from ranges-v3)
3190template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3191template<> struct priority_tag<0> {};
3192
3193// taken from ranges-v3
3194template<typename T>
3196{
3197 static JSON_INLINE_VARIABLE constexpr T value{};
3198};
3199
3200#ifndef JSON_HAS_CPP_17
3201 template<typename T>
3202 constexpr T static_const<T>::value;
3203#endif
3204
3205template<typename T, typename... Args>
3206inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3207{
3208 return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
3209}
3210
3211} // namespace detail
3213
3214// #include <nlohmann/detail/meta/type_traits.hpp>
3215// __ _____ _____ _____
3216// __| | __| | | | JSON for Modern C++
3217// | | |__ | | | | | | version 3.11.2
3218// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3219//
3220// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3221// SPDX-License-Identifier: MIT
3222
3223
3224
3225#include <limits> // numeric_limits
3226#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3227#include <utility> // declval
3228#include <tuple> // tuple
3229
3230// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3231// __ _____ _____ _____
3232// __| | __| | | | JSON for Modern C++
3233// | | |__ | | | | | | version 3.11.2
3234// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3235//
3236// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3237// SPDX-License-Identifier: MIT
3238
3239
3240
3241#include <iterator> // random_access_iterator_tag
3242
3243// #include <nlohmann/detail/abi_macros.hpp>
3244
3245// #include <nlohmann/detail/meta/void_t.hpp>
3246
3247// #include <nlohmann/detail/meta/cpp_future.hpp>
3248
3249
3251namespace detail
3252{
3253
3254template<typename It, typename = void>
3256
3257template<typename It>
3259 It,
3260 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3261 typename It::reference, typename It::iterator_category >>
3262{
3263 using difference_type = typename It::difference_type;
3264 using value_type = typename It::value_type;
3265 using pointer = typename It::pointer;
3266 using reference = typename It::reference;
3267 using iterator_category = typename It::iterator_category;
3268};
3269
3270// This is required as some compilers implement std::iterator_traits in a way that
3271// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3272template<typename T, typename = void>
3274{
3275};
3276
3277template<typename T>
3278struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3279 : iterator_types<T>
3280{
3281};
3282
3283template<typename T>
3285{
3286 using iterator_category = std::random_access_iterator_tag;
3287 using value_type = T;
3288 using difference_type = ptrdiff_t;
3289 using pointer = T*;
3290 using reference = T&;
3291};
3292
3293} // namespace detail
3295
3296// #include <nlohmann/detail/macro_scope.hpp>
3297
3298// #include <nlohmann/detail/meta/call_std/begin.hpp>
3299// __ _____ _____ _____
3300// __| | __| | | | JSON for Modern C++
3301// | | |__ | | | | | | version 3.11.2
3302// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3303//
3304// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3305// SPDX-License-Identifier: MIT
3306
3307
3308
3309// #include <nlohmann/detail/macro_scope.hpp>
3310
3311
3313
3315
3317
3318// #include <nlohmann/detail/meta/call_std/end.hpp>
3319// __ _____ _____ _____
3320// __| | __| | | | JSON for Modern C++
3321// | | |__ | | | | | | version 3.11.2
3322// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3323//
3324// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3325// SPDX-License-Identifier: MIT
3326
3327
3328
3329// #include <nlohmann/detail/macro_scope.hpp>
3330
3331
3333
3335
3337
3338// #include <nlohmann/detail/meta/cpp_future.hpp>
3339
3340// #include <nlohmann/detail/meta/detected.hpp>
3341
3342// #include <nlohmann/json_fwd.hpp>
3343// __ _____ _____ _____
3344// __| | __| | | | JSON for Modern C++
3345// | | |__ | | | | | | version 3.11.2
3346// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3347//
3348// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
3349// SPDX-License-Identifier: MIT
3350
3351#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3352 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3353
3354 #include <cstdint> // int64_t, uint64_t
3355 #include <map> // map
3356 #include <memory> // allocator
3357 #include <string> // string
3358 #include <vector> // vector
3359
3360 // #include <nlohmann/detail/abi_macros.hpp>
3361
3362
3369
3377 template<typename T = void, typename SFINAE = void>
3378 struct adl_serializer;
3379
3382 template<template<typename U, typename V, typename... Args> class ObjectType =
3383 std::map,
3384 template<typename U, typename... Args> class ArrayType = std::vector,
3385 class StringType = std::string, class BooleanType = bool,
3386 class NumberIntegerType = std::int64_t,
3387 class NumberUnsignedType = std::uint64_t,
3388 class NumberFloatType = double,
3389 template<typename U> class AllocatorType = std::allocator,
3390 template<typename T, typename SFINAE = void> class JSONSerializer =
3392 class BinaryType = std::vector<std::uint8_t>>
3393 class basic_json;
3394
3397 template<typename RefStringType>
3398 class json_pointer;
3399
3405
3408 template<class Key, class T, class IgnoredLess, class Allocator>
3409 struct ordered_map;
3410
3414
3416
3417#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3418
3419
3429namespace detail
3430{
3431
3433// helpers //
3435
3436// Note to maintainers:
3437//
3438// Every trait in this file expects a non CV-qualified type.
3439// The only exceptions are in the 'aliases for detected' section
3440// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3441//
3442// In this case, T has to be properly CV-qualified to constraint the function arguments
3443// (e.g. to_json(BasicJsonType&, const T&))
3444
3445template<typename> struct is_basic_json : std::false_type {};
3446
3448struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3449
3450// used by exceptions create() member functions
3451// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3452// false_type otherwise
3453template<typename BasicJsonContext>
3455 std::integral_constant < bool,
3456 is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3457 || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3458{};
3459
3461// json_ref helpers //
3463
3464template<typename>
3465class json_ref;
3466
3467template<typename>
3468struct is_json_ref : std::false_type {};
3469
3470template<typename T>
3471struct is_json_ref<json_ref<T>> : std::true_type {};
3472
3474// aliases for detected //
3476
3477template<typename T>
3478using mapped_type_t = typename T::mapped_type;
3479
3480template<typename T>
3481using key_type_t = typename T::key_type;
3482
3483template<typename T>
3484using value_type_t = typename T::value_type;
3485
3486template<typename T>
3487using difference_type_t = typename T::difference_type;
3488
3489template<typename T>
3490using pointer_t = typename T::pointer;
3491
3492template<typename T>
3493using reference_t = typename T::reference;
3494
3495template<typename T>
3496using iterator_category_t = typename T::iterator_category;
3497
3498template<typename T, typename... Args>
3499using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3500
3501template<typename T, typename... Args>
3502using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3503
3504template<typename T, typename U>
3505using get_template_function = decltype(std::declval<T>().template get<U>());
3506
3507// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3508template<typename BasicJsonType, typename T, typename = void>
3509struct has_from_json : std::false_type {};
3510
3511// trait checking if j.get<T> is valid
3512// use this trait instead of std::is_constructible or std::is_convertible,
3513// both rely on, or make use of implicit conversions, and thus fail when T
3514// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3515template <typename BasicJsonType, typename T>
3517{
3519};
3520
3521template<typename BasicJsonType, typename T>
3522struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3523{
3524 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3525
3526 static constexpr bool value =
3528 const BasicJsonType&, T&>::value;
3529};
3530
3531// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3532// this overload is used for non-default-constructible user-defined-types
3533template<typename BasicJsonType, typename T, typename = void>
3534struct has_non_default_from_json : std::false_type {};
3535
3536template<typename BasicJsonType, typename T>
3537struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3538{
3539 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3540
3541 static constexpr bool value =
3543 const BasicJsonType&>::value;
3544};
3545
3546// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3547// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3548template<typename BasicJsonType, typename T, typename = void>
3549struct has_to_json : std::false_type {};
3550
3551template<typename BasicJsonType, typename T>
3552struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3553{
3554 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3555
3556 static constexpr bool value =
3557 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3558 T>::value;
3559};
3560
3561template<typename T>
3562using detect_key_compare = typename T::key_compare;
3563
3564template<typename T>
3565struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3566
3567// obtains the actual object key comparator
3568template<typename BasicJsonType>
3570{
3571 using object_t = typename BasicJsonType::object_t;
3572 using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3573 using type = typename std::conditional < has_key_compare<object_t>::value,
3574 typename object_t::key_compare, object_comparator_t>::type;
3575};
3576
3577template<typename BasicJsonType>
3579
3581// is_ functions //
3583
3584// https://en.cppreference.com/w/cpp/types/conjunction
3585template<class...> struct conjunction : std::true_type { };
3586template<class B> struct conjunction<B> : B { };
3587template<class B, class... Bn>
3588struct conjunction<B, Bn...>
3589: std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3590
3591// https://en.cppreference.com/w/cpp/types/negation
3592template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3593
3594// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3595// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3596// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3597template <typename T>
3598struct is_default_constructible : std::is_default_constructible<T> {};
3599
3600template <typename T1, typename T2>
3601struct is_default_constructible<std::pair<T1, T2>>
3602 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3603
3604template <typename T1, typename T2>
3605struct is_default_constructible<const std::pair<T1, T2>>
3606 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3607
3608template <typename... Ts>
3609struct is_default_constructible<std::tuple<Ts...>>
3610 : conjunction<is_default_constructible<Ts>...> {};
3611
3612template <typename... Ts>
3613struct is_default_constructible<const std::tuple<Ts...>>
3614 : conjunction<is_default_constructible<Ts>...> {};
3615
3616
3617template <typename T, typename... Args>
3618struct is_constructible : std::is_constructible<T, Args...> {};
3619
3620template <typename T1, typename T2>
3621struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3622
3623template <typename T1, typename T2>
3624struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3625
3626template <typename... Ts>
3627struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3628
3629template <typename... Ts>
3630struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3631
3632
3633template<typename T, typename = void>
3634struct is_iterator_traits : std::false_type {};
3635
3636template<typename T>
3638{
3639 private:
3640 using traits = iterator_traits<T>;
3641
3642 public:
3643 static constexpr auto value =
3649};
3650
3651template<typename T>
3653{
3654 private:
3655 using t_ref = typename std::add_lvalue_reference<T>::type;
3656
3657 using iterator = detected_t<result_of_begin, t_ref>;
3658 using sentinel = detected_t<result_of_end, t_ref>;
3659
3660 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3661 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3662 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3663 static constexpr auto is_iterator_begin =
3665
3666 public:
3667 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3668};
3669
3670template<typename R>
3671using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3672
3673template<typename T>
3675
3676// The following implementation of is_complete_type is taken from
3677// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3678// and is written by Xiang Fan who agreed to using it in this library.
3679
3680template<typename T, typename = void>
3681struct is_complete_type : std::false_type {};
3682
3683template<typename T>
3684struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3685
3686template<typename BasicJsonType, typename CompatibleObjectType,
3687 typename = void>
3688struct is_compatible_object_type_impl : std::false_type {};
3689
3690template<typename BasicJsonType, typename CompatibleObjectType>
3692 BasicJsonType, CompatibleObjectType,
3693 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3694 is_detected<key_type_t, CompatibleObjectType>::value >>
3695{
3696 using object_t = typename BasicJsonType::object_t;
3697
3698 // macOS's is_constructible does not play well with nonesuch...
3699 static constexpr bool value =
3700 is_constructible<typename object_t::key_type,
3701 typename CompatibleObjectType::key_type>::value &&
3702 is_constructible<typename object_t::mapped_type,
3703 typename CompatibleObjectType::mapped_type>::value;
3704};
3705
3706template<typename BasicJsonType, typename CompatibleObjectType>
3708 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3709
3710template<typename BasicJsonType, typename ConstructibleObjectType,
3711 typename = void>
3712struct is_constructible_object_type_impl : std::false_type {};
3713
3714template<typename BasicJsonType, typename ConstructibleObjectType>
3716 BasicJsonType, ConstructibleObjectType,
3717 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3718 is_detected<key_type_t, ConstructibleObjectType>::value >>
3719{
3720 using object_t = typename BasicJsonType::object_t;
3721
3722 static constexpr bool value =
3724 (std::is_move_assignable<ConstructibleObjectType>::value ||
3725 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3726 (is_constructible<typename ConstructibleObjectType::key_type,
3727 typename object_t::key_type>::value &&
3728 std::is_same <
3729 typename object_t::mapped_type,
3730 typename ConstructibleObjectType::mapped_type >::value)) ||
3731 (has_from_json<BasicJsonType,
3732 typename ConstructibleObjectType::mapped_type>::value ||
3734 BasicJsonType,
3735 typename ConstructibleObjectType::mapped_type >::value);
3736};
3737
3738template<typename BasicJsonType, typename ConstructibleObjectType>
3740 : is_constructible_object_type_impl<BasicJsonType,
3741 ConstructibleObjectType> {};
3742
3743template<typename BasicJsonType, typename CompatibleStringType>
3745{
3746 static constexpr auto value =
3748};
3749
3750template<typename BasicJsonType, typename ConstructibleStringType>
3752{
3753 // launder type through decltype() to fix compilation failure on ICPC
3754#ifdef __INTEL_COMPILER
3755 using laundered_type = decltype(std::declval<ConstructibleStringType>());
3756#else
3757 using laundered_type = ConstructibleStringType;
3758#endif
3759
3760 static constexpr auto value =
3761 conjunction <
3763 is_detected_exact<typename BasicJsonType::string_t::value_type,
3765};
3766
3767template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3768struct is_compatible_array_type_impl : std::false_type {};
3769
3770template<typename BasicJsonType, typename CompatibleArrayType>
3772 BasicJsonType, CompatibleArrayType,
3773 enable_if_t <
3774 is_detected<iterator_t, CompatibleArrayType>::value&&
3775 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3776// special case for types like std::filesystem::path whose iterator's value_type are themselves
3777// c.f. https://github.com/nlohmann/json/pull/3073
3778 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3779{
3780 static constexpr bool value =
3781 is_constructible<BasicJsonType,
3783};
3784
3785template<typename BasicJsonType, typename CompatibleArrayType>
3787 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3788
3789template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3790struct is_constructible_array_type_impl : std::false_type {};
3791
3792template<typename BasicJsonType, typename ConstructibleArrayType>
3794 BasicJsonType, ConstructibleArrayType,
3795 enable_if_t<std::is_same<ConstructibleArrayType,
3796 typename BasicJsonType::value_type>::value >>
3797 : std::true_type {};
3798
3799template<typename BasicJsonType, typename ConstructibleArrayType>
3801 BasicJsonType, ConstructibleArrayType,
3802 enable_if_t < !std::is_same<ConstructibleArrayType,
3803 typename BasicJsonType::value_type>::value&&
3804 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3805 is_default_constructible<ConstructibleArrayType>::value&&
3806(std::is_move_assignable<ConstructibleArrayType>::value ||
3807 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3808is_detected<iterator_t, ConstructibleArrayType>::value&&
3809is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3810is_detected<range_value_t, ConstructibleArrayType>::value&&
3811// special case for types like std::filesystem::path whose iterator's value_type are themselves
3812// c.f. https://github.com/nlohmann/json/pull/3073
3813!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3815 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3816{
3818
3819 static constexpr bool value =
3820 std::is_same<value_type,
3821 typename BasicJsonType::array_t::value_type>::value ||
3822 has_from_json<BasicJsonType,
3825 BasicJsonType,
3827};
3828
3829template<typename BasicJsonType, typename ConstructibleArrayType>
3831 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3832
3833template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3834 typename = void>
3835struct is_compatible_integer_type_impl : std::false_type {};
3836
3837template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3839 RealIntegerType, CompatibleNumberIntegerType,
3840 enable_if_t < std::is_integral<RealIntegerType>::value&&
3841 std::is_integral<CompatibleNumberIntegerType>::value&&
3842 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3843{
3844 // is there an assert somewhere on overflows?
3845 using RealLimits = std::numeric_limits<RealIntegerType>;
3846 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3847
3848 static constexpr auto value =
3849 is_constructible<RealIntegerType,
3850 CompatibleNumberIntegerType>::value &&
3851 CompatibleLimits::is_integer &&
3852 RealLimits::is_signed == CompatibleLimits::is_signed;
3853};
3854
3855template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3857 : is_compatible_integer_type_impl<RealIntegerType,
3858 CompatibleNumberIntegerType> {};
3859
3860template<typename BasicJsonType, typename CompatibleType, typename = void>
3861struct is_compatible_type_impl: std::false_type {};
3862
3863template<typename BasicJsonType, typename CompatibleType>
3865 BasicJsonType, CompatibleType,
3866 enable_if_t<is_complete_type<CompatibleType>::value >>
3867{
3868 static constexpr bool value =
3870};
3871
3872template<typename BasicJsonType, typename CompatibleType>
3874 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3875
3876template<typename T1, typename T2>
3877struct is_constructible_tuple : std::false_type {};
3878
3879template<typename T1, typename... Args>
3880struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3881
3882template<typename BasicJsonType, typename T>
3883struct is_json_iterator_of : std::false_type {};
3884
3885template<typename BasicJsonType>
3886struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3887
3888template<typename BasicJsonType>
3889struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3890{};
3891
3892// checks if a given type T is a template specialization of Primary
3893template<template <typename...> class Primary, typename T>
3894struct is_specialization_of : std::false_type {};
3895
3896template<template <typename...> class Primary, typename... Args>
3897struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3898
3899template<typename T>
3901
3902// checks if A and B are comparable using Compare functor
3903template<typename Compare, typename A, typename B, typename = void>
3904struct is_comparable : std::false_type {};
3905
3906template<typename Compare, typename A, typename B>
3907struct is_comparable<Compare, A, B, void_t<
3908decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3909decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3910>> : std::true_type {};
3911
3912template<typename T>
3913using detect_is_transparent = typename T::is_transparent;
3914
3915// type trait to check if KeyType can be used as object key (without a BasicJsonType)
3916// see is_usable_as_basic_json_key_type below
3917template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3918 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3919using is_usable_as_key_type = typename std::conditional <
3921 && !(ExcludeObjectKeyType && std::is_same<KeyType,
3922 ObjectKeyType>::value)
3923 && (!RequireTransparentComparator
3924 || is_detected <detect_is_transparent, Comparator>::value)
3926 std::true_type,
3927 std::false_type >::type;
3928
3929// type trait to check if KeyType can be used as object key
3930// true if:
3931// - KeyType is comparable with BasicJsonType::object_t::key_type
3932// - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3933// - the comparator is transparent or RequireTransparentComparator is false
3934// - KeyType is not a JSON iterator or json_pointer
3935template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3936 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3937using is_usable_as_basic_json_key_type = typename std::conditional <
3938 is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
3939 typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
3940 RequireTransparentComparator, ExcludeObjectKeyType>::value
3942 std::true_type,
3943 std::false_type >::type;
3944
3945template<typename ObjectType, typename KeyType>
3946using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3947
3948// type trait to check if object_t has an erase() member functions accepting KeyType
3949template<typename BasicJsonType, typename KeyType>
3950using has_erase_with_key_type = typename std::conditional <
3951 is_detected <
3953 typename BasicJsonType::object_t, KeyType >::value,
3954 std::true_type,
3955 std::false_type >::type;
3956
3957// a naive helper to check if a type is an ordered_map (exploits the fact that
3958// ordered_map inherits capacity() from std::vector)
3959template <typename T>
3961{
3962 using one = char;
3963
3964 struct two
3965 {
3966 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3967 };
3968
3969 template <typename C> static one test( decltype(&C::capacity) ) ;
3970 template <typename C> static two test(...);
3971
3972 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3973};
3974
3975// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3976template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3978{
3979 return static_cast<T>(value);
3980}
3981
3982template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3984{
3985 return value;
3986}
3987
3988template<typename... Types>
3990
3991template<typename... Types>
3993
3994template<typename... Types>
3996
3997// there's a disjunction trait in another PR; replace when merged
3998template<typename... Types>
3999using same_sign = std::integral_constant < bool,
4000 all_signed<Types...>::value || all_unsigned<Types...>::value >;
4001
4002template<typename OfType, typename T>
4003using never_out_of_range = std::integral_constant < bool,
4004 (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4005 || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4006
4007template<typename OfType, typename T,
4008 bool OfTypeSigned = std::is_signed<OfType>::value,
4009 bool TSigned = std::is_signed<T>::value>
4011
4012template<typename OfType, typename T>
4013struct value_in_range_of_impl2<OfType, T, false, false>
4014{
4015 static constexpr bool test(T val)
4016 {
4017 using CommonType = typename std::common_type<OfType, T>::type;
4018 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4019 }
4020};
4021
4022template<typename OfType, typename T>
4023struct value_in_range_of_impl2<OfType, T, true, false>
4024{
4025 static constexpr bool test(T val)
4026 {
4027 using CommonType = typename std::common_type<OfType, T>::type;
4028 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4029 }
4030};
4031
4032template<typename OfType, typename T>
4033struct value_in_range_of_impl2<OfType, T, false, true>
4034{
4035 static constexpr bool test(T val)
4036 {
4037 using CommonType = typename std::common_type<OfType, T>::type;
4038 return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4039 }
4040};
4041
4042
4043template<typename OfType, typename T>
4044struct value_in_range_of_impl2<OfType, T, true, true>
4045{
4046 static constexpr bool test(T val)
4047 {
4048 using CommonType = typename std::common_type<OfType, T>::type;
4049 return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4050 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4051 }
4052};
4053
4054template<typename OfType, typename T,
4055 bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4058
4059template<typename OfType, typename T>
4060struct value_in_range_of_impl1<OfType, T, false>
4061{
4062 static constexpr bool test(T val)
4063 {
4065 }
4066};
4067
4068template<typename OfType, typename T>
4069struct value_in_range_of_impl1<OfType, T, true>
4070{
4071 static constexpr bool test(T /*val*/)
4072 {
4073 return true;
4074 }
4075};
4076
4077template<typename OfType, typename T>
4078inline constexpr bool value_in_range_of(T val)
4079{
4081}
4082
4083template<bool Value>
4084using bool_constant = std::integral_constant<bool, Value>;
4085
4087// is_c_string
4089
4090namespace impl
4091{
4092
4093template<typename T>
4094inline constexpr bool is_c_string()
4095{
4096 using TUnExt = typename std::remove_extent<T>::type;
4097 using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4098 using TUnPtr = typename std::remove_pointer<T>::type;
4099 using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4100 return
4101 (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
4102 || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
4103}
4104
4105} // namespace impl
4106
4107// checks whether T is a [cv] char */[cv] char[] C string
4108template<typename T>
4109struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4110
4111template<typename T>
4113
4115// is_transparent
4117
4118namespace impl
4119{
4120
4121template<typename T>
4122inline constexpr bool is_transparent()
4123{
4125}
4126
4127} // namespace impl
4128
4129// checks whether T has a member named is_transparent
4130template<typename T>
4131struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4132
4134
4135} // namespace detail
4137
4138// #include <nlohmann/detail/string_concat.hpp>
4139// __ _____ _____ _____
4140// __| | __| | | | JSON for Modern C++
4141// | | |__ | | | | | | version 3.11.2
4142// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4143//
4144// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4145// SPDX-License-Identifier: MIT
4146
4147
4148
4149#include <cstring> // strlen
4150#include <string> // string
4151#include <utility> // forward
4152
4153// #include <nlohmann/detail/meta/cpp_future.hpp>
4154
4155// #include <nlohmann/detail/meta/detected.hpp>
4156
4157
4159namespace detail
4160{
4161
4162inline std::size_t concat_length()
4163{
4164 return 0;
4165}
4166
4167template<typename... Args>
4168inline std::size_t concat_length(const char* cstr, Args&& ... rest);
4169
4170template<typename StringType, typename... Args>
4171inline std::size_t concat_length(const StringType& str, Args&& ... rest);
4172
4173template<typename... Args>
4174inline std::size_t concat_length(const char /*c*/, Args&& ... rest)
4175{
4176 return 1 + concat_length(std::forward<Args>(rest)...);
4177}
4178
4179template<typename... Args>
4180inline std::size_t concat_length(const char* cstr, Args&& ... rest)
4181{
4182 // cppcheck-suppress ignoredReturnValue
4183 return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...);
4184}
4185
4186template<typename StringType, typename... Args>
4187inline std::size_t concat_length(const StringType& str, Args&& ... rest)
4188{
4189 return str.size() + concat_length(std::forward<Args>(rest)...);
4190}
4191
4192template<typename OutStringType>
4193inline void concat_into(OutStringType& /*out*/)
4194{}
4195
4196template<typename StringType, typename Arg>
4197using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
4198
4199template<typename StringType, typename Arg>
4201
4202template<typename StringType, typename Arg>
4203using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
4204
4205template<typename StringType, typename Arg>
4207
4208template<typename StringType, typename Arg>
4209using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4210
4211template<typename StringType, typename Arg>
4213
4214template<typename StringType, typename Arg>
4215using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4216
4217template<typename StringType, typename Arg>
4219
4220template < typename OutStringType, typename Arg, typename... Args,
4221 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4223inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
4224
4225template < typename OutStringType, typename Arg, typename... Args,
4226 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4229inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4230
4231template < typename OutStringType, typename Arg, typename... Args,
4232 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4236inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4237
4238template<typename OutStringType, typename Arg, typename... Args,
4240inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
4241{
4242 out.append(std::forward<Arg>(arg));
4243 concat_into(out, std::forward<Args>(rest)...);
4244}
4245
4246template < typename OutStringType, typename Arg, typename... Args,
4247 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4248 && detect_string_can_append_op<OutStringType, Arg>::value, int > >
4249inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4250{
4251 out += std::forward<Arg>(arg);
4252 concat_into(out, std::forward<Args>(rest)...);
4253}
4254
4255template < typename OutStringType, typename Arg, typename... Args,
4256 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4257 && !detect_string_can_append_op<OutStringType, Arg>::value
4258 && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
4259inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4260{
4261 out.append(arg.begin(), arg.end());
4262 concat_into(out, std::forward<Args>(rest)...);
4263}
4264
4265template < typename OutStringType, typename Arg, typename... Args,
4266 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4267 && !detect_string_can_append_op<OutStringType, Arg>::value
4268 && !detect_string_can_append_iter<OutStringType, Arg>::value
4269 && detect_string_can_append_data<OutStringType, Arg>::value, int > >
4270inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4271{
4272 out.append(arg.data(), arg.size());
4273 concat_into(out, std::forward<Args>(rest)...);
4274}
4275
4276template<typename OutStringType = std::string, typename... Args>
4277inline OutStringType concat(Args && ... args)
4278{
4279 OutStringType str;
4280 str.reserve(concat_length(std::forward<Args>(args)...));
4281 concat_into(str, std::forward<Args>(args)...);
4282 return str;
4283}
4284
4285} // namespace detail
4287
4288
4289
4291namespace detail
4292{
4293
4295// exceptions //
4297
4300class exception : public std::exception
4301{
4302 public:
4304 const char* what() const noexcept override
4305 {
4306 return m.what();
4307 }
4308
4310 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4311
4312 protected:
4314 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4315
4316 static std::string name(const std::string& ename, int id_)
4317 {
4318 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4319 }
4320
4321 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4322 {
4323 return "";
4324 }
4325
4326 template<typename BasicJsonType>
4327 static std::string diagnostics(const BasicJsonType* leaf_element)
4328 {
4329#if JSON_DIAGNOSTICS
4330 std::vector<std::string> tokens;
4331 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4332 {
4333 switch (current->m_parent->type())
4334 {
4335 case value_t::array:
4336 {
4337 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
4338 {
4339 if (&current->m_parent->m_value.array->operator[](i) == current)
4340 {
4341 tokens.emplace_back(std::to_string(i));
4342 break;
4343 }
4344 }
4345 break;
4346 }
4347
4348 case value_t::object:
4349 {
4350 for (const auto& element : *current->m_parent->m_value.object)
4351 {
4352 if (&element.second == current)
4353 {
4354 tokens.emplace_back(element.first.c_str());
4355 break;
4356 }
4357 }
4358 break;
4359 }
4360
4361 case value_t::null: // LCOV_EXCL_LINE
4362 case value_t::string: // LCOV_EXCL_LINE
4363 case value_t::boolean: // LCOV_EXCL_LINE
4364 case value_t::number_integer: // LCOV_EXCL_LINE
4365 case value_t::number_unsigned: // LCOV_EXCL_LINE
4366 case value_t::number_float: // LCOV_EXCL_LINE
4367 case value_t::binary: // LCOV_EXCL_LINE
4368 case value_t::discarded: // LCOV_EXCL_LINE
4369 default: // LCOV_EXCL_LINE
4370 break; // LCOV_EXCL_LINE
4371 }
4372 }
4373
4374 if (tokens.empty())
4375 {
4376 return "";
4377 }
4378
4379 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4380 [](const std::string & a, const std::string & b)
4381 {
4382 return concat(a, '/', detail::escape(b));
4383 });
4384 return concat('(', str, ") ");
4385#else
4386 static_cast<void>(leaf_element);
4387 return "";
4388#endif
4389 }
4390
4391 private:
4393 std::runtime_error m;
4394};
4395
4399{
4400 public:
4410 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4411 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4412 {
4413 std::string w = concat(exception::name("parse_error", id_), "parse error",
4414 position_string(pos), ": ", exception::diagnostics(context), what_arg);
4415 return {id_, pos.chars_read_total, w.c_str()};
4416 }
4417
4418 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4419 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4420 {
4421 std::string w = concat(exception::name("parse_error", id_), "parse error",
4422 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4423 ": ", exception::diagnostics(context), what_arg);
4424 return {id_, byte_, w.c_str()};
4425 }
4426
4436 const std::size_t byte;
4437
4438 private:
4439 parse_error(int id_, std::size_t byte_, const char* what_arg)
4440 : exception(id_, what_arg), byte(byte_) {}
4441
4442 static std::string position_string(const position_t& pos)
4443 {
4444 return concat(" at line ", std::to_string(pos.lines_read + 1),
4445 ", column ", std::to_string(pos.chars_read_current_line));
4446 }
4447};
4448
4452{
4453 public:
4454 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4455 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4456 {
4457 std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4458 return {id_, w.c_str()};
4459 }
4460
4461 private:
4463 invalid_iterator(int id_, const char* what_arg)
4464 : exception(id_, what_arg) {}
4465};
4466
4469class type_error : public exception
4470{
4471 public:
4472 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4473 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4474 {
4475 std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4476 return {id_, w.c_str()};
4477 }
4478
4479 private:
4481 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4482};
4483
4487{
4488 public:
4489 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4490 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4491 {
4492 std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4493 return {id_, w.c_str()};
4494 }
4495
4496 private:
4498 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4499};
4500
4504{
4505 public:
4506 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4507 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4508 {
4509 std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4510 return {id_, w.c_str()};
4511 }
4512
4513 private:
4515 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4516};
4517
4518} // namespace detail
4520
4521// #include <nlohmann/detail/macro_scope.hpp>
4522
4523// #include <nlohmann/detail/meta/cpp_future.hpp>
4524
4525// #include <nlohmann/detail/meta/identity_tag.hpp>
4526// __ _____ _____ _____
4527// __| | __| | | | JSON for Modern C++
4528// | | |__ | | | | | | version 3.11.2
4529// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4530//
4531// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4532// SPDX-License-Identifier: MIT
4533
4534
4535
4536// #include <nlohmann/detail/abi_macros.hpp>
4537
4538
4540namespace detail
4541{
4542
4543// dispatching helper struct
4544template <class T> struct identity_tag {};
4545
4546} // namespace detail
4548
4549// #include <nlohmann/detail/meta/std_fs.hpp>
4550// __ _____ _____ _____
4551// __| | __| | | | JSON for Modern C++
4552// | | |__ | | | | | | version 3.11.2
4553// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4554//
4555// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
4556// SPDX-License-Identifier: MIT
4557
4558
4559
4560// #include <nlohmann/detail/macro_scope.hpp>
4561
4562
4563#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4564#include <experimental/filesystem>
4566namespace detail
4567{
4568namespace std_fs = std::experimental::filesystem;
4569} // namespace detail
4571#elif JSON_HAS_FILESYSTEM
4572#include <filesystem>
4574namespace detail
4575{
4576namespace std_fs = std::filesystem;
4577} // namespace detail
4579#endif
4580
4581// #include <nlohmann/detail/meta/type_traits.hpp>
4582
4583// #include <nlohmann/detail/string_concat.hpp>
4584
4585// #include <nlohmann/detail/value_t.hpp>
4586
4587
4589namespace detail
4590{
4591
4592template<typename BasicJsonType>
4593inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4594{
4595 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4596 {
4597 JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4598 }
4599 n = nullptr;
4600}
4601
4602// overloads for basic_json template parameters
4603template < typename BasicJsonType, typename ArithmeticType,
4604 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
4605 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4606 int > = 0 >
4607void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4608{
4609 switch (static_cast<value_t>(j))
4610 {
4612 {
4613 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4614 break;
4615 }
4617 {
4618 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4619 break;
4620 }
4622 {
4623 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4624 break;
4625 }
4626
4627 case value_t::null:
4628 case value_t::object:
4629 case value_t::array:
4630 case value_t::string:
4631 case value_t::boolean:
4632 case value_t::binary:
4633 case value_t::discarded:
4634 default:
4635 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4636 }
4637}
4638
4639template<typename BasicJsonType>
4640inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4641{
4642 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4643 {
4644 JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4645 }
4646 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4647}
4648
4649template<typename BasicJsonType>
4650inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4651{
4652 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4653 {
4654 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4655 }
4656 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4657}
4658
4659template <
4660 typename BasicJsonType, typename StringType,
4661 enable_if_t <
4662 std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4663 && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
4664 && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4665 && !is_json_ref<StringType>::value, int > = 0 >
4666inline void from_json(const BasicJsonType& j, StringType& s)
4667{
4668 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4669 {
4670 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4671 }
4672
4673 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4674}
4675
4676template<typename BasicJsonType>
4677inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4678{
4679 get_arithmetic_value(j, val);
4680}
4681
4682template<typename BasicJsonType>
4683inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4684{
4685 get_arithmetic_value(j, val);
4686}
4687
4688template<typename BasicJsonType>
4689inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4690{
4691 get_arithmetic_value(j, val);
4692}
4693
4694#if !JSON_DISABLE_ENUM_SERIALIZATION
4695template<typename BasicJsonType, typename EnumType,
4696 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4697inline void from_json(const BasicJsonType& j, EnumType& e)
4698{
4699 typename std::underlying_type<EnumType>::type val;
4700 get_arithmetic_value(j, val);
4701 e = static_cast<EnumType>(val);
4702}
4703#endif // JSON_DISABLE_ENUM_SERIALIZATION
4704
4705// forward_list doesn't have an insert method
4706template<typename BasicJsonType, typename T, typename Allocator,
4707 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4708inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4709{
4710 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4711 {
4712 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4713 }
4714 l.clear();
4715 std::transform(j.rbegin(), j.rend(),
4716 std::front_inserter(l), [](const BasicJsonType & i)
4717 {
4718 return i.template get<T>();
4719 });
4720}
4721
4722// valarray doesn't have an insert method
4723template<typename BasicJsonType, typename T,
4724 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4725inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4726{
4727 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4728 {
4729 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4730 }
4731 l.resize(j.size());
4732 std::transform(j.begin(), j.end(), std::begin(l),
4733 [](const BasicJsonType & elem)
4734 {
4735 return elem.template get<T>();
4736 });
4737}
4738
4739template<typename BasicJsonType, typename T, std::size_t N>
4740auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4741-> decltype(j.template get<T>(), void())
4742{
4743 for (std::size_t i = 0; i < N; ++i)
4744 {
4745 arr[i] = j.at(i).template get<T>();
4746 }
4747}
4748
4749template<typename BasicJsonType>
4750inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4751{
4752 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4753}
4754
4755template<typename BasicJsonType, typename T, std::size_t N>
4756auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4757 priority_tag<2> /*unused*/)
4758-> decltype(j.template get<T>(), void())
4759{
4760 for (std::size_t i = 0; i < N; ++i)
4761 {
4762 arr[i] = j.at(i).template get<T>();
4763 }
4764}
4765
4766template<typename BasicJsonType, typename ConstructibleArrayType,
4768 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4769 int> = 0>
4770auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4771-> decltype(
4772 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4773 j.template get<typename ConstructibleArrayType::value_type>(),
4774 void())
4775{
4776 using std::end;
4777
4778 ConstructibleArrayType ret;
4779 ret.reserve(j.size());
4780 std::transform(j.begin(), j.end(),
4781 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4782 {
4783 // get<BasicJsonType>() returns *this, this won't call a from_json
4784 // method when value_type is BasicJsonType
4785 return i.template get<typename ConstructibleArrayType::value_type>();
4786 });
4787 arr = std::move(ret);
4788}
4789
4790template<typename BasicJsonType, typename ConstructibleArrayType,
4792 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4793 int> = 0>
4794inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4795 priority_tag<0> /*unused*/)
4796{
4797 using std::end;
4798
4799 ConstructibleArrayType ret;
4800 std::transform(
4801 j.begin(), j.end(), std::inserter(ret, end(ret)),
4802 [](const BasicJsonType & i)
4803 {
4804 // get<BasicJsonType>() returns *this, this won't call a from_json
4805 // method when value_type is BasicJsonType
4806 return i.template get<typename ConstructibleArrayType::value_type>();
4807 });
4808 arr = std::move(ret);
4809}
4810
4811template < typename BasicJsonType, typename ConstructibleArrayType,
4812 enable_if_t <
4813 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4814 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4816 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4817 !is_basic_json<ConstructibleArrayType>::value,
4818 int > = 0 >
4819auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4820-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4821j.template get<typename ConstructibleArrayType::value_type>(),
4822void())
4823{
4824 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4825 {
4826 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4827 }
4828
4829 from_json_array_impl(j, arr, priority_tag<3> {});
4830}
4831
4832template < typename BasicJsonType, typename T, std::size_t... Idx >
4833std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4834 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4835{
4836 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4837}
4838
4839template < typename BasicJsonType, typename T, std::size_t N >
4840auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4841-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4842{
4843 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4844 {
4845 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4846 }
4847
4848 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4849}
4850
4851template<typename BasicJsonType>
4852inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4853{
4854 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4855 {
4856 JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4857 }
4858
4859 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4860}
4861
4862template<typename BasicJsonType, typename ConstructibleObjectType,
4863 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4864inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4865{
4866 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4867 {
4868 JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4869 }
4870
4871 ConstructibleObjectType ret;
4872 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4873 using value_type = typename ConstructibleObjectType::value_type;
4874 std::transform(
4875 inner_object->begin(), inner_object->end(),
4876 std::inserter(ret, ret.begin()),
4877 [](typename BasicJsonType::object_t::value_type const & p)
4878 {
4879 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4880 });
4881 obj = std::move(ret);
4882}
4883
4884// overload for arithmetic types, not chosen for basic_json template arguments
4885// (BooleanType, etc..); note: Is it really necessary to provide explicit
4886// overloads for boolean_t etc. in case of a custom BooleanType which is not
4887// an arithmetic type?
4888template < typename BasicJsonType, typename ArithmeticType,
4889 enable_if_t <
4890 std::is_arithmetic<ArithmeticType>::value&&
4891 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4892 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4893 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4894 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4895 int > = 0 >
4896inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4897{
4898 switch (static_cast<value_t>(j))
4899 {
4901 {
4902 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4903 break;
4904 }
4906 {
4907 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4908 break;
4909 }
4911 {
4912 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4913 break;
4914 }
4915 case value_t::boolean:
4916 {
4917 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4918 break;
4919 }
4920
4921 case value_t::null:
4922 case value_t::object:
4923 case value_t::array:
4924 case value_t::string:
4925 case value_t::binary:
4926 case value_t::discarded:
4927 default:
4928 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4929 }
4930}
4931
4932template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4933std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4934{
4935 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4936}
4937
4938template < typename BasicJsonType, class A1, class A2 >
4939std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4940{
4941 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4942 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4943}
4944
4945template<typename BasicJsonType, typename A1, typename A2>
4946inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4947{
4948 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4949}
4950
4951template<typename BasicJsonType, typename... Args>
4952std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4953{
4954 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4955}
4956
4957template<typename BasicJsonType, typename... Args>
4958inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4959{
4960 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4961}
4962
4963template<typename BasicJsonType, typename TupleRelated>
4964auto from_json(BasicJsonType&& j, TupleRelated&& t)
4965-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4966{
4967 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4968 {
4969 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4970 }
4971
4972 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4973}
4974
4975template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4976 typename = enable_if_t < !std::is_constructible <
4977 typename BasicJsonType::string_t, Key >::value >>
4978inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4979{
4980 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4981 {
4982 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4983 }
4984 m.clear();
4985 for (const auto& p : j)
4986 {
4987 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4988 {
4989 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4990 }
4991 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4992 }
4993}
4994
4995template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4996 typename = enable_if_t < !std::is_constructible <
4997 typename BasicJsonType::string_t, Key >::value >>
4998inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4999{
5000 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5001 {
5002 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5003 }
5004 m.clear();
5005 for (const auto& p : j)
5006 {
5007 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5008 {
5009 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5010 }
5011 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5012 }
5013}
5014
5015#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5016template<typename BasicJsonType>
5017inline void from_json(const BasicJsonType& j, std_fs::path& p)
5018{
5019 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5020 {
5021 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5022 }
5023 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5024}
5025#endif
5026
5028{
5029 template<typename BasicJsonType, typename T>
5030 auto operator()(const BasicJsonType& j, T&& val) const
5031 noexcept(noexcept(from_json(j, std::forward<T>(val))))
5032 -> decltype(from_json(j, std::forward<T>(val)))
5033 {
5034 return from_json(j, std::forward<T>(val));
5035 }
5036};
5037
5038} // namespace detail
5039
5040#ifndef JSON_HAS_CPP_17
5044namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5045{
5046#endif
5047JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5049#ifndef JSON_HAS_CPP_17
5050} // namespace
5051#endif
5052
5054
5055// #include <nlohmann/detail/conversions/to_json.hpp>
5056// __ _____ _____ _____
5057// __| | __| | | | JSON for Modern C++
5058// | | |__ | | | | | | version 3.11.2
5059// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5060//
5061// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5062// SPDX-License-Identifier: MIT
5063
5064
5065
5066#include <algorithm> // copy
5067#include <iterator> // begin, end
5068#include <string> // string
5069#include <tuple> // tuple, get
5070#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5071#include <utility> // move, forward, declval, pair
5072#include <valarray> // valarray
5073#include <vector> // vector
5074
5075// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5076// __ _____ _____ _____
5077// __| | __| | | | JSON for Modern C++
5078// | | |__ | | | | | | version 3.11.2
5079// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5080//
5081// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5082// SPDX-License-Identifier: MIT
5083
5084
5085
5086#include <cstddef> // size_t
5087#include <iterator> // input_iterator_tag
5088#include <string> // string, to_string
5089#include <tuple> // tuple_size, get, tuple_element
5090#include <utility> // move
5091
5092#if JSON_HAS_RANGES
5093 #include <ranges> // enable_borrowed_range
5094#endif
5095
5096// #include <nlohmann/detail/abi_macros.hpp>
5097
5098// #include <nlohmann/detail/meta/type_traits.hpp>
5099
5100// #include <nlohmann/detail/value_t.hpp>
5101
5102
5104namespace detail
5105{
5106
5107template<typename string_type>
5108void int_to_string( string_type& target, std::size_t value )
5109{
5110 // For ADL
5111 using std::to_string;
5112 target = to_string(value);
5113}
5114template<typename IteratorType> class iteration_proxy_value
5115{
5116 public:
5117 using difference_type = std::ptrdiff_t;
5121 using iterator_category = std::input_iterator_tag;
5122 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
5123
5124 private:
5126 IteratorType anchor{};
5128 std::size_t array_index = 0;
5130 mutable std::size_t array_index_last = 0;
5132 mutable string_type array_index_str = "0";
5134 string_type empty_str{};
5135
5136 public:
5137 explicit iteration_proxy_value() = default;
5138 explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5139 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5140 && std::is_nothrow_default_constructible<string_type>::value)
5141 : anchor(std::move(it))
5142 , array_index(array_index_)
5143 {}
5144
5147 // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5149 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5150 && std::is_nothrow_move_constructible<string_type>::value) = default;
5152 noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5153 && std::is_nothrow_move_assignable<string_type>::value) = default;
5155
5157 const iteration_proxy_value& operator*() const
5158 {
5159 return *this;
5160 }
5161
5164 {
5165 ++anchor;
5166 ++array_index;
5167
5168 return *this;
5169 }
5170
5171 iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5172 {
5173 auto tmp = iteration_proxy_value(anchor, array_index);
5174 ++anchor;
5175 ++array_index;
5176 return tmp;
5177 }
5178
5181 {
5182 return anchor == o.anchor;
5183 }
5184
5187 {
5188 return anchor != o.anchor;
5189 }
5190
5192 const string_type& key() const
5193 {
5194 JSON_ASSERT(anchor.m_object != nullptr);
5195
5196 switch (anchor.m_object->type())
5197 {
5198 // use integer array index as key
5199 case value_t::array:
5200 {
5201 if (array_index != array_index_last)
5202 {
5203 int_to_string( array_index_str, array_index );
5204 array_index_last = array_index;
5205 }
5206 return array_index_str;
5207 }
5208
5209 // use key from the object
5210 case value_t::object:
5211 return anchor.key();
5212
5213 // use an empty key for all primitive types
5214 case value_t::null:
5215 case value_t::string:
5216 case value_t::boolean:
5220 case value_t::binary:
5221 case value_t::discarded:
5222 default:
5223 return empty_str;
5224 }
5225 }
5226
5228 typename IteratorType::reference value() const
5229 {
5230 return anchor.value();
5231 }
5232};
5233
5235template<typename IteratorType> class iteration_proxy
5236{
5237 private:
5239 typename IteratorType::pointer container = nullptr;
5240
5241 public:
5242 explicit iteration_proxy() = default;
5243
5245 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5246 : container(&cont) {}
5247
5250 iteration_proxy(iteration_proxy&&) noexcept = default;
5251 iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5252 ~iteration_proxy() = default;
5253
5255 iteration_proxy_value<IteratorType> begin() const noexcept
5256 {
5257 return iteration_proxy_value<IteratorType>(container->begin());
5258 }
5259
5262 {
5263 return iteration_proxy_value<IteratorType>(container->end());
5264 }
5265};
5266
5267// Structured Bindings Support
5268// For further reference see https://blog.tartanllama.xyz/structured-bindings/
5269// And see https://github.com/nlohmann/json/pull/1391
5270template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5271auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5272{
5273 return i.key();
5274}
5275// Structured Bindings Support
5276// For further reference see https://blog.tartanllama.xyz/structured-bindings/
5277// And see https://github.com/nlohmann/json/pull/1391
5278template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5279auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5280{
5281 return i.value();
5282}
5283
5284} // namespace detail
5286
5287// The Addition to the STD Namespace is required to add
5288// Structured Bindings Support to the iteration_proxy_value class
5289// For further reference see https://blog.tartanllama.xyz/structured-bindings/
5290// And see https://github.com/nlohmann/json/pull/1391
5291namespace std
5292{
5293
5294#if defined(__clang__)
5295 // Fix: https://github.com/nlohmann/json/issues/1401
5296 #pragma clang diagnostic push
5297 #pragma clang diagnostic ignored "-Wmismatched-tags"
5298#endif
5299template<typename IteratorType>
5300class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
5301 : public std::integral_constant<std::size_t, 2> {};
5302
5303template<std::size_t N, typename IteratorType>
5304class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
5305{
5306 public:
5307 using type = decltype(
5308 get<N>(std::declval <
5309 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5310};
5311#if defined(__clang__)
5312 #pragma clang diagnostic pop
5313#endif
5314
5315} // namespace std
5316
5317#if JSON_HAS_RANGES
5318 template <typename IteratorType>
5319 inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5320#endif
5321
5322// #include <nlohmann/detail/macro_scope.hpp>
5323
5324// #include <nlohmann/detail/meta/cpp_future.hpp>
5325
5326// #include <nlohmann/detail/meta/std_fs.hpp>
5327
5328// #include <nlohmann/detail/meta/type_traits.hpp>
5329
5330// #include <nlohmann/detail/value_t.hpp>
5331
5332
5334namespace detail
5335{
5336
5338// constructors //
5340
5341/*
5342 * Note all external_constructor<>::construct functions need to call
5343 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
5344 * allocated value (e.g., a string). See bug issue
5345 * https://github.com/nlohmann/json/issues/2865 for more information.
5346 */
5347
5348template<value_t> struct external_constructor;
5349
5350template<>
5352{
5353 template<typename BasicJsonType>
5354 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5355 {
5356 j.m_value.destroy(j.m_type);
5357 j.m_type = value_t::boolean;
5358 j.m_value = b;
5359 j.assert_invariant();
5360 }
5361};
5362
5363template<>
5365{
5366 template<typename BasicJsonType>
5367 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5368 {
5369 j.m_value.destroy(j.m_type);
5370 j.m_type = value_t::string;
5371 j.m_value = s;
5372 j.assert_invariant();
5373 }
5374
5375 template<typename BasicJsonType>
5376 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5377 {
5378 j.m_value.destroy(j.m_type);
5379 j.m_type = value_t::string;
5380 j.m_value = std::move(s);
5381 j.assert_invariant();
5382 }
5383
5384 template < typename BasicJsonType, typename CompatibleStringType,
5385 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
5386 int > = 0 >
5387 static void construct(BasicJsonType& j, const CompatibleStringType& str)
5388 {
5389 j.m_value.destroy(j.m_type);
5390 j.m_type = value_t::string;
5391 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5392 j.assert_invariant();
5393 }
5394};
5395
5396template<>
5398{
5399 template<typename BasicJsonType>
5400 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5401 {
5402 j.m_value.destroy(j.m_type);
5403 j.m_type = value_t::binary;
5404 j.m_value = typename BasicJsonType::binary_t(b);
5405 j.assert_invariant();
5406 }
5407
5408 template<typename BasicJsonType>
5409 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5410 {
5411 j.m_value.destroy(j.m_type);
5412 j.m_type = value_t::binary;
5413 j.m_value = typename BasicJsonType::binary_t(std::move(b));
5414 j.assert_invariant();
5415 }
5416};
5417
5418template<>
5420{
5421 template<typename BasicJsonType>
5422 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5423 {
5424 j.m_value.destroy(j.m_type);
5425 j.m_type = value_t::number_float;
5426 j.m_value = val;
5427 j.assert_invariant();
5428 }
5429};
5430
5431template<>
5433{
5434 template<typename BasicJsonType>
5435 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5436 {
5437 j.m_value.destroy(j.m_type);
5438 j.m_type = value_t::number_unsigned;
5439 j.m_value = val;
5440 j.assert_invariant();
5441 }
5442};
5443
5444template<>
5446{
5447 template<typename BasicJsonType>
5448 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5449 {
5450 j.m_value.destroy(j.m_type);
5451 j.m_type = value_t::number_integer;
5452 j.m_value = val;
5453 j.assert_invariant();
5454 }
5455};
5456
5457template<>
5459{
5460 template<typename BasicJsonType>
5461 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5462 {
5463 j.m_value.destroy(j.m_type);
5464 j.m_type = value_t::array;
5465 j.m_value = arr;
5466 j.set_parents();
5467 j.assert_invariant();
5468 }
5469
5470 template<typename BasicJsonType>
5471 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5472 {
5473 j.m_value.destroy(j.m_type);
5474 j.m_type = value_t::array;
5475 j.m_value = std::move(arr);
5476 j.set_parents();
5477 j.assert_invariant();
5478 }
5479
5480 template < typename BasicJsonType, typename CompatibleArrayType,
5481 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
5482 int > = 0 >
5483 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5484 {
5485 using std::begin;
5486 using std::end;
5487
5488 j.m_value.destroy(j.m_type);
5489 j.m_type = value_t::array;
5490 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5491 j.set_parents();
5492 j.assert_invariant();
5493 }
5494
5495 template<typename BasicJsonType>
5496 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5497 {
5498 j.m_value.destroy(j.m_type);
5499 j.m_type = value_t::array;
5500 j.m_value = value_t::array;
5501 j.m_value.array->reserve(arr.size());
5502 for (const bool x : arr)
5503 {
5504 j.m_value.array->push_back(x);
5505 j.set_parent(j.m_value.array->back());
5506 }
5507 j.assert_invariant();
5508 }
5509
5510 template<typename BasicJsonType, typename T,
5512 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5513 {
5514 j.m_value.destroy(j.m_type);
5515 j.m_type = value_t::array;
5516 j.m_value = value_t::array;
5517 j.m_value.array->resize(arr.size());
5518 if (arr.size() > 0)
5519 {
5520 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
5521 }
5522 j.set_parents();
5523 j.assert_invariant();
5524 }
5525};
5526
5527template<>
5529{
5530 template<typename BasicJsonType>
5531 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5532 {
5533 j.m_value.destroy(j.m_type);
5534 j.m_type = value_t::object;
5535 j.m_value = obj;
5536 j.set_parents();
5537 j.assert_invariant();
5538 }
5539
5540 template<typename BasicJsonType>
5541 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5542 {
5543 j.m_value.destroy(j.m_type);
5544 j.m_type = value_t::object;
5545 j.m_value = std::move(obj);
5546 j.set_parents();
5547 j.assert_invariant();
5548 }
5549
5550 template < typename BasicJsonType, typename CompatibleObjectType,
5551 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
5552 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5553 {
5554 using std::begin;
5555 using std::end;
5556
5557 j.m_value.destroy(j.m_type);
5558 j.m_type = value_t::object;
5559 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5560 j.set_parents();
5561 j.assert_invariant();
5562 }
5563};
5564
5566// to_json //
5568
5569template<typename BasicJsonType, typename T,
5570 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5571inline void to_json(BasicJsonType& j, T b) noexcept
5572{
5574}
5575
5576template < typename BasicJsonType, typename BoolRef,
5577 enable_if_t <
5578 ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5579 && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5580 || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5581 && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5582 typename BasicJsonType::boolean_t >::value))
5583 && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
5584inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5585{
5586 external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5587}
5588
5589template<typename BasicJsonType, typename CompatibleString,
5590 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5591inline void to_json(BasicJsonType& j, const CompatibleString& s)
5592{
5594}
5595
5596template<typename BasicJsonType>
5597inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5598{
5600}
5601
5602template<typename BasicJsonType, typename FloatType,
5603 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5604inline void to_json(BasicJsonType& j, FloatType val) noexcept
5605{
5606 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5607}
5608
5609template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5610 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5611inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5612{
5613 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5614}
5615
5616template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5617 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5618inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5619{
5620 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5621}
5622
5623#if !JSON_DISABLE_ENUM_SERIALIZATION
5624template<typename BasicJsonType, typename EnumType,
5625 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5626inline void to_json(BasicJsonType& j, EnumType e) noexcept
5627{
5628 using underlying_type = typename std::underlying_type<EnumType>::type;
5629 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5630}
5631#endif // JSON_DISABLE_ENUM_SERIALIZATION
5632
5633template<typename BasicJsonType>
5634inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5635{
5637}
5638
5639template < typename BasicJsonType, typename CompatibleArrayType,
5640 enable_if_t < is_compatible_array_type<BasicJsonType,
5641 CompatibleArrayType>::value&&
5642 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
5644 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
5645 !is_basic_json<CompatibleArrayType>::value,
5646 int > = 0 >
5647inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5648{
5650}
5651
5652template<typename BasicJsonType>
5653inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5654{
5656}
5657
5658template<typename BasicJsonType, typename T,
5659 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5660inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5661{
5663}
5664
5665template<typename BasicJsonType>
5666inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5667{
5669}
5670
5671template < typename BasicJsonType, typename CompatibleObjectType,
5672 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5673inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5674{
5676}
5677
5678template<typename BasicJsonType>
5679inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5680{
5682}
5683
5684template <
5685 typename BasicJsonType, typename T, std::size_t N,
5686 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5687 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5688 int > = 0 >
5689inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5690{
5692}
5693
5694template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5695inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5696{
5697 j = { p.first, p.second };
5698}
5699
5700// for https://github.com/nlohmann/json/pull/1134
5701template<typename BasicJsonType, typename T,
5702 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5703inline void to_json(BasicJsonType& j, const T& b)
5704{
5705 j = { {b.key(), b.value()} };
5706}
5707
5708template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5709inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5710{
5711 j = { std::get<Idx>(t)... };
5712}
5713
5714template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5715inline void to_json(BasicJsonType& j, const T& t)
5716{
5717 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5718}
5719
5720#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5721template<typename BasicJsonType>
5722inline void to_json(BasicJsonType& j, const std_fs::path& p)
5723{
5724 j = p.string();
5725}
5726#endif
5727
5729{
5730 template<typename BasicJsonType, typename T>
5731 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5732 -> decltype(to_json(j, std::forward<T>(val)), void())
5733 {
5734 return to_json(j, std::forward<T>(val));
5735 }
5736};
5737} // namespace detail
5738
5739#ifndef JSON_HAS_CPP_17
5743namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5744{
5745#endif
5746JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5748#ifndef JSON_HAS_CPP_17
5749} // namespace
5750#endif
5751
5753
5754// #include <nlohmann/detail/meta/identity_tag.hpp>
5755
5756
5758
5760template<typename ValueType, typename>
5762{
5765 template<typename BasicJsonType, typename TargetType = ValueType>
5766 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5767 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5768 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5769 {
5770 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5771 }
5772
5775 template<typename BasicJsonType, typename TargetType = ValueType>
5776 static auto from_json(BasicJsonType && j) noexcept(
5777 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5778 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5779 {
5780 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5781 }
5782
5785 template<typename BasicJsonType, typename TargetType = ValueType>
5786 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5787 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5788 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5789 {
5790 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5791 }
5792};
5793
5795
5796// #include <nlohmann/byte_container_with_subtype.hpp>
5797// __ _____ _____ _____
5798// __| | __| | | | JSON for Modern C++
5799// | | |__ | | | | | | version 3.11.2
5800// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5801//
5802// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5803// SPDX-License-Identifier: MIT
5804
5805
5806
5807#include <cstdint> // uint8_t, uint64_t
5808#include <tuple> // tie
5809#include <utility> // move
5810
5811// #include <nlohmann/detail/abi_macros.hpp>
5812
5813
5815
5818template<typename BinaryType>
5819class byte_container_with_subtype : public BinaryType
5820{
5821 public:
5822 using container_type = BinaryType;
5823 using subtype_type = std::uint64_t;
5824
5827 : container_type()
5828 {}
5829
5832 : container_type(b)
5833 {}
5834
5836 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5837 : container_type(std::move(b))
5838 {}
5839
5842 : container_type(b)
5843 , m_subtype(subtype_)
5844 , m_has_subtype(true)
5845 {}
5846
5848 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5849 : container_type(std::move(b))
5850 , m_subtype(subtype_)
5851 , m_has_subtype(true)
5852 {}
5853
5855 {
5856 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5857 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5858 }
5859
5861 {
5862 return !(rhs == *this);
5863 }
5864
5867 void set_subtype(subtype_type subtype_) noexcept
5868 {
5869 m_subtype = subtype_;
5870 m_has_subtype = true;
5871 }
5872
5875 constexpr subtype_type subtype() const noexcept
5876 {
5877 return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5878 }
5879
5882 constexpr bool has_subtype() const noexcept
5883 {
5884 return m_has_subtype;
5885 }
5886
5889 void clear_subtype() noexcept
5890 {
5891 m_subtype = 0;
5892 m_has_subtype = false;
5893 }
5894
5895 private:
5896 subtype_type m_subtype = 0;
5897 bool m_has_subtype = false;
5898};
5899
5901
5902// #include <nlohmann/detail/conversions/from_json.hpp>
5903
5904// #include <nlohmann/detail/conversions/to_json.hpp>
5905
5906// #include <nlohmann/detail/exceptions.hpp>
5907
5908// #include <nlohmann/detail/hash.hpp>
5909// __ _____ _____ _____
5910// __| | __| | | | JSON for Modern C++
5911// | | |__ | | | | | | version 3.11.2
5912// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5913//
5914// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
5915// SPDX-License-Identifier: MIT
5916
5917
5918
5919#include <cstdint> // uint8_t
5920#include <cstddef> // size_t
5921#include <functional> // hash
5922
5923// #include <nlohmann/detail/abi_macros.hpp>
5924
5925// #include <nlohmann/detail/value_t.hpp>
5926
5927
5929namespace detail
5930{
5931
5932// boost::hash_combine
5933inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5934{
5935 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5936 return seed;
5937}
5938
5950template<typename BasicJsonType>
5951std::size_t hash(const BasicJsonType& j)
5952{
5953 using string_t = typename BasicJsonType::string_t;
5954 using number_integer_t = typename BasicJsonType::number_integer_t;
5955 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5956 using number_float_t = typename BasicJsonType::number_float_t;
5957
5958 const auto type = static_cast<std::size_t>(j.type());
5959 switch (j.type())
5960 {
5961 case BasicJsonType::value_t::null:
5962 case BasicJsonType::value_t::discarded:
5963 {
5964 return combine(type, 0);
5965 }
5966
5967 case BasicJsonType::value_t::object:
5968 {
5969 auto seed = combine(type, j.size());
5970 for (const auto& element : j.items())
5971 {
5972 const auto h = std::hash<string_t> {}(element.key());
5973 seed = combine(seed, h);
5974 seed = combine(seed, hash(element.value()));
5975 }
5976 return seed;
5977 }
5978
5979 case BasicJsonType::value_t::array:
5980 {
5981 auto seed = combine(type, j.size());
5982 for (const auto& element : j)
5983 {
5984 seed = combine(seed, hash(element));
5985 }
5986 return seed;
5987 }
5988
5989 case BasicJsonType::value_t::string:
5990 {
5991 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5992 return combine(type, h);
5993 }
5994
5995 case BasicJsonType::value_t::boolean:
5996 {
5997 const auto h = std::hash<bool> {}(j.template get<bool>());
5998 return combine(type, h);
5999 }
6000
6001 case BasicJsonType::value_t::number_integer:
6002 {
6003 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
6004 return combine(type, h);
6005 }
6006
6007 case BasicJsonType::value_t::number_unsigned:
6008 {
6009 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
6010 return combine(type, h);
6011 }
6012
6013 case BasicJsonType::value_t::number_float:
6014 {
6015 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
6016 return combine(type, h);
6017 }
6018
6019 case BasicJsonType::value_t::binary:
6020 {
6021 auto seed = combine(type, j.get_binary().size());
6022 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
6023 seed = combine(seed, h);
6024 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6025 for (const auto byte : j.get_binary())
6026 {
6027 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6028 }
6029 return seed;
6030 }
6031
6032 default: // LCOV_EXCL_LINE
6033 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6034 return 0; // LCOV_EXCL_LINE
6035 }
6036}
6037
6038} // namespace detail
6040
6041// #include <nlohmann/detail/input/binary_reader.hpp>
6042// __ _____ _____ _____
6043// __| | __| | | | JSON for Modern C++
6044// | | |__ | | | | | | version 3.11.2
6045// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6046//
6047// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6048// SPDX-License-Identifier: MIT
6049
6050
6051
6052#include <algorithm> // generate_n
6053#include <array> // array
6054#include <cmath> // ldexp
6055#include <cstddef> // size_t
6056#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6057#include <cstdio> // snprintf
6058#include <cstring> // memcpy
6059#include <iterator> // back_inserter
6060#include <limits> // numeric_limits
6061#include <string> // char_traits, string
6062#include <utility> // make_pair, move
6063#include <vector> // vector
6064
6065// #include <nlohmann/detail/exceptions.hpp>
6066
6067// #include <nlohmann/detail/input/input_adapters.hpp>
6068// __ _____ _____ _____
6069// __| | __| | | | JSON for Modern C++
6070// | | |__ | | | | | | version 3.11.2
6071// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6072//
6073// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6074// SPDX-License-Identifier: MIT
6075
6076
6077
6078#include <array> // array
6079#include <cstddef> // size_t
6080#include <cstring> // strlen
6081#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6082#include <memory> // shared_ptr, make_shared, addressof
6083#include <numeric> // accumulate
6084#include <string> // string, char_traits
6085#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6086#include <utility> // pair, declval
6087
6088#ifndef JSON_NO_IO
6089 #include <cstdio> // FILE *
6090 #include <istream> // istream
6091#endif // JSON_NO_IO
6092
6093// #include <nlohmann/detail/iterators/iterator_traits.hpp>
6094
6095// #include <nlohmann/detail/macro_scope.hpp>
6096
6097
6099namespace detail
6100{
6101
6104
6106// input adapters //
6108
6109#ifndef JSON_NO_IO
6115{
6116 public:
6117 using char_type = char;
6118
6120 explicit file_input_adapter(std::FILE* f) noexcept
6121 : m_file(f)
6122 {
6123 JSON_ASSERT(m_file != nullptr);
6124 }
6125
6126 // make class move-only
6129 file_input_adapter& operator=(const file_input_adapter&) = delete;
6132
6133 std::char_traits<char>::int_type get_character() noexcept
6134 {
6135 return std::fgetc(m_file);
6136 }
6137
6138 private:
6140 std::FILE* m_file;
6141};
6142
6143
6154{
6155 public:
6156 using char_type = char;
6157
6159 {
6160 // clear stream flags; we use underlying streambuf I/O, do not
6161 // maintain ifstream flags, except eof
6162 if (is != nullptr)
6163 {
6164 is->clear(is->rdstate() & std::ios::eofbit);
6165 }
6166 }
6167
6168 explicit input_stream_adapter(std::istream& i)
6169 : is(&i), sb(i.rdbuf())
6170 {}
6171
6172 // delete because of pointer members
6176
6178 : is(rhs.is), sb(rhs.sb)
6179 {
6180 rhs.is = nullptr;
6181 rhs.sb = nullptr;
6182 }
6183
6184 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6185 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6186 // end up as the same value, e.g. 0xFFFFFFFF.
6187 std::char_traits<char>::int_type get_character()
6188 {
6189 auto res = sb->sbumpc();
6190 // set eof manually, as we don't use the istream interface.
6191 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6192 {
6193 is->clear(is->rdstate() | std::ios::eofbit);
6194 }
6195 return res;
6196 }
6197
6198 private:
6200 std::istream* is = nullptr;
6201 std::streambuf* sb = nullptr;
6202};
6203#endif // JSON_NO_IO
6204
6205// General-purpose iterator-based adapter. It might not be as fast as
6206// theoretically possible for some containers, but it is extremely versatile.
6207template<typename IteratorType>
6209{
6210 public:
6211 using char_type = typename std::iterator_traits<IteratorType>::value_type;
6212
6213 iterator_input_adapter(IteratorType first, IteratorType last)
6214 : current(std::move(first)), end(std::move(last))
6215 {}
6216
6217 typename std::char_traits<char_type>::int_type get_character()
6218 {
6219 if (JSON_HEDLEY_LIKELY(current != end))
6220 {
6221 auto result = std::char_traits<char_type>::to_int_type(*current);
6222 std::advance(current, 1);
6223 return result;
6224 }
6225
6226 return std::char_traits<char_type>::eof();
6227 }
6228
6229 private:
6230 IteratorType current;
6231 IteratorType end;
6232
6233 template<typename BaseInputAdapter, size_t T>
6235
6236 bool empty() const
6237 {
6238 return current == end;
6239 }
6240};
6241
6242
6243template<typename BaseInputAdapter, size_t T>
6245
6246template<typename BaseInputAdapter>
6247struct wide_string_input_helper<BaseInputAdapter, 4>
6248{
6249 // UTF-32
6250 static void fill_buffer(BaseInputAdapter& input,
6251 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6252 size_t& utf8_bytes_index,
6253 size_t& utf8_bytes_filled)
6254 {
6255 utf8_bytes_index = 0;
6256
6257 if (JSON_HEDLEY_UNLIKELY(input.empty()))
6258 {
6259 utf8_bytes[0] = std::char_traits<char>::eof();
6260 utf8_bytes_filled = 1;
6261 }
6262 else
6263 {
6264 // get the current character
6265 const auto wc = input.get_character();
6266
6267 // UTF-32 to UTF-8 encoding
6268 if (wc < 0x80)
6269 {
6270 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6271 utf8_bytes_filled = 1;
6272 }
6273 else if (wc <= 0x7FF)
6274 {
6275 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6276 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6277 utf8_bytes_filled = 2;
6278 }
6279 else if (wc <= 0xFFFF)
6280 {
6281 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6282 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6283 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6284 utf8_bytes_filled = 3;
6285 }
6286 else if (wc <= 0x10FFFF)
6287 {
6288 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6289 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6290 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6291 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6292 utf8_bytes_filled = 4;
6293 }
6294 else
6295 {
6296 // unknown character
6297 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6298 utf8_bytes_filled = 1;
6299 }
6300 }
6301 }
6302};
6303
6304template<typename BaseInputAdapter>
6305struct wide_string_input_helper<BaseInputAdapter, 2>
6306{
6307 // UTF-16
6308 static void fill_buffer(BaseInputAdapter& input,
6309 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6310 size_t& utf8_bytes_index,
6311 size_t& utf8_bytes_filled)
6312 {
6313 utf8_bytes_index = 0;
6314
6315 if (JSON_HEDLEY_UNLIKELY(input.empty()))
6316 {
6317 utf8_bytes[0] = std::char_traits<char>::eof();
6318 utf8_bytes_filled = 1;
6319 }
6320 else
6321 {
6322 // get the current character
6323 const auto wc = input.get_character();
6324
6325 // UTF-16 to UTF-8 encoding
6326 if (wc < 0x80)
6327 {
6328 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6329 utf8_bytes_filled = 1;
6330 }
6331 else if (wc <= 0x7FF)
6332 {
6333 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6334 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6335 utf8_bytes_filled = 2;
6336 }
6337 else if (0xD800 > wc || wc >= 0xE000)
6338 {
6339 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6340 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6341 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6342 utf8_bytes_filled = 3;
6343 }
6344 else
6345 {
6346 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6347 {
6348 const auto wc2 = static_cast<unsigned int>(input.get_character());
6349 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6350 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6351 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6352 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6353 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6354 utf8_bytes_filled = 4;
6355 }
6356 else
6357 {
6358 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6359 utf8_bytes_filled = 1;
6360 }
6361 }
6362 }
6363 }
6364};
6365
6366// Wraps another input apdater to convert wide character types into individual bytes.
6367template<typename BaseInputAdapter, typename WideCharType>
6369{
6370 public:
6371 using char_type = char;
6372
6373 wide_string_input_adapter(BaseInputAdapter base)
6374 : base_adapter(base) {}
6375
6376 typename std::char_traits<char>::int_type get_character() noexcept
6377 {
6378 // check if buffer needs to be filled
6379 if (utf8_bytes_index == utf8_bytes_filled)
6380 {
6381 fill_buffer<sizeof(WideCharType)>();
6382
6383 JSON_ASSERT(utf8_bytes_filled > 0);
6384 JSON_ASSERT(utf8_bytes_index == 0);
6385 }
6386
6387 // use buffer
6388 JSON_ASSERT(utf8_bytes_filled > 0);
6389 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
6390 return utf8_bytes[utf8_bytes_index++];
6391 }
6392
6393 private:
6394 BaseInputAdapter base_adapter;
6395
6396 template<size_t T>
6397 void fill_buffer()
6398 {
6399 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
6400 }
6401
6403 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6404
6406 std::size_t utf8_bytes_index = 0;
6408 std::size_t utf8_bytes_filled = 0;
6409};
6410
6411
6412template<typename IteratorType, typename Enable = void>
6414{
6415 using iterator_type = IteratorType;
6416 using char_type = typename std::iterator_traits<iterator_type>::value_type;
6418
6419 static adapter_type create(IteratorType first, IteratorType last)
6420 {
6421 return adapter_type(std::move(first), std::move(last));
6422 }
6423};
6424
6425template<typename T>
6427{
6428 using value_type = typename std::iterator_traits<T>::value_type;
6429 enum
6430 {
6431 value = sizeof(value_type) > 1
6432 };
6433};
6434
6435template<typename IteratorType>
6437{
6438 using iterator_type = IteratorType;
6439 using char_type = typename std::iterator_traits<iterator_type>::value_type;
6442
6443 static adapter_type create(IteratorType first, IteratorType last)
6444 {
6445 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6446 }
6447};
6448
6449// General purpose iterator-based input
6450template<typename IteratorType>
6452{
6454 return factory_type::create(first, last);
6455}
6456
6457// Convenience shorthand from container to iterator
6458// Enables ADL on begin(container) and end(container)
6459// Encloses the using declarations in namespace for not to leak them to outside scope
6460
6461namespace container_input_adapter_factory_impl
6462{
6463
6464using std::begin;
6465using std::end;
6466
6467template<typename ContainerType, typename Enable = void>
6469
6470template<typename ContainerType>
6472 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6473 {
6474 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6475
6476 static adapter_type create(const ContainerType& container)
6477{
6478 return input_adapter(begin(container), end(container));
6479}
6480 };
6481
6482} // namespace container_input_adapter_factory_impl
6483
6484template<typename ContainerType>
6486{
6488}
6489
6490#ifndef JSON_NO_IO
6491// Special cases with fast paths
6492inline file_input_adapter input_adapter(std::FILE* file)
6493{
6494 return file_input_adapter(file);
6495}
6496
6497inline input_stream_adapter input_adapter(std::istream& stream)
6498{
6499 return input_stream_adapter(stream);
6500}
6501
6502inline input_stream_adapter input_adapter(std::istream&& stream)
6503{
6504 return input_stream_adapter(stream);
6505}
6506#endif // JSON_NO_IO
6507
6508using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6509
6510// Null-delimited strings, and the like.
6511template < typename CharT,
6512 typename std::enable_if <
6513 std::is_pointer<CharT>::value&&
6514 !std::is_array<CharT>::value&&
6515 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6516 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6517 int >::type = 0 >
6519{
6520 auto length = std::strlen(reinterpret_cast<const char*>(b));
6521 const auto* ptr = reinterpret_cast<const char*>(b);
6522 return input_adapter(ptr, ptr + length);
6523}
6524
6525template<typename T, std::size_t N>
6526auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6527{
6528 return input_adapter(array, array + N);
6529}
6530
6531// This class only handles inputs of input_buffer_adapter type.
6532// It's required so that expressions like {ptr, len} can be implicitly cast
6533// to the correct adapter.
6535{
6536 public:
6537 template < typename CharT,
6538 typename std::enable_if <
6539 std::is_pointer<CharT>::value&&
6540 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
6541 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6542 int >::type = 0 >
6543 span_input_adapter(CharT b, std::size_t l)
6544 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6545
6546 template<class IteratorType,
6547 typename std::enable_if<
6548 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6549 int>::type = 0>
6550 span_input_adapter(IteratorType first, IteratorType last)
6551 : ia(input_adapter(first, last)) {}
6552
6554 {
6555 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6556 }
6557
6558 private:
6560};
6561
6562} // namespace detail
6564
6565// #include <nlohmann/detail/input/json_sax.hpp>
6566// __ _____ _____ _____
6567// __| | __| | | | JSON for Modern C++
6568// | | |__ | | | | | | version 3.11.2
6569// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6570//
6571// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
6572// SPDX-License-Identifier: MIT
6573
6574
6575
6576#include <cstddef>
6577#include <string> // string
6578#include <utility> // move
6579#include <vector> // vector
6580
6581// #include <nlohmann/detail/exceptions.hpp>
6582
6583// #include <nlohmann/detail/macro_scope.hpp>
6584
6585// #include <nlohmann/detail/string_concat.hpp>
6586
6587
6589
6598template<typename BasicJsonType>
6600{
6601 using number_integer_t = typename BasicJsonType::number_integer_t;
6602 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6603 using number_float_t = typename BasicJsonType::number_float_t;
6604 using string_t = typename BasicJsonType::string_t;
6605 using binary_t = typename BasicJsonType::binary_t;
6606
6611 virtual bool null() = 0;
6612
6618 virtual bool boolean(bool val) = 0;
6619
6625 virtual bool number_integer(number_integer_t val) = 0;
6626
6632 virtual bool number_unsigned(number_unsigned_t val) = 0;
6633
6640 virtual bool number_float(number_float_t val, const string_t& s) = 0;
6641
6648 virtual bool string(string_t& val) = 0;
6649
6656 virtual bool binary(binary_t& val) = 0;
6657
6664 virtual bool start_object(std::size_t elements) = 0;
6665
6672 virtual bool key(string_t& val) = 0;
6673
6678 virtual bool end_object() = 0;
6679
6686 virtual bool start_array(std::size_t elements) = 0;
6687
6692 virtual bool end_array() = 0;
6693
6701 virtual bool parse_error(std::size_t position,
6702 const std::string& last_token,
6703 const detail::exception& ex) = 0;
6704
6705 json_sax() = default;
6706 json_sax(const json_sax&) = default;
6707 json_sax(json_sax&&) noexcept = default;
6708 json_sax& operator=(const json_sax&) = default;
6709 json_sax& operator=(json_sax&&) noexcept = default;
6710 virtual ~json_sax() = default;
6711};
6712
6713
6714namespace detail
6715{
6729template<typename BasicJsonType>
6731{
6732 public:
6733 using number_integer_t = typename BasicJsonType::number_integer_t;
6734 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6735 using number_float_t = typename BasicJsonType::number_float_t;
6736 using string_t = typename BasicJsonType::string_t;
6737 using binary_t = typename BasicJsonType::binary_t;
6738
6744 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6745 : root(r), allow_exceptions(allow_exceptions_)
6746 {}
6747
6748 // make class move-only
6750 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6752 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6754
6755 bool null()
6756 {
6757 handle_value(nullptr);
6758 return true;
6759 }
6760
6761 bool boolean(bool val)
6762 {
6763 handle_value(val);
6764 return true;
6765 }
6766
6768 {
6769 handle_value(val);
6770 return true;
6771 }
6772
6774 {
6775 handle_value(val);
6776 return true;
6777 }
6778
6779 bool number_float(number_float_t val, const string_t& /*unused*/)
6780 {
6781 handle_value(val);
6782 return true;
6783 }
6784
6785 bool string(string_t& val)
6786 {
6787 handle_value(val);
6788 return true;
6789 }
6790
6791 bool binary(binary_t& val)
6792 {
6793 handle_value(std::move(val));
6794 return true;
6795 }
6796
6797 bool start_object(std::size_t len)
6798 {
6799 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6800
6801 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6802 {
6803 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6804 }
6805
6806 return true;
6807 }
6808
6809 bool key(string_t& val)
6810 {
6811 JSON_ASSERT(!ref_stack.empty());
6812 JSON_ASSERT(ref_stack.back()->is_object());
6813
6814 // add null at given key and store the reference for later
6815 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6816 return true;
6817 }
6818
6820 {
6821 JSON_ASSERT(!ref_stack.empty());
6822 JSON_ASSERT(ref_stack.back()->is_object());
6823
6824 ref_stack.back()->set_parents();
6825 ref_stack.pop_back();
6826 return true;
6827 }
6828
6829 bool start_array(std::size_t len)
6830 {
6831 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6832
6833 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6834 {
6835 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6836 }
6837
6838 return true;
6839 }
6840
6842 {
6843 JSON_ASSERT(!ref_stack.empty());
6844 JSON_ASSERT(ref_stack.back()->is_array());
6845
6846 ref_stack.back()->set_parents();
6847 ref_stack.pop_back();
6848 return true;
6849 }
6850
6851 template<class Exception>
6852 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6853 const Exception& ex)
6854 {
6855 errored = true;
6856 static_cast<void>(ex);
6857 if (allow_exceptions)
6858 {
6859 JSON_THROW(ex);
6860 }
6861 return false;
6862 }
6863
6864 constexpr bool is_errored() const
6865 {
6866 return errored;
6867 }
6868
6869 private:
6876 template<typename Value>
6878 BasicJsonType* handle_value(Value&& v)
6879 {
6880 if (ref_stack.empty())
6881 {
6882 root = BasicJsonType(std::forward<Value>(v));
6883 return &root;
6884 }
6885
6886 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6887
6888 if (ref_stack.back()->is_array())
6889 {
6890 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6891 return &(ref_stack.back()->m_value.array->back());
6892 }
6893
6894 JSON_ASSERT(ref_stack.back()->is_object());
6895 JSON_ASSERT(object_element);
6896 *object_element = BasicJsonType(std::forward<Value>(v));
6897 return object_element;
6898 }
6899
6901 BasicJsonType& root;
6903 std::vector<BasicJsonType*> ref_stack {};
6905 BasicJsonType* object_element = nullptr;
6907 bool errored = false;
6909 const bool allow_exceptions = true;
6910};
6911
6912template<typename BasicJsonType>
6914{
6915 public:
6916 using number_integer_t = typename BasicJsonType::number_integer_t;
6917 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6918 using number_float_t = typename BasicJsonType::number_float_t;
6919 using string_t = typename BasicJsonType::string_t;
6920 using binary_t = typename BasicJsonType::binary_t;
6921 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6922 using parse_event_t = typename BasicJsonType::parse_event_t;
6923
6925 const parser_callback_t cb,
6926 const bool allow_exceptions_ = true)
6927 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6928 {
6929 keep_stack.push_back(true);
6930 }
6931
6932 // make class move-only
6934 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6936 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6938
6939 bool null()
6940 {
6941 handle_value(nullptr);
6942 return true;
6943 }
6944
6945 bool boolean(bool val)
6946 {
6947 handle_value(val);
6948 return true;
6949 }
6950
6952 {
6953 handle_value(val);
6954 return true;
6955 }
6956
6958 {
6959 handle_value(val);
6960 return true;
6961 }
6962
6963 bool number_float(number_float_t val, const string_t& /*unused*/)
6964 {
6965 handle_value(val);
6966 return true;
6967 }
6968
6969 bool string(string_t& val)
6970 {
6971 handle_value(val);
6972 return true;
6973 }
6974
6975 bool binary(binary_t& val)
6976 {
6977 handle_value(std::move(val));
6978 return true;
6979 }
6980
6981 bool start_object(std::size_t len)
6982 {
6983 // check callback for object start
6984 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6985 keep_stack.push_back(keep);
6986
6987 auto val = handle_value(BasicJsonType::value_t::object, true);
6988 ref_stack.push_back(val.second);
6989
6990 // check object limit
6991 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6992 {
6993 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6994 }
6995
6996 return true;
6997 }
6998
6999 bool key(string_t& val)
7000 {
7001 BasicJsonType k = BasicJsonType(val);
7002
7003 // check callback for key
7004 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
7005 key_keep_stack.push_back(keep);
7006
7007 // add discarded value at given key and store the reference for later
7008 if (keep && ref_stack.back())
7009 {
7010 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
7011 }
7012
7013 return true;
7014 }
7015
7017 {
7018 if (ref_stack.back())
7019 {
7020 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
7021 {
7022 // discard object
7023 *ref_stack.back() = discarded;
7024 }
7025 else
7026 {
7027 ref_stack.back()->set_parents();
7028 }
7029 }
7030
7031 JSON_ASSERT(!ref_stack.empty());
7032 JSON_ASSERT(!keep_stack.empty());
7033 ref_stack.pop_back();
7034 keep_stack.pop_back();
7035
7036 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
7037 {
7038 // remove discarded value
7039 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
7040 {
7041 if (it->is_discarded())
7042 {
7043 ref_stack.back()->erase(it);
7044 break;
7045 }
7046 }
7047 }
7048
7049 return true;
7050 }
7051
7052 bool start_array(std::size_t len)
7053 {
7054 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
7055 keep_stack.push_back(keep);
7056
7057 auto val = handle_value(BasicJsonType::value_t::array, true);
7058 ref_stack.push_back(val.second);
7059
7060 // check array limit
7061 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7062 {
7063 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
7064 }
7065
7066 return true;
7067 }
7068
7070 {
7071 bool keep = true;
7072
7073 if (ref_stack.back())
7074 {
7075 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
7076 if (keep)
7077 {
7078 ref_stack.back()->set_parents();
7079 }
7080 else
7081 {
7082 // discard array
7083 *ref_stack.back() = discarded;
7084 }
7085 }
7086
7087 JSON_ASSERT(!ref_stack.empty());
7088 JSON_ASSERT(!keep_stack.empty());
7089 ref_stack.pop_back();
7090 keep_stack.pop_back();
7091
7092 // remove discarded value
7093 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
7094 {
7095 ref_stack.back()->m_value.array->pop_back();
7096 }
7097
7098 return true;
7099 }
7100
7101 template<class Exception>
7102 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
7103 const Exception& ex)
7104 {
7105 errored = true;
7106 static_cast<void>(ex);
7107 if (allow_exceptions)
7108 {
7109 JSON_THROW(ex);
7110 }
7111 return false;
7112 }
7113
7114 constexpr bool is_errored() const
7115 {
7116 return errored;
7117 }
7118
7119 private:
7135 template<typename Value>
7136 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
7137 {
7138 JSON_ASSERT(!keep_stack.empty());
7139
7140 // do not handle this value if we know it would be added to a discarded
7141 // container
7142 if (!keep_stack.back())
7143 {
7144 return {false, nullptr};
7145 }
7146
7147 // create value
7148 auto value = BasicJsonType(std::forward<Value>(v));
7149
7150 // check callback
7151 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
7152
7153 // do not handle this value if we just learnt it shall be discarded
7154 if (!keep)
7155 {
7156 return {false, nullptr};
7157 }
7158
7159 if (ref_stack.empty())
7160 {
7161 root = std::move(value);
7162 return {true, &root};
7163 }
7164
7165 // skip this value if we already decided to skip the parent
7166 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
7167 if (!ref_stack.back())
7168 {
7169 return {false, nullptr};
7170 }
7171
7172 // we now only expect arrays and objects
7173 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
7174
7175 // array
7176 if (ref_stack.back()->is_array())
7177 {
7178 ref_stack.back()->m_value.array->emplace_back(std::move(value));
7179 return {true, &(ref_stack.back()->m_value.array->back())};
7180 }
7181
7182 // object
7183 JSON_ASSERT(ref_stack.back()->is_object());
7184 // check if we should store an element for the current key
7185 JSON_ASSERT(!key_keep_stack.empty());
7186 const bool store_element = key_keep_stack.back();
7187 key_keep_stack.pop_back();
7188
7189 if (!store_element)
7190 {
7191 return {false, nullptr};
7192 }
7193
7194 JSON_ASSERT(object_element);
7195 *object_element = std::move(value);
7196 return {true, object_element};
7197 }
7198
7200 BasicJsonType& root;
7202 std::vector<BasicJsonType*> ref_stack {};
7204 std::vector<bool> keep_stack {};
7206 std::vector<bool> key_keep_stack {};
7208 BasicJsonType* object_element = nullptr;
7210 bool errored = false;
7212 const parser_callback_t callback = nullptr;
7214 const bool allow_exceptions = true;
7216 BasicJsonType discarded = BasicJsonType::value_t::discarded;
7217};
7218
7219template<typename BasicJsonType>
7221{
7222 public:
7223 using number_integer_t = typename BasicJsonType::number_integer_t;
7224 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7225 using number_float_t = typename BasicJsonType::number_float_t;
7226 using string_t = typename BasicJsonType::string_t;
7227 using binary_t = typename BasicJsonType::binary_t;
7228
7229 bool null()
7230 {
7231 return true;
7232 }
7233
7234 bool boolean(bool /*unused*/)
7235 {
7236 return true;
7237 }
7238
7240 {
7241 return true;
7242 }
7243
7245 {
7246 return true;
7247 }
7248
7249 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
7250 {
7251 return true;
7252 }
7253
7254 bool string(string_t& /*unused*/)
7255 {
7256 return true;
7257 }
7258
7259 bool binary(binary_t& /*unused*/)
7260 {
7261 return true;
7262 }
7263
7264 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7265 {
7266 return true;
7267 }
7268
7269 bool key(string_t& /*unused*/)
7270 {
7271 return true;
7272 }
7273
7275 {
7276 return true;
7277 }
7278
7279 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7280 {
7281 return true;
7282 }
7283
7285 {
7286 return true;
7287 }
7288
7289 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
7290 {
7291 return false;
7292 }
7293};
7294
7295} // namespace detail
7297
7298// #include <nlohmann/detail/input/lexer.hpp>
7299// __ _____ _____ _____
7300// __| | __| | | | JSON for Modern C++
7301// | | |__ | | | | | | version 3.11.2
7302// |_____|_____|_____|_|___| https://github.com/nlohmann/json
7303//
7304// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7305// SPDX-License-Identifier: MIT
7306
7307
7308
7309#include <array> // array
7310#include <clocale> // localeconv
7311#include <cstddef> // size_t
7312#include <cstdio> // snprintf
7313#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7314#include <initializer_list> // initializer_list
7315#include <string> // char_traits, string
7316#include <utility> // move
7317#include <vector> // vector
7318
7319// #include <nlohmann/detail/input/input_adapters.hpp>
7320
7321// #include <nlohmann/detail/input/position_t.hpp>
7322
7323// #include <nlohmann/detail/macro_scope.hpp>
7324
7325
7327namespace detail
7328{
7329
7331// lexer //
7333
7334template<typename BasicJsonType>
7336{
7337 public:
7339 enum class token_type
7340 {
7341 uninitialized,
7342 literal_true,
7343 literal_false,
7344 literal_null,
7345 value_string,
7346 value_unsigned,
7347 value_integer,
7348 value_float,
7349 begin_array,
7350 begin_object,
7351 end_array,
7352 end_object,
7353 name_separator,
7354 value_separator,
7355 parse_error,
7356 end_of_input,
7357 literal_or_value
7358 };
7359
7363 static const char* token_type_name(const token_type t) noexcept
7364 {
7365 switch (t)
7366 {
7367 case token_type::uninitialized:
7368 return "<uninitialized>";
7369 case token_type::literal_true:
7370 return "true literal";
7371 case token_type::literal_false:
7372 return "false literal";
7373 case token_type::literal_null:
7374 return "null literal";
7375 case token_type::value_string:
7376 return "string literal";
7377 case token_type::value_unsigned:
7378 case token_type::value_integer:
7379 case token_type::value_float:
7380 return "number literal";
7381 case token_type::begin_array:
7382 return "'['";
7383 case token_type::begin_object:
7384 return "'{'";
7385 case token_type::end_array:
7386 return "']'";
7387 case token_type::end_object:
7388 return "'}'";
7389 case token_type::name_separator:
7390 return "':'";
7391 case token_type::value_separator:
7392 return "','";
7393 case token_type::parse_error:
7394 return "<parse error>";
7395 case token_type::end_of_input:
7396 return "end of input";
7397 case token_type::literal_or_value:
7398 return "'[', '{', or a literal";
7399 // LCOV_EXCL_START
7400 default: // catch non-enum values
7401 return "unknown token";
7402 // LCOV_EXCL_STOP
7403 }
7404 }
7405};
7411template<typename BasicJsonType, typename InputAdapterType>
7412class lexer : public lexer_base<BasicJsonType>
7413{
7414 using number_integer_t = typename BasicJsonType::number_integer_t;
7415 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7416 using number_float_t = typename BasicJsonType::number_float_t;
7417 using string_t = typename BasicJsonType::string_t;
7418 using char_type = typename InputAdapterType::char_type;
7419 using char_int_type = typename std::char_traits<char_type>::int_type;
7420
7421 public:
7423
7424 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7425 : ia(std::move(adapter))
7426 , ignore_comments(ignore_comments_)
7427 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7428 {}
7429
7430 // delete because of pointer members
7431 lexer(const lexer&) = delete;
7432 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7433 lexer& operator=(lexer&) = delete;
7434 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7435 ~lexer() = default;
7436
7437 private:
7439 // locales
7441
7444 static char get_decimal_point() noexcept
7445 {
7446 const auto* loc = localeconv();
7447 JSON_ASSERT(loc != nullptr);
7448 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7449 }
7450
7452 // scan functions
7454
7470 int get_codepoint()
7471 {
7472 // this function only makes sense after reading `\u`
7473 JSON_ASSERT(current == 'u');
7474 int codepoint = 0;
7475
7476 const auto factors = { 12u, 8u, 4u, 0u };
7477 for (const auto factor : factors)
7478 {
7479 get();
7480
7481 if (current >= '0' && current <= '9')
7482 {
7483 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7484 }
7485 else if (current >= 'A' && current <= 'F')
7486 {
7487 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7488 }
7489 else if (current >= 'a' && current <= 'f')
7490 {
7491 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7492 }
7493 else
7494 {
7495 return -1;
7496 }
7497 }
7498
7499 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7500 return codepoint;
7501 }
7502
7518 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7519 {
7520 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7521 add(current);
7522
7523 for (auto range = ranges.begin(); range != ranges.end(); ++range)
7524 {
7525 get();
7526 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
7527 {
7528 add(current);
7529 }
7530 else
7531 {
7532 error_message = "invalid string: ill-formed UTF-8 byte";
7533 return false;
7534 }
7535 }
7536
7537 return true;
7538 }
7539
7555 token_type scan_string()
7556 {
7557 // reset token_buffer (ignore opening quote)
7558 reset();
7559
7560 // we entered the function by reading an open quote
7561 JSON_ASSERT(current == '\"');
7562
7563 while (true)
7564 {
7565 // get next character
7566 switch (get())
7567 {
7568 // end of file while parsing string
7569 case std::char_traits<char_type>::eof():
7570 {
7571 error_message = "invalid string: missing closing quote";
7572 return token_type::parse_error;
7573 }
7574
7575 // closing quote
7576 case '\"':
7577 {
7578 return token_type::value_string;
7579 }
7580
7581 // escapes
7582 case '\\':
7583 {
7584 switch (get())
7585 {
7586 // quotation mark
7587 case '\"':
7588 add('\"');
7589 break;
7590 // reverse solidus
7591 case '\\':
7592 add('\\');
7593 break;
7594 // solidus
7595 case '/':
7596 add('/');
7597 break;
7598 // backspace
7599 case 'b':
7600 add('\b');
7601 break;
7602 // form feed
7603 case 'f':
7604 add('\f');
7605 break;
7606 // line feed
7607 case 'n':
7608 add('\n');
7609 break;
7610 // carriage return
7611 case 'r':
7612 add('\r');
7613 break;
7614 // tab
7615 case 't':
7616 add('\t');
7617 break;
7618
7619 // unicode escapes
7620 case 'u':
7621 {
7622 const int codepoint1 = get_codepoint();
7623 int codepoint = codepoint1; // start with codepoint1
7624
7625 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7626 {
7627 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7628 return token_type::parse_error;
7629 }
7630
7631 // check if code point is a high surrogate
7632 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7633 {
7634 // expect next \uxxxx entry
7635 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7636 {
7637 const int codepoint2 = get_codepoint();
7638
7639 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7640 {
7641 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7642 return token_type::parse_error;
7643 }
7644
7645 // check if codepoint2 is a low surrogate
7646 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7647 {
7648 // overwrite codepoint
7649 codepoint = static_cast<int>(
7650 // high surrogate occupies the most significant 22 bits
7651 (static_cast<unsigned int>(codepoint1) << 10u)
7652 // low surrogate occupies the least significant 15 bits
7653 + static_cast<unsigned int>(codepoint2)
7654 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7655 // in the result, so we have to subtract with:
7656 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7657 - 0x35FDC00u);
7658 }
7659 else
7660 {
7661 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7662 return token_type::parse_error;
7663 }
7664 }
7665 else
7666 {
7667 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7668 return token_type::parse_error;
7669 }
7670 }
7671 else
7672 {
7673 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7674 {
7675 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7676 return token_type::parse_error;
7677 }
7678 }
7679
7680 // result of the above calculation yields a proper codepoint
7681 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7682
7683 // translate codepoint into bytes
7684 if (codepoint < 0x80)
7685 {
7686 // 1-byte characters: 0xxxxxxx (ASCII)
7687 add(static_cast<char_int_type>(codepoint));
7688 }
7689 else if (codepoint <= 0x7FF)
7690 {
7691 // 2-byte characters: 110xxxxx 10xxxxxx
7692 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7693 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7694 }
7695 else if (codepoint <= 0xFFFF)
7696 {
7697 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7698 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7699 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7700 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7701 }
7702 else
7703 {
7704 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7705 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7706 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7707 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7708 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7709 }
7710
7711 break;
7712 }
7713
7714 // other characters after escape
7715 default:
7716 error_message = "invalid string: forbidden character after backslash";
7717 return token_type::parse_error;
7718 }
7719
7720 break;
7721 }
7722
7723 // invalid control characters
7724 case 0x00:
7725 {
7726 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7727 return token_type::parse_error;
7728 }
7729
7730 case 0x01:
7731 {
7732 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7733 return token_type::parse_error;
7734 }
7735
7736 case 0x02:
7737 {
7738 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7739 return token_type::parse_error;
7740 }
7741
7742 case 0x03:
7743 {
7744 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7745 return token_type::parse_error;
7746 }
7747
7748 case 0x04:
7749 {
7750 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7751 return token_type::parse_error;
7752 }
7753
7754 case 0x05:
7755 {
7756 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7757 return token_type::parse_error;
7758 }
7759
7760 case 0x06:
7761 {
7762 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7763 return token_type::parse_error;
7764 }
7765
7766 case 0x07:
7767 {
7768 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7769 return token_type::parse_error;
7770 }
7771
7772 case 0x08:
7773 {
7774 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7775 return token_type::parse_error;
7776 }
7777
7778 case 0x09:
7779 {
7780 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7781 return token_type::parse_error;
7782 }
7783
7784 case 0x0A:
7785 {
7786 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7787 return token_type::parse_error;
7788 }
7789
7790 case 0x0B:
7791 {
7792 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7793 return token_type::parse_error;
7794 }
7795
7796 case 0x0C:
7797 {
7798 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7799 return token_type::parse_error;
7800 }
7801
7802 case 0x0D:
7803 {
7804 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7805 return token_type::parse_error;
7806 }
7807
7808 case 0x0E:
7809 {
7810 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7811 return token_type::parse_error;
7812 }
7813
7814 case 0x0F:
7815 {
7816 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7817 return token_type::parse_error;
7818 }
7819
7820 case 0x10:
7821 {
7822 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7823 return token_type::parse_error;
7824 }
7825
7826 case 0x11:
7827 {
7828 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7829 return token_type::parse_error;
7830 }
7831
7832 case 0x12:
7833 {
7834 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7835 return token_type::parse_error;
7836 }
7837
7838 case 0x13:
7839 {
7840 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7841 return token_type::parse_error;
7842 }
7843
7844 case 0x14:
7845 {
7846 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7847 return token_type::parse_error;
7848 }
7849
7850 case 0x15:
7851 {
7852 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7853 return token_type::parse_error;
7854 }
7855
7856 case 0x16:
7857 {
7858 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7859 return token_type::parse_error;
7860 }
7861
7862 case 0x17:
7863 {
7864 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7865 return token_type::parse_error;
7866 }
7867
7868 case 0x18:
7869 {
7870 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7871 return token_type::parse_error;
7872 }
7873
7874 case 0x19:
7875 {
7876 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7877 return token_type::parse_error;
7878 }
7879
7880 case 0x1A:
7881 {
7882 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7883 return token_type::parse_error;
7884 }
7885
7886 case 0x1B:
7887 {
7888 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7889 return token_type::parse_error;
7890 }
7891
7892 case 0x1C:
7893 {
7894 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7895 return token_type::parse_error;
7896 }
7897
7898 case 0x1D:
7899 {
7900 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7901 return token_type::parse_error;
7902 }
7903
7904 case 0x1E:
7905 {
7906 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7907 return token_type::parse_error;
7908 }
7909
7910 case 0x1F:
7911 {
7912 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7913 return token_type::parse_error;
7914 }
7915
7916 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7917 case 0x20:
7918 case 0x21:
7919 case 0x23:
7920 case 0x24:
7921 case 0x25:
7922 case 0x26:
7923 case 0x27:
7924 case 0x28:
7925 case 0x29:
7926 case 0x2A:
7927 case 0x2B:
7928 case 0x2C:
7929 case 0x2D:
7930 case 0x2E:
7931 case 0x2F:
7932 case 0x30:
7933 case 0x31:
7934 case 0x32:
7935 case 0x33:
7936 case 0x34:
7937 case 0x35:
7938 case 0x36:
7939 case 0x37:
7940 case 0x38:
7941 case 0x39:
7942 case 0x3A:
7943 case 0x3B:
7944 case 0x3C:
7945 case 0x3D:
7946 case 0x3E:
7947 case 0x3F:
7948 case 0x40:
7949 case 0x41:
7950 case 0x42:
7951 case 0x43:
7952 case 0x44:
7953 case 0x45:
7954 case 0x46:
7955 case 0x47:
7956 case 0x48:
7957 case 0x49:
7958 case 0x4A:
7959 case 0x4B:
7960 case 0x4C:
7961 case 0x4D:
7962 case 0x4E:
7963 case 0x4F:
7964 case 0x50:
7965 case 0x51:
7966 case 0x52:
7967 case 0x53:
7968 case 0x54:
7969 case 0x55:
7970 case 0x56:
7971 case 0x57:
7972 case 0x58:
7973 case 0x59:
7974 case 0x5A:
7975 case 0x5B:
7976 case 0x5D:
7977 case 0x5E:
7978 case 0x5F:
7979 case 0x60:
7980 case 0x61:
7981 case 0x62:
7982 case 0x63:
7983 case 0x64:
7984 case 0x65:
7985 case 0x66:
7986 case 0x67:
7987 case 0x68:
7988 case 0x69:
7989 case 0x6A:
7990 case 0x6B:
7991 case 0x6C:
7992 case 0x6D:
7993 case 0x6E:
7994 case 0x6F:
7995 case 0x70:
7996 case 0x71:
7997 case 0x72:
7998 case 0x73:
7999 case 0x74:
8000 case 0x75:
8001 case 0x76:
8002 case 0x77:
8003 case 0x78:
8004 case 0x79:
8005 case 0x7A:
8006 case 0x7B:
8007 case 0x7C:
8008 case 0x7D:
8009 case 0x7E:
8010 case 0x7F:
8011 {
8012 add(current);
8013 break;
8014 }
8015
8016 // U+0080..U+07FF: bytes C2..DF 80..BF
8017 case 0xC2:
8018 case 0xC3:
8019 case 0xC4:
8020 case 0xC5:
8021 case 0xC6:
8022 case 0xC7:
8023 case 0xC8:
8024 case 0xC9:
8025 case 0xCA:
8026 case 0xCB:
8027 case 0xCC:
8028 case 0xCD:
8029 case 0xCE:
8030 case 0xCF:
8031 case 0xD0:
8032 case 0xD1:
8033 case 0xD2:
8034 case 0xD3:
8035 case 0xD4:
8036 case 0xD5:
8037 case 0xD6:
8038 case 0xD7:
8039 case 0xD8:
8040 case 0xD9:
8041 case 0xDA:
8042 case 0xDB:
8043 case 0xDC:
8044 case 0xDD:
8045 case 0xDE:
8046 case 0xDF:
8047 {
8048 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
8049 {
8050 return token_type::parse_error;
8051 }
8052 break;
8053 }
8054
8055 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8056 case 0xE0:
8057 {
8058 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8059 {
8060 return token_type::parse_error;
8061 }
8062 break;
8063 }
8064
8065 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8066 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8067 case 0xE1:
8068 case 0xE2:
8069 case 0xE3:
8070 case 0xE4:
8071 case 0xE5:
8072 case 0xE6:
8073 case 0xE7:
8074 case 0xE8:
8075 case 0xE9:
8076 case 0xEA:
8077 case 0xEB:
8078 case 0xEC:
8079 case 0xEE:
8080 case 0xEF:
8081 {
8082 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8083 {
8084 return token_type::parse_error;
8085 }
8086 break;
8087 }
8088
8089 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8090 case 0xED:
8091 {
8092 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8093 {
8094 return token_type::parse_error;
8095 }
8096 break;
8097 }
8098
8099 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8100 case 0xF0:
8101 {
8102 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8103 {
8104 return token_type::parse_error;
8105 }
8106 break;
8107 }
8108
8109 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8110 case 0xF1:
8111 case 0xF2:
8112 case 0xF3:
8113 {
8114 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8115 {
8116 return token_type::parse_error;
8117 }
8118 break;
8119 }
8120
8121 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8122 case 0xF4:
8123 {
8124 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8125 {
8126 return token_type::parse_error;
8127 }
8128 break;
8129 }
8130
8131 // remaining bytes (80..C1 and F5..FF) are ill-formed
8132 default:
8133 {
8134 error_message = "invalid string: ill-formed UTF-8 byte";
8135 return token_type::parse_error;
8136 }
8137 }
8138 }
8139 }
8140
8145 bool scan_comment()
8146 {
8147 switch (get())
8148 {
8149 // single-line comments skip input until a newline or EOF is read
8150 case '/':
8151 {
8152 while (true)
8153 {
8154 switch (get())
8155 {
8156 case '\n':
8157 case '\r':
8158 case std::char_traits<char_type>::eof():
8159 case '\0':
8160 return true;
8161
8162 default:
8163 break;
8164 }
8165 }
8166 }
8167
8168 // multi-line comments skip input until */ is read
8169 case '*':
8170 {
8171 while (true)
8172 {
8173 switch (get())
8174 {
8175 case std::char_traits<char_type>::eof():
8176 case '\0':
8177 {
8178 error_message = "invalid comment; missing closing '*/'";
8179 return false;
8180 }
8181
8182 case '*':
8183 {
8184 switch (get())
8185 {
8186 case '/':
8187 return true;
8188
8189 default:
8190 {
8191 unget();
8192 continue;
8193 }
8194 }
8195 }
8196
8197 default:
8198 continue;
8199 }
8200 }
8201 }
8202
8203 // unexpected character after reading '/'
8204 default:
8205 {
8206 error_message = "invalid comment; expecting '/' or '*' after '/'";
8207 return false;
8208 }
8209 }
8210 }
8211
8213 static void strtof(float& f, const char* str, char** endptr) noexcept
8214 {
8215 f = std::strtof(str, endptr);
8216 }
8217
8219 static void strtof(double& f, const char* str, char** endptr) noexcept
8220 {
8221 f = std::strtod(str, endptr);
8222 }
8223
8225 static void strtof(long double& f, const char* str, char** endptr) noexcept
8226 {
8227 f = std::strtold(str, endptr);
8228 }
8229
8270 token_type scan_number() // lgtm [cpp/use-of-goto]
8271 {
8272 // reset token_buffer to store the number's bytes
8273 reset();
8274
8275 // the type of the parsed number; initially set to unsigned; will be
8276 // changed if minus sign, decimal point or exponent is read
8277 token_type number_type = token_type::value_unsigned;
8278
8279 // state (init): we just found out we need to scan a number
8280 switch (current)
8281 {
8282 case '-':
8283 {
8284 add(current);
8285 goto scan_number_minus;
8286 }
8287
8288 case '0':
8289 {
8290 add(current);
8291 goto scan_number_zero;
8292 }
8293
8294 case '1':
8295 case '2':
8296 case '3':
8297 case '4':
8298 case '5':
8299 case '6':
8300 case '7':
8301 case '8':
8302 case '9':
8303 {
8304 add(current);
8305 goto scan_number_any1;
8306 }
8307
8308 // all other characters are rejected outside scan_number()
8309 default: // LCOV_EXCL_LINE
8310 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8311 }
8312
8313scan_number_minus:
8314 // state: we just parsed a leading minus sign
8315 number_type = token_type::value_integer;
8316 switch (get())
8317 {
8318 case '0':
8319 {
8320 add(current);
8321 goto scan_number_zero;
8322 }
8323
8324 case '1':
8325 case '2':
8326 case '3':
8327 case '4':
8328 case '5':
8329 case '6':
8330 case '7':
8331 case '8':
8332 case '9':
8333 {
8334 add(current);
8335 goto scan_number_any1;
8336 }
8337
8338 default:
8339 {
8340 error_message = "invalid number; expected digit after '-'";
8341 return token_type::parse_error;
8342 }
8343 }
8344
8345scan_number_zero:
8346 // state: we just parse a zero (maybe with a leading minus sign)
8347 switch (get())
8348 {
8349 case '.':
8350 {
8351 add(decimal_point_char);
8352 goto scan_number_decimal1;
8353 }
8354
8355 case 'e':
8356 case 'E':
8357 {
8358 add(current);
8359 goto scan_number_exponent;
8360 }
8361
8362 default:
8363 goto scan_number_done;
8364 }
8365
8366scan_number_any1:
8367 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8368 switch (get())
8369 {
8370 case '0':
8371 case '1':
8372 case '2':
8373 case '3':
8374 case '4':
8375 case '5':
8376 case '6':
8377 case '7':
8378 case '8':
8379 case '9':
8380 {
8381 add(current);
8382 goto scan_number_any1;
8383 }
8384
8385 case '.':
8386 {
8387 add(decimal_point_char);
8388 goto scan_number_decimal1;
8389 }
8390
8391 case 'e':
8392 case 'E':
8393 {
8394 add(current);
8395 goto scan_number_exponent;
8396 }
8397
8398 default:
8399 goto scan_number_done;
8400 }
8401
8402scan_number_decimal1:
8403 // state: we just parsed a decimal point
8404 number_type = token_type::value_float;
8405 switch (get())
8406 {
8407 case '0':
8408 case '1':
8409 case '2':
8410 case '3':
8411 case '4':
8412 case '5':
8413 case '6':
8414 case '7':
8415 case '8':
8416 case '9':
8417 {
8418 add(current);
8419 goto scan_number_decimal2;
8420 }
8421
8422 default:
8423 {
8424 error_message = "invalid number; expected digit after '.'";
8425 return token_type::parse_error;
8426 }
8427 }
8428
8429scan_number_decimal2:
8430 // we just parsed at least one number after a decimal point
8431 switch (get())
8432 {
8433 case '0':
8434 case '1':
8435 case '2':
8436 case '3':
8437 case '4':
8438 case '5':
8439 case '6':
8440 case '7':
8441 case '8':
8442 case '9':
8443 {
8444 add(current);
8445 goto scan_number_decimal2;
8446 }
8447
8448 case 'e':
8449 case 'E':
8450 {
8451 add(current);
8452 goto scan_number_exponent;
8453 }
8454
8455 default:
8456 goto scan_number_done;
8457 }
8458
8459scan_number_exponent:
8460 // we just parsed an exponent
8461 number_type = token_type::value_float;
8462 switch (get())
8463 {
8464 case '+':
8465 case '-':
8466 {
8467 add(current);
8468 goto scan_number_sign;
8469 }
8470
8471 case '0':
8472 case '1':
8473 case '2':
8474 case '3':
8475 case '4':
8476 case '5':
8477 case '6':
8478 case '7':
8479 case '8':
8480 case '9':
8481 {
8482 add(current);
8483 goto scan_number_any2;
8484 }
8485
8486 default:
8487 {
8488 error_message =
8489 "invalid number; expected '+', '-', or digit after exponent";
8490 return token_type::parse_error;
8491 }
8492 }
8493
8494scan_number_sign:
8495 // we just parsed an exponent sign
8496 switch (get())
8497 {
8498 case '0':
8499 case '1':
8500 case '2':
8501 case '3':
8502 case '4':
8503 case '5':
8504 case '6':
8505 case '7':
8506 case '8':
8507 case '9':
8508 {
8509 add(current);
8510 goto scan_number_any2;
8511 }
8512
8513 default:
8514 {
8515 error_message = "invalid number; expected digit after exponent sign";
8516 return token_type::parse_error;
8517 }
8518 }
8519
8520scan_number_any2:
8521 // we just parsed a number after the exponent or exponent sign
8522 switch (get())
8523 {
8524 case '0':
8525 case '1':
8526 case '2':
8527 case '3':
8528 case '4':
8529 case '5':
8530 case '6':
8531 case '7':
8532 case '8':
8533 case '9':
8534 {
8535 add(current);
8536 goto scan_number_any2;
8537 }
8538
8539 default:
8540 goto scan_number_done;
8541 }
8542
8543scan_number_done:
8544 // unget the character after the number (we only read it to know that
8545 // we are done scanning a number)
8546 unget();
8547
8548 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8549 errno = 0;
8550
8551 // try to parse integers first and fall back to floats
8552 if (number_type == token_type::value_unsigned)
8553 {
8554 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8555
8556 // we checked the number format before
8557 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8558
8559 if (errno == 0)
8560 {
8561 value_unsigned = static_cast<number_unsigned_t>(x);
8562 if (value_unsigned == x)
8563 {
8564 return token_type::value_unsigned;
8565 }
8566 }
8567 }
8568 else if (number_type == token_type::value_integer)
8569 {
8570 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8571
8572 // we checked the number format before
8573 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8574
8575 if (errno == 0)
8576 {
8577 value_integer = static_cast<number_integer_t>(x);
8578 if (value_integer == x)
8579 {
8580 return token_type::value_integer;
8581 }
8582 }
8583 }
8584
8585 // this code is reached if we parse a floating-point number or if an
8586 // integer conversion above failed
8587 strtof(value_float, token_buffer.data(), &endptr);
8588
8589 // we checked the number format before
8590 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8591
8592 return token_type::value_float;
8593 }
8594
8601 token_type scan_literal(const char_type* literal_text, const std::size_t length,
8602 token_type return_type)
8603 {
8604 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8605 for (std::size_t i = 1; i < length; ++i)
8606 {
8607 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8608 {
8609 error_message = "invalid literal";
8610 return token_type::parse_error;
8611 }
8612 }
8613 return return_type;
8614 }
8615
8617 // input management
8619
8621 void reset() noexcept
8622 {
8623 token_buffer.clear();
8624 token_string.clear();
8625 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8626 }
8627
8628 /*
8629 @brief get next character from the input
8630
8631 This function provides the interface to the used input adapter. It does
8632 not throw in case the input reached EOF, but returns a
8633 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8634 for use in error messages.
8635
8636 @return character read from the input
8637 */
8638 char_int_type get()
8639 {
8640 ++position.chars_read_total;
8641 ++position.chars_read_current_line;
8642
8643 if (next_unget)
8644 {
8645 // just reset the next_unget variable and work with current
8646 next_unget = false;
8647 }
8648 else
8649 {
8650 current = ia.get_character();
8651 }
8652
8653 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8654 {
8655 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8656 }
8657
8658 if (current == '\n')
8659 {
8660 ++position.lines_read;
8661 position.chars_read_current_line = 0;
8662 }
8663
8664 return current;
8665 }
8666
8675 void unget()
8676 {
8677 next_unget = true;
8678
8679 --position.chars_read_total;
8680
8681 // in case we "unget" a newline, we have to also decrement the lines_read
8682 if (position.chars_read_current_line == 0)
8683 {
8684 if (position.lines_read > 0)
8685 {
8686 --position.lines_read;
8687 }
8688 }
8689 else
8690 {
8691 --position.chars_read_current_line;
8692 }
8693
8694 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8695 {
8696 JSON_ASSERT(!token_string.empty());
8697 token_string.pop_back();
8698 }
8699 }
8700
8702 void add(char_int_type c)
8703 {
8704 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8705 }
8706
8707 public:
8709 // value getters
8711
8713 constexpr number_integer_t get_number_integer() const noexcept
8714 {
8715 return value_integer;
8716 }
8717
8719 constexpr number_unsigned_t get_number_unsigned() const noexcept
8720 {
8721 return value_unsigned;
8722 }
8723
8725 constexpr number_float_t get_number_float() const noexcept
8726 {
8727 return value_float;
8728 }
8729
8731 string_t& get_string()
8732 {
8733 return token_buffer;
8734 }
8735
8737 // diagnostics
8739
8741 constexpr position_t get_position() const noexcept
8742 {
8743 return position;
8744 }
8745
8749 std::string get_token_string() const
8750 {
8751 // escape control characters
8752 std::string result;
8753 for (const auto c : token_string)
8754 {
8755 if (static_cast<unsigned char>(c) <= '\x1F')
8756 {
8757 // escape control characters
8758 std::array<char, 9> cs{{}};
8759 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8760 result += cs.data();
8761 }
8762 else
8763 {
8764 // add character as is
8765 result.push_back(static_cast<std::string::value_type>(c));
8766 }
8767 }
8768
8769 return result;
8770 }
8771
8774 constexpr const char* get_error_message() const noexcept
8775 {
8776 return error_message;
8777 }
8778
8780 // actual scanner
8782
8788 {
8789 if (get() == 0xEF)
8790 {
8791 // check if we completely parse the BOM
8792 return get() == 0xBB && get() == 0xBF;
8793 }
8794
8795 // the first character is not the beginning of the BOM; unget it to
8796 // process is later
8797 unget();
8798 return true;
8799 }
8800
8802 {
8803 do
8804 {
8805 get();
8806 }
8807 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8808 }
8809
8811 {
8812 // initially, skip the BOM
8813 if (position.chars_read_total == 0 && !skip_bom())
8814 {
8815 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8816 return token_type::parse_error;
8817 }
8818
8819 // read next character and ignore whitespace
8820 skip_whitespace();
8821
8822 // ignore comments
8823 while (ignore_comments && current == '/')
8824 {
8825 if (!scan_comment())
8826 {
8827 return token_type::parse_error;
8828 }
8829
8830 // skip following whitespace
8831 skip_whitespace();
8832 }
8833
8834 switch (current)
8835 {
8836 // structural characters
8837 case '[':
8838 return token_type::begin_array;
8839 case ']':
8840 return token_type::end_array;
8841 case '{':
8842 return token_type::begin_object;
8843 case '}':
8844 return token_type::end_object;
8845 case ':':
8846 return token_type::name_separator;
8847 case ',':
8848 return token_type::value_separator;
8849
8850 // literals
8851 case 't':
8852 {
8853 std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
8854 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8855 }
8856 case 'f':
8857 {
8858 std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
8859 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8860 }
8861 case 'n':
8862 {
8863 std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
8864 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8865 }
8866
8867 // string
8868 case '\"':
8869 return scan_string();
8870
8871 // number
8872 case '-':
8873 case '0':
8874 case '1':
8875 case '2':
8876 case '3':
8877 case '4':
8878 case '5':
8879 case '6':
8880 case '7':
8881 case '8':
8882 case '9':
8883 return scan_number();
8884
8885 // end of input (the null byte is needed when parsing from
8886 // string literals)
8887 case '\0':
8888 case std::char_traits<char_type>::eof():
8889 return token_type::end_of_input;
8890
8891 // error
8892 default:
8893 error_message = "invalid literal";
8894 return token_type::parse_error;
8895 }
8896 }
8897
8898 private:
8900 InputAdapterType ia;
8901
8903 const bool ignore_comments = false;
8904
8906 char_int_type current = std::char_traits<char_type>::eof();
8907
8909 bool next_unget = false;
8910
8912 position_t position {};
8913
8915 std::vector<char_type> token_string {};
8916
8918 string_t token_buffer {};
8919
8921 const char* error_message = "";
8922
8923 // number values
8924 number_integer_t value_integer = 0;
8925 number_unsigned_t value_unsigned = 0;
8926 number_float_t value_float = 0;
8927
8929 const char_int_type decimal_point_char = '.';
8930};
8931
8932} // namespace detail
8934
8935// #include <nlohmann/detail/macro_scope.hpp>
8936
8937// #include <nlohmann/detail/meta/is_sax.hpp>
8938// __ _____ _____ _____
8939// __| | __| | | | JSON for Modern C++
8940// | | |__ | | | | | | version 3.11.2
8941// |_____|_____|_____|_|___| https://github.com/nlohmann/json
8942//
8943// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
8944// SPDX-License-Identifier: MIT
8945
8946
8947
8948#include <cstdint> // size_t
8949#include <utility> // declval
8950#include <string> // string
8951
8952// #include <nlohmann/detail/abi_macros.hpp>
8953
8954// #include <nlohmann/detail/meta/detected.hpp>
8955
8956// #include <nlohmann/detail/meta/type_traits.hpp>
8957
8958
8960namespace detail
8961{
8962
8963template<typename T>
8964using null_function_t = decltype(std::declval<T&>().null());
8965
8966template<typename T>
8968 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8969
8970template<typename T, typename Integer>
8972 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8973
8974template<typename T, typename Unsigned>
8976 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8977
8978template<typename T, typename Float, typename String>
8979using number_float_function_t = decltype(std::declval<T&>().number_float(
8980 std::declval<Float>(), std::declval<const String&>()));
8981
8982template<typename T, typename String>
8984 decltype(std::declval<T&>().string(std::declval<String&>()));
8985
8986template<typename T, typename Binary>
8988 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8989
8990template<typename T>
8992 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8993
8994template<typename T, typename String>
8996 decltype(std::declval<T&>().key(std::declval<String&>()));
8997
8998template<typename T>
8999using end_object_function_t = decltype(std::declval<T&>().end_object());
9000
9001template<typename T>
9003 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9004
9005template<typename T>
9006using end_array_function_t = decltype(std::declval<T&>().end_array());
9007
9008template<typename T, typename Exception>
9009using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9010 std::declval<std::size_t>(), std::declval<const std::string&>(),
9011 std::declval<const Exception&>()));
9012
9013template<typename SAX, typename BasicJsonType>
9015{
9016 private:
9018 "BasicJsonType must be of type basic_json<...>");
9019
9020 using number_integer_t = typename BasicJsonType::number_integer_t;
9021 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9022 using number_float_t = typename BasicJsonType::number_float_t;
9023 using string_t = typename BasicJsonType::string_t;
9024 using binary_t = typename BasicJsonType::binary_t;
9025 using exception_t = typename BasicJsonType::exception;
9026
9027 public:
9028 static constexpr bool value =
9042};
9043
9044template<typename SAX, typename BasicJsonType>
9046{
9047 private:
9049 "BasicJsonType must be of type basic_json<...>");
9050
9051 using number_integer_t = typename BasicJsonType::number_integer_t;
9052 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9053 using number_float_t = typename BasicJsonType::number_float_t;
9054 using string_t = typename BasicJsonType::string_t;
9055 using binary_t = typename BasicJsonType::binary_t;
9056 using exception_t = typename BasicJsonType::exception;
9057
9058 public:
9060 "Missing/invalid function: bool null()");
9062 "Missing/invalid function: bool boolean(bool)");
9064 "Missing/invalid function: bool boolean(bool)");
9065 static_assert(
9067 number_integer_t>::value,
9068 "Missing/invalid function: bool number_integer(number_integer_t)");
9069 static_assert(
9071 number_unsigned_t>::value,
9072 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9073 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9074 number_float_t, string_t>::value,
9075 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9076 static_assert(
9078 "Missing/invalid function: bool string(string_t&)");
9079 static_assert(
9081 "Missing/invalid function: bool binary(binary_t&)");
9083 "Missing/invalid function: bool start_object(std::size_t)");
9085 "Missing/invalid function: bool key(string_t&)");
9087 "Missing/invalid function: bool end_object()");
9089 "Missing/invalid function: bool start_array(std::size_t)");
9091 "Missing/invalid function: bool end_array()");
9092 static_assert(
9094 "Missing/invalid function: bool parse_error(std::size_t, const "
9095 "std::string&, const exception&)");
9096};
9097
9098} // namespace detail
9100
9101// #include <nlohmann/detail/meta/type_traits.hpp>
9102
9103// #include <nlohmann/detail/string_concat.hpp>
9104
9105// #include <nlohmann/detail/value_t.hpp>
9106
9107
9109namespace detail
9110{
9111
9114{
9115 error,
9116 ignore,
9117 store
9118};
9119
9127static inline bool little_endianness(int num = 1) noexcept
9128{
9129 return *reinterpret_cast<char*>(&num) == 1;
9130}
9131
9132
9134// binary reader //
9136
9140template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9142{
9143 using number_integer_t = typename BasicJsonType::number_integer_t;
9144 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9145 using number_float_t = typename BasicJsonType::number_float_t;
9146 using string_t = typename BasicJsonType::string_t;
9147 using binary_t = typename BasicJsonType::binary_t;
9148 using json_sax_t = SAX;
9149 using char_type = typename InputAdapterType::char_type;
9150 using char_int_type = typename std::char_traits<char_type>::int_type;
9151
9152 public:
9158 explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9159 {
9161 }
9162
9163 // make class move-only
9165 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9167 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9168 ~binary_reader() = default;
9169
9179 bool sax_parse(const input_format_t format,
9180 json_sax_t* sax_,
9181 const bool strict = true,
9182 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9183 {
9184 sax = sax_;
9185 bool result = false;
9186
9187 switch (format)
9188 {
9190 result = parse_bson_internal();
9191 break;
9192
9194 result = parse_cbor_internal(true, tag_handler);
9195 break;
9196
9198 result = parse_msgpack_internal();
9199 break;
9200
9203 result = parse_ubjson_internal();
9204 break;
9205
9206 case input_format_t::json: // LCOV_EXCL_LINE
9207 default: // LCOV_EXCL_LINE
9208 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9209 }
9210
9211 // strict mode: next byte must be EOF
9212 if (result && strict)
9213 {
9214 if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
9215 {
9216 get_ignore_noop();
9217 }
9218 else
9219 {
9220 get();
9221 }
9222
9223 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
9224 {
9225 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9226 exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9227 }
9228 }
9229
9230 return result;
9231 }
9232
9233 private:
9235 // BSON //
9237
9242 bool parse_bson_internal()
9243 {
9244 std::int32_t document_size{};
9245 get_number<std::int32_t, true>(input_format_t::bson, document_size);
9246
9247 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
9248 {
9249 return false;
9250 }
9251
9252 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9253 {
9254 return false;
9255 }
9256
9257 return sax->end_object();
9258 }
9259
9267 bool get_bson_cstr(string_t& result)
9268 {
9269 auto out = std::back_inserter(result);
9270 while (true)
9271 {
9272 get();
9273 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
9274 {
9275 return false;
9276 }
9277 if (current == 0x00)
9278 {
9279 return true;
9280 }
9281 *out++ = static_cast<typename string_t::value_type>(current);
9282 }
9283 }
9284
9296 template<typename NumberType>
9297 bool get_bson_string(const NumberType len, string_t& result)
9298 {
9299 if (JSON_HEDLEY_UNLIKELY(len < 1))
9300 {
9301 auto last_token = get_token_string();
9302 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9303 exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
9304 }
9305
9306 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
9307 }
9308
9318 template<typename NumberType>
9319 bool get_bson_binary(const NumberType len, binary_t& result)
9320 {
9321 if (JSON_HEDLEY_UNLIKELY(len < 0))
9322 {
9323 auto last_token = get_token_string();
9324 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9325 exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
9326 }
9327
9328 // All BSON binary values have a subtype
9329 std::uint8_t subtype{};
9330 get_number<std::uint8_t>(input_format_t::bson, subtype);
9331 result.set_subtype(subtype);
9332
9333 return get_binary(input_format_t::bson, len, result);
9334 }
9335
9346 bool parse_bson_element_internal(const char_int_type element_type,
9347 const std::size_t element_type_parse_position)
9348 {
9349 switch (element_type)
9350 {
9351 case 0x01: // double
9352 {
9353 double number{};
9354 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9355 }
9356
9357 case 0x02: // string
9358 {
9359 std::int32_t len{};
9360 string_t value;
9361 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
9362 }
9363
9364 case 0x03: // object
9365 {
9366 return parse_bson_internal();
9367 }
9368
9369 case 0x04: // array
9370 {
9371 return parse_bson_array();
9372 }
9373
9374 case 0x05: // binary
9375 {
9376 std::int32_t len{};
9377 binary_t value;
9378 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
9379 }
9380
9381 case 0x08: // boolean
9382 {
9383 return sax->boolean(get() != 0);
9384 }
9385
9386 case 0x0A: // null
9387 {
9388 return sax->null();
9389 }
9390
9391 case 0x10: // int32
9392 {
9393 std::int32_t value{};
9394 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9395 }
9396
9397 case 0x12: // int64
9398 {
9399 std::int64_t value{};
9400 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9401 }
9402
9403 default: // anything else not supported (yet)
9404 {
9405 std::array<char, 3> cr{{}};
9406 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9407 std::string cr_str{cr.data()};
9408 return sax->parse_error(element_type_parse_position, cr_str,
9409 parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9410 }
9411 }
9412 }
9413
9426 bool parse_bson_element_list(const bool is_array)
9427 {
9428 string_t key;
9429
9430 while (auto element_type = get())
9431 {
9432 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
9433 {
9434 return false;
9435 }
9436
9437 const std::size_t element_type_parse_position = chars_read;
9438 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
9439 {
9440 return false;
9441 }
9442
9443 if (!is_array && !sax->key(key))
9444 {
9445 return false;
9446 }
9447
9448 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9449 {
9450 return false;
9451 }
9452
9453 // get_bson_cstr only appends
9454 key.clear();
9455 }
9456
9457 return true;
9458 }
9459
9464 bool parse_bson_array()
9465 {
9466 std::int32_t document_size{};
9467 get_number<std::int32_t, true>(input_format_t::bson, document_size);
9468
9469 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9470 {
9471 return false;
9472 }
9473
9474 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9475 {
9476 return false;
9477 }
9478
9479 return sax->end_array();
9480 }
9481
9483 // CBOR //
9485
9494 bool parse_cbor_internal(const bool get_char,
9495 const cbor_tag_handler_t tag_handler)
9496 {
9497 switch (get_char ? get() : current)
9498 {
9499 // EOF
9500 case std::char_traits<char_type>::eof():
9501 return unexpect_eof(input_format_t::cbor, "value");
9502
9503 // Integer 0x00..0x17 (0..23)
9504 case 0x00:
9505 case 0x01:
9506 case 0x02:
9507 case 0x03:
9508 case 0x04:
9509 case 0x05:
9510 case 0x06:
9511 case 0x07:
9512 case 0x08:
9513 case 0x09:
9514 case 0x0A:
9515 case 0x0B:
9516 case 0x0C:
9517 case 0x0D:
9518 case 0x0E:
9519 case 0x0F:
9520 case 0x10:
9521 case 0x11:
9522 case 0x12:
9523 case 0x13:
9524 case 0x14:
9525 case 0x15:
9526 case 0x16:
9527 case 0x17:
9528 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9529
9530 case 0x18: // Unsigned integer (one-byte uint8_t follows)
9531 {
9532 std::uint8_t number{};
9533 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9534 }
9535
9536 case 0x19: // Unsigned integer (two-byte uint16_t follows)
9537 {
9538 std::uint16_t number{};
9539 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9540 }
9541
9542 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9543 {
9544 std::uint32_t number{};
9545 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9546 }
9547
9548 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9549 {
9550 std::uint64_t number{};
9551 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9552 }
9553
9554 // Negative integer -1-0x00..-1-0x17 (-1..-24)
9555 case 0x20:
9556 case 0x21:
9557 case 0x22:
9558 case 0x23:
9559 case 0x24:
9560 case 0x25:
9561 case 0x26:
9562 case 0x27:
9563 case 0x28:
9564 case 0x29:
9565 case 0x2A:
9566 case 0x2B:
9567 case 0x2C:
9568 case 0x2D:
9569 case 0x2E:
9570 case 0x2F:
9571 case 0x30:
9572 case 0x31:
9573 case 0x32:
9574 case 0x33:
9575 case 0x34:
9576 case 0x35:
9577 case 0x36:
9578 case 0x37:
9579 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9580
9581 case 0x38: // Negative integer (one-byte uint8_t follows)
9582 {
9583 std::uint8_t number{};
9584 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9585 }
9586
9587 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9588 {
9589 std::uint16_t number{};
9590 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9591 }
9592
9593 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9594 {
9595 std::uint32_t number{};
9596 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9597 }
9598
9599 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9600 {
9601 std::uint64_t number{};
9602 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9603 - static_cast<number_integer_t>(number));
9604 }
9605
9606 // Binary data (0x00..0x17 bytes follow)
9607 case 0x40:
9608 case 0x41:
9609 case 0x42:
9610 case 0x43:
9611 case 0x44:
9612 case 0x45:
9613 case 0x46:
9614 case 0x47:
9615 case 0x48:
9616 case 0x49:
9617 case 0x4A:
9618 case 0x4B:
9619 case 0x4C:
9620 case 0x4D:
9621 case 0x4E:
9622 case 0x4F:
9623 case 0x50:
9624 case 0x51:
9625 case 0x52:
9626 case 0x53:
9627 case 0x54:
9628 case 0x55:
9629 case 0x56:
9630 case 0x57:
9631 case 0x58: // Binary data (one-byte uint8_t for n follows)
9632 case 0x59: // Binary data (two-byte uint16_t for n follow)
9633 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9634 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9635 case 0x5F: // Binary data (indefinite length)
9636 {
9637 binary_t b;
9638 return get_cbor_binary(b) && sax->binary(b);
9639 }
9640
9641 // UTF-8 string (0x00..0x17 bytes follow)
9642 case 0x60:
9643 case 0x61:
9644 case 0x62:
9645 case 0x63:
9646 case 0x64:
9647 case 0x65:
9648 case 0x66:
9649 case 0x67:
9650 case 0x68:
9651 case 0x69:
9652 case 0x6A:
9653 case 0x6B:
9654 case 0x6C:
9655 case 0x6D:
9656 case 0x6E:
9657 case 0x6F:
9658 case 0x70:
9659 case 0x71:
9660 case 0x72:
9661 case 0x73:
9662 case 0x74:
9663 case 0x75:
9664 case 0x76:
9665 case 0x77:
9666 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9667 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9668 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9669 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9670 case 0x7F: // UTF-8 string (indefinite length)
9671 {
9672 string_t s;
9673 return get_cbor_string(s) && sax->string(s);
9674 }
9675
9676 // array (0x00..0x17 data items follow)
9677 case 0x80:
9678 case 0x81:
9679 case 0x82:
9680 case 0x83:
9681 case 0x84:
9682 case 0x85:
9683 case 0x86:
9684 case 0x87:
9685 case 0x88:
9686 case 0x89:
9687 case 0x8A:
9688 case 0x8B:
9689 case 0x8C:
9690 case 0x8D:
9691 case 0x8E:
9692 case 0x8F:
9693 case 0x90:
9694 case 0x91:
9695 case 0x92:
9696 case 0x93:
9697 case 0x94:
9698 case 0x95:
9699 case 0x96:
9700 case 0x97:
9701 return get_cbor_array(
9702 conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9703
9704 case 0x98: // array (one-byte uint8_t for n follows)
9705 {
9706 std::uint8_t len{};
9707 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9708 }
9709
9710 case 0x99: // array (two-byte uint16_t for n follow)
9711 {
9712 std::uint16_t len{};
9713 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9714 }
9715
9716 case 0x9A: // array (four-byte uint32_t for n follow)
9717 {
9718 std::uint32_t len{};
9719 return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9720 }
9721
9722 case 0x9B: // array (eight-byte uint64_t for n follow)
9723 {
9724 std::uint64_t len{};
9725 return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9726 }
9727
9728 case 0x9F: // array (indefinite length)
9729 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9730
9731 // map (0x00..0x17 pairs of data items follow)
9732 case 0xA0:
9733 case 0xA1:
9734 case 0xA2:
9735 case 0xA3:
9736 case 0xA4:
9737 case 0xA5:
9738 case 0xA6:
9739 case 0xA7:
9740 case 0xA8:
9741 case 0xA9:
9742 case 0xAA:
9743 case 0xAB:
9744 case 0xAC:
9745 case 0xAD:
9746 case 0xAE:
9747 case 0xAF:
9748 case 0xB0:
9749 case 0xB1:
9750 case 0xB2:
9751 case 0xB3:
9752 case 0xB4:
9753 case 0xB5:
9754 case 0xB6:
9755 case 0xB7:
9756 return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9757
9758 case 0xB8: // map (one-byte uint8_t for n follows)
9759 {
9760 std::uint8_t len{};
9761 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9762 }
9763
9764 case 0xB9: // map (two-byte uint16_t for n follow)
9765 {
9766 std::uint16_t len{};
9767 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9768 }
9769
9770 case 0xBA: // map (four-byte uint32_t for n follow)
9771 {
9772 std::uint32_t len{};
9773 return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9774 }
9775
9776 case 0xBB: // map (eight-byte uint64_t for n follow)
9777 {
9778 std::uint64_t len{};
9779 return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9780 }
9781
9782 case 0xBF: // map (indefinite length)
9783 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9784
9785 case 0xC6: // tagged item
9786 case 0xC7:
9787 case 0xC8:
9788 case 0xC9:
9789 case 0xCA:
9790 case 0xCB:
9791 case 0xCC:
9792 case 0xCD:
9793 case 0xCE:
9794 case 0xCF:
9795 case 0xD0:
9796 case 0xD1:
9797 case 0xD2:
9798 case 0xD3:
9799 case 0xD4:
9800 case 0xD8: // tagged item (1 bytes follow)
9801 case 0xD9: // tagged item (2 bytes follow)
9802 case 0xDA: // tagged item (4 bytes follow)
9803 case 0xDB: // tagged item (8 bytes follow)
9804 {
9805 switch (tag_handler)
9806 {
9808 {
9809 auto last_token = get_token_string();
9810 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9811 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9812 }
9813
9815 {
9816 // ignore binary subtype
9817 switch (current)
9818 {
9819 case 0xD8:
9820 {
9821 std::uint8_t subtype_to_ignore{};
9822 get_number(input_format_t::cbor, subtype_to_ignore);
9823 break;
9824 }
9825 case 0xD9:
9826 {
9827 std::uint16_t subtype_to_ignore{};
9828 get_number(input_format_t::cbor, subtype_to_ignore);
9829 break;
9830 }
9831 case 0xDA:
9832 {
9833 std::uint32_t subtype_to_ignore{};
9834 get_number(input_format_t::cbor, subtype_to_ignore);
9835 break;
9836 }
9837 case 0xDB:
9838 {
9839 std::uint64_t subtype_to_ignore{};
9840 get_number(input_format_t::cbor, subtype_to_ignore);
9841 break;
9842 }
9843 default:
9844 break;
9845 }
9846 return parse_cbor_internal(true, tag_handler);
9847 }
9848
9850 {
9851 binary_t b;
9852 // use binary subtype and store in binary container
9853 switch (current)
9854 {
9855 case 0xD8:
9856 {
9857 std::uint8_t subtype{};
9858 get_number(input_format_t::cbor, subtype);
9859 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9860 break;
9861 }
9862 case 0xD9:
9863 {
9864 std::uint16_t subtype{};
9865 get_number(input_format_t::cbor, subtype);
9866 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9867 break;
9868 }
9869 case 0xDA:
9870 {
9871 std::uint32_t subtype{};
9872 get_number(input_format_t::cbor, subtype);
9873 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9874 break;
9875 }
9876 case 0xDB:
9877 {
9878 std::uint64_t subtype{};
9879 get_number(input_format_t::cbor, subtype);
9880 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9881 break;
9882 }
9883 default:
9884 return parse_cbor_internal(true, tag_handler);
9885 }
9886 get();
9887 return get_cbor_binary(b) && sax->binary(b);
9888 }
9889
9890 default: // LCOV_EXCL_LINE
9891 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9892 return false; // LCOV_EXCL_LINE
9893 }
9894 }
9895
9896 case 0xF4: // false
9897 return sax->boolean(false);
9898
9899 case 0xF5: // true
9900 return sax->boolean(true);
9901
9902 case 0xF6: // null
9903 return sax->null();
9904
9905 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9906 {
9907 const auto byte1_raw = get();
9908 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9909 {
9910 return false;
9911 }
9912 const auto byte2_raw = get();
9913 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9914 {
9915 return false;
9916 }
9917
9918 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9919 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9920
9921 // code from RFC 7049, Appendix D, Figure 3:
9922 // As half-precision floating-point numbers were only added
9923 // to IEEE 754 in 2008, today's programming platforms often
9924 // still only have limited support for them. It is very
9925 // easy to include at least decoding support for them even
9926 // without such support. An example of a small decoder for
9927 // half-precision floating-point numbers in the C language
9928 // is shown in Fig. 3.
9929 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9930 const double val = [&half]
9931 {
9932 const int exp = (half >> 10u) & 0x1Fu;
9933 const unsigned int mant = half & 0x3FFu;
9934 JSON_ASSERT(0 <= exp&& exp <= 32);
9935 JSON_ASSERT(mant <= 1024);
9936 switch (exp)
9937 {
9938 case 0:
9939 return std::ldexp(mant, -24);
9940 case 31:
9941 return (mant == 0)
9942 ? std::numeric_limits<double>::infinity()
9943 : std::numeric_limits<double>::quiet_NaN();
9944 default:
9945 return std::ldexp(mant + 1024, exp - 25);
9946 }
9947 }();
9948 return sax->number_float((half & 0x8000u) != 0
9949 ? static_cast<number_float_t>(-val)
9950 : static_cast<number_float_t>(val), "");
9951 }
9952
9953 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9954 {
9955 float number{};
9956 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9957 }
9958
9959 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9960 {
9961 double number{};
9962 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9963 }
9964
9965 default: // anything else (0xFF is handled inside the other types)
9966 {
9967 auto last_token = get_token_string();
9968 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9969 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9970 }
9971 }
9972 }
9973
9985 bool get_cbor_string(string_t& result)
9986 {
9987 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9988 {
9989 return false;
9990 }
9991
9992 switch (current)
9993 {
9994 // UTF-8 string (0x00..0x17 bytes follow)
9995 case 0x60:
9996 case 0x61:
9997 case 0x62:
9998 case 0x63:
9999 case 0x64:
10000 case 0x65:
10001 case 0x66:
10002 case 0x67:
10003 case 0x68:
10004 case 0x69:
10005 case 0x6A:
10006 case 0x6B:
10007 case 0x6C:
10008 case 0x6D:
10009 case 0x6E:
10010 case 0x6F:
10011 case 0x70:
10012 case 0x71:
10013 case 0x72:
10014 case 0x73:
10015 case 0x74:
10016 case 0x75:
10017 case 0x76:
10018 case 0x77:
10019 {
10020 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10021 }
10022
10023 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10024 {
10025 std::uint8_t len{};
10026 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10027 }
10028
10029 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10030 {
10031 std::uint16_t len{};
10032 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10033 }
10034
10035 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10036 {
10037 std::uint32_t len{};
10038 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10039 }
10040
10041 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10042 {
10043 std::uint64_t len{};
10044 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10045 }
10046
10047 case 0x7F: // UTF-8 string (indefinite length)
10048 {
10049 while (get() != 0xFF)
10050 {
10051 string_t chunk;
10052 if (!get_cbor_string(chunk))
10053 {
10054 return false;
10055 }
10056 result.append(chunk);
10057 }
10058 return true;
10059 }
10060
10061 default:
10062 {
10063 auto last_token = get_token_string();
10064 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10065 exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10066 }
10067 }
10068 }
10069
10081 bool get_cbor_binary(binary_t& result)
10082 {
10083 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
10084 {
10085 return false;
10086 }
10087
10088 switch (current)
10089 {
10090 // Binary data (0x00..0x17 bytes follow)
10091 case 0x40:
10092 case 0x41:
10093 case 0x42:
10094 case 0x43:
10095 case 0x44:
10096 case 0x45:
10097 case 0x46:
10098 case 0x47:
10099 case 0x48:
10100 case 0x49:
10101 case 0x4A:
10102 case 0x4B:
10103 case 0x4C:
10104 case 0x4D:
10105 case 0x4E:
10106 case 0x4F:
10107 case 0x50:
10108 case 0x51:
10109 case 0x52:
10110 case 0x53:
10111 case 0x54:
10112 case 0x55:
10113 case 0x56:
10114 case 0x57:
10115 {
10116 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10117 }
10118
10119 case 0x58: // Binary data (one-byte uint8_t for n follows)
10120 {
10121 std::uint8_t len{};
10122 return get_number(input_format_t::cbor, len) &&
10123 get_binary(input_format_t::cbor, len, result);
10124 }
10125
10126 case 0x59: // Binary data (two-byte uint16_t for n follow)
10127 {
10128 std::uint16_t len{};
10129 return get_number(input_format_t::cbor, len) &&
10130 get_binary(input_format_t::cbor, len, result);
10131 }
10132
10133 case 0x5A: // Binary data (four-byte uint32_t for n follow)
10134 {
10135 std::uint32_t len{};
10136 return get_number(input_format_t::cbor, len) &&
10137 get_binary(input_format_t::cbor, len, result);
10138 }
10139
10140 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10141 {
10142 std::uint64_t len{};
10143 return get_number(input_format_t::cbor, len) &&
10144 get_binary(input_format_t::cbor, len, result);
10145 }
10146
10147 case 0x5F: // Binary data (indefinite length)
10148 {
10149 while (get() != 0xFF)
10150 {
10151 binary_t chunk;
10152 if (!get_cbor_binary(chunk))
10153 {
10154 return false;
10155 }
10156 result.insert(result.end(), chunk.begin(), chunk.end());
10157 }
10158 return true;
10159 }
10160
10161 default:
10162 {
10163 auto last_token = get_token_string();
10164 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10165 exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
10166 }
10167 }
10168 }
10169
10176 bool get_cbor_array(const std::size_t len,
10177 const cbor_tag_handler_t tag_handler)
10178 {
10179 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10180 {
10181 return false;
10182 }
10183
10184 if (len != static_cast<std::size_t>(-1))
10185 {
10186 for (std::size_t i = 0; i < len; ++i)
10187 {
10188 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10189 {
10190 return false;
10191 }
10192 }
10193 }
10194 else
10195 {
10196 while (get() != 0xFF)
10197 {
10198 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10199 {
10200 return false;
10201 }
10202 }
10203 }
10204
10205 return sax->end_array();
10206 }
10207
10214 bool get_cbor_object(const std::size_t len,
10215 const cbor_tag_handler_t tag_handler)
10216 {
10217 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10218 {
10219 return false;
10220 }
10221
10222 if (len != 0)
10223 {
10224 string_t key;
10225 if (len != static_cast<std::size_t>(-1))
10226 {
10227 for (std::size_t i = 0; i < len; ++i)
10228 {
10229 get();
10230 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10231 {
10232 return false;
10233 }
10234
10235 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10236 {
10237 return false;
10238 }
10239 key.clear();
10240 }
10241 }
10242 else
10243 {
10244 while (get() != 0xFF)
10245 {
10246 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
10247 {
10248 return false;
10249 }
10250
10251 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10252 {
10253 return false;
10254 }
10255 key.clear();
10256 }
10257 }
10258 }
10259
10260 return sax->end_object();
10261 }
10262
10264 // MsgPack //
10266
10270 bool parse_msgpack_internal()
10271 {
10272 switch (get())
10273 {
10274 // EOF
10275 case std::char_traits<char_type>::eof():
10276 return unexpect_eof(input_format_t::msgpack, "value");
10277
10278 // positive fixint
10279 case 0x00:
10280 case 0x01:
10281 case 0x02:
10282 case 0x03:
10283 case 0x04:
10284 case 0x05:
10285 case 0x06:
10286 case 0x07:
10287 case 0x08:
10288 case 0x09:
10289 case 0x0A:
10290 case 0x0B:
10291 case 0x0C:
10292 case 0x0D:
10293 case 0x0E:
10294 case 0x0F:
10295 case 0x10:
10296 case 0x11:
10297 case 0x12:
10298 case 0x13:
10299 case 0x14:
10300 case 0x15:
10301 case 0x16:
10302 case 0x17:
10303 case 0x18:
10304 case 0x19:
10305 case 0x1A:
10306 case 0x1B:
10307 case 0x1C:
10308 case 0x1D:
10309 case 0x1E:
10310 case 0x1F:
10311 case 0x20:
10312 case 0x21:
10313 case 0x22:
10314 case 0x23:
10315 case 0x24:
10316 case 0x25:
10317 case 0x26:
10318 case 0x27:
10319 case 0x28:
10320 case 0x29:
10321 case 0x2A:
10322 case 0x2B:
10323 case 0x2C:
10324 case 0x2D:
10325 case 0x2E:
10326 case 0x2F:
10327 case 0x30:
10328 case 0x31:
10329 case 0x32:
10330 case 0x33:
10331 case 0x34:
10332 case 0x35:
10333 case 0x36:
10334 case 0x37:
10335 case 0x38:
10336 case 0x39:
10337 case 0x3A:
10338 case 0x3B:
10339 case 0x3C:
10340 case 0x3D:
10341 case 0x3E:
10342 case 0x3F:
10343 case 0x40:
10344 case 0x41:
10345 case 0x42:
10346 case 0x43:
10347 case 0x44:
10348 case 0x45:
10349 case 0x46:
10350 case 0x47:
10351 case 0x48:
10352 case 0x49:
10353 case 0x4A:
10354 case 0x4B:
10355 case 0x4C:
10356 case 0x4D:
10357 case 0x4E:
10358 case 0x4F:
10359 case 0x50:
10360 case 0x51:
10361 case 0x52:
10362 case 0x53:
10363 case 0x54:
10364 case 0x55:
10365 case 0x56:
10366 case 0x57:
10367 case 0x58:
10368 case 0x59:
10369 case 0x5A:
10370 case 0x5B:
10371 case 0x5C:
10372 case 0x5D:
10373 case 0x5E:
10374 case 0x5F:
10375 case 0x60:
10376 case 0x61:
10377 case 0x62:
10378 case 0x63:
10379 case 0x64:
10380 case 0x65:
10381 case 0x66:
10382 case 0x67:
10383 case 0x68:
10384 case 0x69:
10385 case 0x6A:
10386 case 0x6B:
10387 case 0x6C:
10388 case 0x6D:
10389 case 0x6E:
10390 case 0x6F:
10391 case 0x70:
10392 case 0x71:
10393 case 0x72:
10394 case 0x73:
10395 case 0x74:
10396 case 0x75:
10397 case 0x76:
10398 case 0x77:
10399 case 0x78:
10400 case 0x79:
10401 case 0x7A:
10402 case 0x7B:
10403 case 0x7C:
10404 case 0x7D:
10405 case 0x7E:
10406 case 0x7F:
10407 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10408
10409 // fixmap
10410 case 0x80:
10411 case 0x81:
10412 case 0x82:
10413 case 0x83:
10414 case 0x84:
10415 case 0x85:
10416 case 0x86:
10417 case 0x87:
10418 case 0x88:
10419 case 0x89:
10420 case 0x8A:
10421 case 0x8B:
10422 case 0x8C:
10423 case 0x8D:
10424 case 0x8E:
10425 case 0x8F:
10426 return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10427
10428 // fixarray
10429 case 0x90:
10430 case 0x91:
10431 case 0x92:
10432 case 0x93:
10433 case 0x94:
10434 case 0x95:
10435 case 0x96:
10436 case 0x97:
10437 case 0x98:
10438 case 0x99:
10439 case 0x9A:
10440 case 0x9B:
10441 case 0x9C:
10442 case 0x9D:
10443 case 0x9E:
10444 case 0x9F:
10445 return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10446
10447 // fixstr
10448 case 0xA0:
10449 case 0xA1:
10450 case 0xA2:
10451 case 0xA3:
10452 case 0xA4:
10453 case 0xA5:
10454 case 0xA6:
10455 case 0xA7:
10456 case 0xA8:
10457 case 0xA9:
10458 case 0xAA:
10459 case 0xAB:
10460 case 0xAC:
10461 case 0xAD:
10462 case 0xAE:
10463 case 0xAF:
10464 case 0xB0:
10465 case 0xB1:
10466 case 0xB2:
10467 case 0xB3:
10468 case 0xB4:
10469 case 0xB5:
10470 case 0xB6:
10471 case 0xB7:
10472 case 0xB8:
10473 case 0xB9:
10474 case 0xBA:
10475 case 0xBB:
10476 case 0xBC:
10477 case 0xBD:
10478 case 0xBE:
10479 case 0xBF:
10480 case 0xD9: // str 8
10481 case 0xDA: // str 16
10482 case 0xDB: // str 32
10483 {
10484 string_t s;
10485 return get_msgpack_string(s) && sax->string(s);
10486 }
10487
10488 case 0xC0: // nil
10489 return sax->null();
10490
10491 case 0xC2: // false
10492 return sax->boolean(false);
10493
10494 case 0xC3: // true
10495 return sax->boolean(true);
10496
10497 case 0xC4: // bin 8
10498 case 0xC5: // bin 16
10499 case 0xC6: // bin 32
10500 case 0xC7: // ext 8
10501 case 0xC8: // ext 16
10502 case 0xC9: // ext 32
10503 case 0xD4: // fixext 1
10504 case 0xD5: // fixext 2
10505 case 0xD6: // fixext 4
10506 case 0xD7: // fixext 8
10507 case 0xD8: // fixext 16
10508 {
10509 binary_t b;
10510 return get_msgpack_binary(b) && sax->binary(b);
10511 }
10512
10513 case 0xCA: // float 32
10514 {
10515 float number{};
10516 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10517 }
10518
10519 case 0xCB: // float 64
10520 {
10521 double number{};
10522 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10523 }
10524
10525 case 0xCC: // uint 8
10526 {
10527 std::uint8_t number{};
10528 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10529 }
10530
10531 case 0xCD: // uint 16
10532 {
10533 std::uint16_t number{};
10534 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10535 }
10536
10537 case 0xCE: // uint 32
10538 {
10539 std::uint32_t number{};
10540 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10541 }
10542
10543 case 0xCF: // uint 64
10544 {
10545 std::uint64_t number{};
10546 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10547 }
10548
10549 case 0xD0: // int 8
10550 {
10551 std::int8_t number{};
10552 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10553 }
10554
10555 case 0xD1: // int 16
10556 {
10557 std::int16_t number{};
10558 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10559 }
10560
10561 case 0xD2: // int 32
10562 {
10563 std::int32_t number{};
10564 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10565 }
10566
10567 case 0xD3: // int 64
10568 {
10569 std::int64_t number{};
10570 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10571 }
10572
10573 case 0xDC: // array 16
10574 {
10575 std::uint16_t len{};
10576 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10577 }
10578
10579 case 0xDD: // array 32
10580 {
10581 std::uint32_t len{};
10582 return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
10583 }
10584
10585 case 0xDE: // map 16
10586 {
10587 std::uint16_t len{};
10588 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10589 }
10590
10591 case 0xDF: // map 32
10592 {
10593 std::uint32_t len{};
10594 return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
10595 }
10596
10597 // negative fixint
10598 case 0xE0:
10599 case 0xE1:
10600 case 0xE2:
10601 case 0xE3:
10602 case 0xE4:
10603 case 0xE5:
10604 case 0xE6:
10605 case 0xE7:
10606 case 0xE8:
10607 case 0xE9:
10608 case 0xEA:
10609 case 0xEB:
10610 case 0xEC:
10611 case 0xED:
10612 case 0xEE:
10613 case 0xEF:
10614 case 0xF0:
10615 case 0xF1:
10616 case 0xF2:
10617 case 0xF3:
10618 case 0xF4:
10619 case 0xF5:
10620 case 0xF6:
10621 case 0xF7:
10622 case 0xF8:
10623 case 0xF9:
10624 case 0xFA:
10625 case 0xFB:
10626 case 0xFC:
10627 case 0xFD:
10628 case 0xFE:
10629 case 0xFF:
10630 return sax->number_integer(static_cast<std::int8_t>(current));
10631
10632 default: // anything else
10633 {
10634 auto last_token = get_token_string();
10635 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10636 exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10637 }
10638 }
10639 }
10640
10651 bool get_msgpack_string(string_t& result)
10652 {
10653 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10654 {
10655 return false;
10656 }
10657
10658 switch (current)
10659 {
10660 // fixstr
10661 case 0xA0:
10662 case 0xA1:
10663 case 0xA2:
10664 case 0xA3:
10665 case 0xA4:
10666 case 0xA5:
10667 case 0xA6:
10668 case 0xA7:
10669 case 0xA8:
10670 case 0xA9:
10671 case 0xAA:
10672 case 0xAB:
10673 case 0xAC:
10674 case 0xAD:
10675 case 0xAE:
10676 case 0xAF:
10677 case 0xB0:
10678 case 0xB1:
10679 case 0xB2:
10680 case 0xB3:
10681 case 0xB4:
10682 case 0xB5:
10683 case 0xB6:
10684 case 0xB7:
10685 case 0xB8:
10686 case 0xB9:
10687 case 0xBA:
10688 case 0xBB:
10689 case 0xBC:
10690 case 0xBD:
10691 case 0xBE:
10692 case 0xBF:
10693 {
10694 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10695 }
10696
10697 case 0xD9: // str 8
10698 {
10699 std::uint8_t len{};
10700 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10701 }
10702
10703 case 0xDA: // str 16
10704 {
10705 std::uint16_t len{};
10706 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10707 }
10708
10709 case 0xDB: // str 32
10710 {
10711 std::uint32_t len{};
10712 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10713 }
10714
10715 default:
10716 {
10717 auto last_token = get_token_string();
10718 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10719 exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10720 }
10721 }
10722 }
10723
10734 bool get_msgpack_binary(binary_t& result)
10735 {
10736 // helper function to set the subtype
10737 auto assign_and_return_true = [&result](std::int8_t subtype)
10738 {
10739 result.set_subtype(static_cast<std::uint8_t>(subtype));
10740 return true;
10741 };
10742
10743 switch (current)
10744 {
10745 case 0xC4: // bin 8
10746 {
10747 std::uint8_t len{};
10748 return get_number(input_format_t::msgpack, len) &&
10749 get_binary(input_format_t::msgpack, len, result);
10750 }
10751
10752 case 0xC5: // bin 16
10753 {
10754 std::uint16_t len{};
10755 return get_number(input_format_t::msgpack, len) &&
10756 get_binary(input_format_t::msgpack, len, result);
10757 }
10758
10759 case 0xC6: // bin 32
10760 {
10761 std::uint32_t len{};
10762 return get_number(input_format_t::msgpack, len) &&
10763 get_binary(input_format_t::msgpack, len, result);
10764 }
10765
10766 case 0xC7: // ext 8
10767 {
10768 std::uint8_t len{};
10769 std::int8_t subtype{};
10770 return get_number(input_format_t::msgpack, len) &&
10771 get_number(input_format_t::msgpack, subtype) &&
10772 get_binary(input_format_t::msgpack, len, result) &&
10773 assign_and_return_true(subtype);
10774 }
10775
10776 case 0xC8: // ext 16
10777 {
10778 std::uint16_t len{};
10779 std::int8_t subtype{};
10780 return get_number(input_format_t::msgpack, len) &&
10781 get_number(input_format_t::msgpack, subtype) &&
10782 get_binary(input_format_t::msgpack, len, result) &&
10783 assign_and_return_true(subtype);
10784 }
10785
10786 case 0xC9: // ext 32
10787 {
10788 std::uint32_t len{};
10789 std::int8_t subtype{};
10790 return get_number(input_format_t::msgpack, len) &&
10791 get_number(input_format_t::msgpack, subtype) &&
10792 get_binary(input_format_t::msgpack, len, result) &&
10793 assign_and_return_true(subtype);
10794 }
10795
10796 case 0xD4: // fixext 1
10797 {
10798 std::int8_t subtype{};
10799 return get_number(input_format_t::msgpack, subtype) &&
10800 get_binary(input_format_t::msgpack, 1, result) &&
10801 assign_and_return_true(subtype);
10802 }
10803
10804 case 0xD5: // fixext 2
10805 {
10806 std::int8_t subtype{};
10807 return get_number(input_format_t::msgpack, subtype) &&
10808 get_binary(input_format_t::msgpack, 2, result) &&
10809 assign_and_return_true(subtype);
10810 }
10811
10812 case 0xD6: // fixext 4
10813 {
10814 std::int8_t subtype{};
10815 return get_number(input_format_t::msgpack, subtype) &&
10816 get_binary(input_format_t::msgpack, 4, result) &&
10817 assign_and_return_true(subtype);
10818 }
10819
10820 case 0xD7: // fixext 8
10821 {
10822 std::int8_t subtype{};
10823 return get_number(input_format_t::msgpack, subtype) &&
10824 get_binary(input_format_t::msgpack, 8, result) &&
10825 assign_and_return_true(subtype);
10826 }
10827
10828 case 0xD8: // fixext 16
10829 {
10830 std::int8_t subtype{};
10831 return get_number(input_format_t::msgpack, subtype) &&
10832 get_binary(input_format_t::msgpack, 16, result) &&
10833 assign_and_return_true(subtype);
10834 }
10835
10836 default: // LCOV_EXCL_LINE
10837 return false; // LCOV_EXCL_LINE
10838 }
10839 }
10840
10845 bool get_msgpack_array(const std::size_t len)
10846 {
10847 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10848 {
10849 return false;
10850 }
10851
10852 for (std::size_t i = 0; i < len; ++i)
10853 {
10854 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10855 {
10856 return false;
10857 }
10858 }
10859
10860 return sax->end_array();
10861 }
10862
10867 bool get_msgpack_object(const std::size_t len)
10868 {
10869 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10870 {
10871 return false;
10872 }
10873
10874 string_t key;
10875 for (std::size_t i = 0; i < len; ++i)
10876 {
10877 get();
10878 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10879 {
10880 return false;
10881 }
10882
10883 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10884 {
10885 return false;
10886 }
10887 key.clear();
10888 }
10889
10890 return sax->end_object();
10891 }
10892
10894 // UBJSON //
10896
10904 bool parse_ubjson_internal(const bool get_char = true)
10905 {
10906 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10907 }
10908
10923 bool get_ubjson_string(string_t& result, const bool get_char = true)
10924 {
10925 if (get_char)
10926 {
10927 get(); // TODO(niels): may we ignore N here?
10928 }
10929
10930 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10931 {
10932 return false;
10933 }
10934
10935 switch (current)
10936 {
10937 case 'U':
10938 {
10939 std::uint8_t len{};
10940 return get_number(input_format, len) && get_string(input_format, len, result);
10941 }
10942
10943 case 'i':
10944 {
10945 std::int8_t len{};
10946 return get_number(input_format, len) && get_string(input_format, len, result);
10947 }
10948
10949 case 'I':
10950 {
10951 std::int16_t len{};
10952 return get_number(input_format, len) && get_string(input_format, len, result);
10953 }
10954
10955 case 'l':
10956 {
10957 std::int32_t len{};
10958 return get_number(input_format, len) && get_string(input_format, len, result);
10959 }
10960
10961 case 'L':
10962 {
10963 std::int64_t len{};
10964 return get_number(input_format, len) && get_string(input_format, len, result);
10965 }
10966
10967 case 'u':
10968 {
10969 if (input_format != input_format_t::bjdata)
10970 {
10971 break;
10972 }
10973 std::uint16_t len{};
10974 return get_number(input_format, len) && get_string(input_format, len, result);
10975 }
10976
10977 case 'm':
10978 {
10979 if (input_format != input_format_t::bjdata)
10980 {
10981 break;
10982 }
10983 std::uint32_t len{};
10984 return get_number(input_format, len) && get_string(input_format, len, result);
10985 }
10986
10987 case 'M':
10988 {
10989 if (input_format != input_format_t::bjdata)
10990 {
10991 break;
10992 }
10993 std::uint64_t len{};
10994 return get_number(input_format, len) && get_string(input_format, len, result);
10995 }
10996
10997 default:
10998 break;
10999 }
11000 auto last_token = get_token_string();
11001 std::string message;
11002
11003 if (input_format != input_format_t::bjdata)
11004 {
11005 message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11006 }
11007 else
11008 {
11009 message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11010 }
11011 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11012 }
11013
11018 bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11019 {
11020 std::pair<std::size_t, char_int_type> size_and_type;
11021 size_t dimlen = 0;
11022 bool no_ndarray = true;
11023
11024 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11025 {
11026 return false;
11027 }
11028
11029 if (size_and_type.first != npos)
11030 {
11031 if (size_and_type.second != 0)
11032 {
11033 if (size_and_type.second != 'N')
11034 {
11035 for (std::size_t i = 0; i < size_and_type.first; ++i)
11036 {
11037 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11038 {
11039 return false;
11040 }
11041 dim.push_back(dimlen);
11042 }
11043 }
11044 }
11045 else
11046 {
11047 for (std::size_t i = 0; i < size_and_type.first; ++i)
11048 {
11049 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11050 {
11051 return false;
11052 }
11053 dim.push_back(dimlen);
11054 }
11055 }
11056 }
11057 else
11058 {
11059 while (current != ']')
11060 {
11061 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11062 {
11063 return false;
11064 }
11065 dim.push_back(dimlen);
11066 get_ignore_noop();
11067 }
11068 }
11069 return true;
11070 }
11071
11083 bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11084 {
11085 if (prefix == 0)
11086 {
11087 prefix = get_ignore_noop();
11088 }
11089
11090 switch (prefix)
11091 {
11092 case 'U':
11093 {
11094 std::uint8_t number{};
11095 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11096 {
11097 return false;
11098 }
11099 result = static_cast<std::size_t>(number);
11100 return true;
11101 }
11102
11103 case 'i':
11104 {
11105 std::int8_t number{};
11106 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11107 {
11108 return false;
11109 }
11110 if (number < 0)
11111 {
11112 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11113 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11114 }
11115 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11116 return true;
11117 }
11118
11119 case 'I':
11120 {
11121 std::int16_t number{};
11122 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11123 {
11124 return false;
11125 }
11126 if (number < 0)
11127 {
11128 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11129 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11130 }
11131 result = static_cast<std::size_t>(number);
11132 return true;
11133 }
11134
11135 case 'l':
11136 {
11137 std::int32_t number{};
11138 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11139 {
11140 return false;
11141 }
11142 if (number < 0)
11143 {
11144 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11145 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11146 }
11147 result = static_cast<std::size_t>(number);
11148 return true;
11149 }
11150
11151 case 'L':
11152 {
11153 std::int64_t number{};
11154 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11155 {
11156 return false;
11157 }
11158 if (number < 0)
11159 {
11160 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11161 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11162 }
11163 if (!value_in_range_of<std::size_t>(number))
11164 {
11165 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11166 exception_message(input_format, "integer value overflow", "size"), nullptr));
11167 }
11168 result = static_cast<std::size_t>(number);
11169 return true;
11170 }
11171
11172 case 'u':
11173 {
11174 if (input_format != input_format_t::bjdata)
11175 {
11176 break;
11177 }
11178 std::uint16_t number{};
11179 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11180 {
11181 return false;
11182 }
11183 result = static_cast<std::size_t>(number);
11184 return true;
11185 }
11186
11187 case 'm':
11188 {
11189 if (input_format != input_format_t::bjdata)
11190 {
11191 break;
11192 }
11193 std::uint32_t number{};
11194 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11195 {
11196 return false;
11197 }
11198 result = conditional_static_cast<std::size_t>(number);
11199 return true;
11200 }
11201
11202 case 'M':
11203 {
11204 if (input_format != input_format_t::bjdata)
11205 {
11206 break;
11207 }
11208 std::uint64_t number{};
11209 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
11210 {
11211 return false;
11212 }
11213 if (!value_in_range_of<std::size_t>(number))
11214 {
11215 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11216 exception_message(input_format, "integer value overflow", "size"), nullptr));
11217 }
11218 result = detail::conditional_static_cast<std::size_t>(number);
11219 return true;
11220 }
11221
11222 case '[':
11223 {
11224 if (input_format != input_format_t::bjdata)
11225 {
11226 break;
11227 }
11228 if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11229 {
11230 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimentional vector is not allowed", "size"), nullptr));
11231 }
11232 std::vector<size_t> dim;
11233 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
11234 {
11235 return false;
11236 }
11237 if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11238 {
11239 result = dim.at(dim.size() - 1);
11240 return true;
11241 }
11242 if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11243 {
11244 for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11245 {
11246 if ( i == 0 )
11247 {
11248 result = 0;
11249 return true;
11250 }
11251 }
11252
11253 string_t key = "_ArraySize_";
11254 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11255 {
11256 return false;
11257 }
11258 result = 1;
11259 for (auto i : dim)
11260 {
11261 result *= i;
11262 if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type()
11263 {
11264 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
11265 }
11266 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11267 {
11268 return false;
11269 }
11270 }
11271 is_ndarray = true;
11272 return sax->end_array();
11273 }
11274 result = 0;
11275 return true;
11276 }
11277
11278 default:
11279 break;
11280 }
11281 auto last_token = get_token_string();
11282 std::string message;
11283
11284 if (input_format != input_format_t::bjdata)
11285 {
11286 message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11287 }
11288 else
11289 {
11290 message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
11291 }
11292 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
11293 }
11294
11306 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
11307 {
11308 result.first = npos; // size
11309 result.second = 0; // type
11310 bool is_ndarray = false;
11311
11312 get_ignore_noop();
11313
11314 if (current == '$')
11315 {
11316 result.second = get(); // must not ignore 'N', because 'N' maybe the type
11317 if (input_format == input_format_t::bjdata
11318 && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
11319 {
11320 auto last_token = get_token_string();
11321 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11322 exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
11323 }
11324
11325 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
11326 {
11327 return false;
11328 }
11329
11330 get_ignore_noop();
11331 if (JSON_HEDLEY_UNLIKELY(current != '#'))
11332 {
11333 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
11334 {
11335 return false;
11336 }
11337 auto last_token = get_token_string();
11338 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11339 exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
11340 }
11341
11342 bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11343 if (input_format == input_format_t::bjdata && is_ndarray)
11344 {
11345 if (inside_ndarray)
11346 {
11347 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11348 exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
11349 }
11350 result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
11351 }
11352 return is_error;
11353 }
11354
11355 if (current == '#')
11356 {
11357 bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11358 if (input_format == input_format_t::bjdata && is_ndarray)
11359 {
11360 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11361 exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
11362 }
11363 return is_error;
11364 }
11365
11366 return true;
11367 }
11368
11373 bool get_ubjson_value(const char_int_type prefix)
11374 {
11375 switch (prefix)
11376 {
11377 case std::char_traits<char_type>::eof(): // EOF
11378 return unexpect_eof(input_format, "value");
11379
11380 case 'T': // true
11381 return sax->boolean(true);
11382 case 'F': // false
11383 return sax->boolean(false);
11384
11385 case 'Z': // null
11386 return sax->null();
11387
11388 case 'U':
11389 {
11390 std::uint8_t number{};
11391 return get_number(input_format, number) && sax->number_unsigned(number);
11392 }
11393
11394 case 'i':
11395 {
11396 std::int8_t number{};
11397 return get_number(input_format, number) && sax->number_integer(number);
11398 }
11399
11400 case 'I':
11401 {
11402 std::int16_t number{};
11403 return get_number(input_format, number) && sax->number_integer(number);
11404 }
11405
11406 case 'l':
11407 {
11408 std::int32_t number{};
11409 return get_number(input_format, number) && sax->number_integer(number);
11410 }
11411
11412 case 'L':
11413 {
11414 std::int64_t number{};
11415 return get_number(input_format, number) && sax->number_integer(number);
11416 }
11417
11418 case 'u':
11419 {
11420 if (input_format != input_format_t::bjdata)
11421 {
11422 break;
11423 }
11424 std::uint16_t number{};
11425 return get_number(input_format, number) && sax->number_unsigned(number);
11426 }
11427
11428 case 'm':
11429 {
11430 if (input_format != input_format_t::bjdata)
11431 {
11432 break;
11433 }
11434 std::uint32_t number{};
11435 return get_number(input_format, number) && sax->number_unsigned(number);
11436 }
11437
11438 case 'M':
11439 {
11440 if (input_format != input_format_t::bjdata)
11441 {
11442 break;
11443 }
11444 std::uint64_t number{};
11445 return get_number(input_format, number) && sax->number_unsigned(number);
11446 }
11447
11448 case 'h':
11449 {
11450 if (input_format != input_format_t::bjdata)
11451 {
11452 break;
11453 }
11454 const auto byte1_raw = get();
11455 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11456 {
11457 return false;
11458 }
11459 const auto byte2_raw = get();
11460 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11461 {
11462 return false;
11463 }
11464
11465 const auto byte1 = static_cast<unsigned char>(byte1_raw);
11466 const auto byte2 = static_cast<unsigned char>(byte2_raw);
11467
11468 // code from RFC 7049, Appendix D, Figure 3:
11469 // As half-precision floating-point numbers were only added
11470 // to IEEE 754 in 2008, today's programming platforms often
11471 // still only have limited support for them. It is very
11472 // easy to include at least decoding support for them even
11473 // without such support. An example of a small decoder for
11474 // half-precision floating-point numbers in the C language
11475 // is shown in Fig. 3.
11476 const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11477 const double val = [&half]
11478 {
11479 const int exp = (half >> 10u) & 0x1Fu;
11480 const unsigned int mant = half & 0x3FFu;
11481 JSON_ASSERT(0 <= exp&& exp <= 32);
11482 JSON_ASSERT(mant <= 1024);
11483 switch (exp)
11484 {
11485 case 0:
11486 return std::ldexp(mant, -24);
11487 case 31:
11488 return (mant == 0)
11489 ? std::numeric_limits<double>::infinity()
11490 : std::numeric_limits<double>::quiet_NaN();
11491 default:
11492 return std::ldexp(mant + 1024, exp - 25);
11493 }
11494 }();
11495 return sax->number_float((half & 0x8000u) != 0
11496 ? static_cast<number_float_t>(-val)
11497 : static_cast<number_float_t>(val), "");
11498 }
11499
11500 case 'd':
11501 {
11502 float number{};
11503 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11504 }
11505
11506 case 'D':
11507 {
11508 double number{};
11509 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11510 }
11511
11512 case 'H':
11513 {
11514 return get_ubjson_high_precision_number();
11515 }
11516
11517 case 'C': // char
11518 {
11519 get();
11520 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11521 {
11522 return false;
11523 }
11524 if (JSON_HEDLEY_UNLIKELY(current > 127))
11525 {
11526 auto last_token = get_token_string();
11527 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11528 exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11529 }
11530 string_t s(1, static_cast<typename string_t::value_type>(current));
11531 return sax->string(s);
11532 }
11533
11534 case 'S': // string
11535 {
11536 string_t s;
11537 return get_ubjson_string(s) && sax->string(s);
11538 }
11539
11540 case '[': // array
11541 return get_ubjson_array();
11542
11543 case '{': // object
11544 return get_ubjson_object();
11545
11546 default: // anything else
11547 break;
11548 }
11549 auto last_token = get_token_string();
11550 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
11551 }
11552
11556 bool get_ubjson_array()
11557 {
11558 std::pair<std::size_t, char_int_type> size_and_type;
11559 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11560 {
11561 return false;
11562 }
11563
11564 // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
11565 // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11566
11567 if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11568 {
11569 size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
11570 auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type & p, char_int_type t)
11571 {
11572 return p.first < t;
11573 });
11574 string_t key = "_ArrayType_";
11575 if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
11576 {
11577 auto last_token = get_token_string();
11578 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11579 exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11580 }
11581
11582 string_t type = it->second; // sax->string() takes a reference
11583 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
11584 {
11585 return false;
11586 }
11587
11588 if (size_and_type.second == 'C')
11589 {
11590 size_and_type.second = 'U';
11591 }
11592
11593 key = "_ArrayData_";
11594 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
11595 {
11596 return false;
11597 }
11598
11599 for (std::size_t i = 0; i < size_and_type.first; ++i)
11600 {
11601 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11602 {
11603 return false;
11604 }
11605 }
11606
11607 return (sax->end_array() && sax->end_object());
11608 }
11609
11610 if (size_and_type.first != npos)
11611 {
11612 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11613 {
11614 return false;
11615 }
11616
11617 if (size_and_type.second != 0)
11618 {
11619 if (size_and_type.second != 'N')
11620 {
11621 for (std::size_t i = 0; i < size_and_type.first; ++i)
11622 {
11623 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11624 {
11625 return false;
11626 }
11627 }
11628 }
11629 }
11630 else
11631 {
11632 for (std::size_t i = 0; i < size_and_type.first; ++i)
11633 {
11634 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11635 {
11636 return false;
11637 }
11638 }
11639 }
11640 }
11641 else
11642 {
11643 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11644 {
11645 return false;
11646 }
11647
11648 while (current != ']')
11649 {
11650 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11651 {
11652 return false;
11653 }
11654 get_ignore_noop();
11655 }
11656 }
11657
11658 return sax->end_array();
11659 }
11660
11664 bool get_ubjson_object()
11665 {
11666 std::pair<std::size_t, char_int_type> size_and_type;
11667 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11668 {
11669 return false;
11670 }
11671
11672 // do not accept ND-array size in objects in BJData
11673 if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11674 {
11675 auto last_token = get_token_string();
11676 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11677 exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11678 }
11679
11680 string_t key;
11681 if (size_and_type.first != npos)
11682 {
11683 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11684 {
11685 return false;
11686 }
11687
11688 if (size_and_type.second != 0)
11689 {
11690 for (std::size_t i = 0; i < size_and_type.first; ++i)
11691 {
11692 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11693 {
11694 return false;
11695 }
11696 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11697 {
11698 return false;
11699 }
11700 key.clear();
11701 }
11702 }
11703 else
11704 {
11705 for (std::size_t i = 0; i < size_and_type.first; ++i)
11706 {
11707 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11708 {
11709 return false;
11710 }
11711 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11712 {
11713 return false;
11714 }
11715 key.clear();
11716 }
11717 }
11718 }
11719 else
11720 {
11721 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11722 {
11723 return false;
11724 }
11725
11726 while (current != '}')
11727 {
11728 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11729 {
11730 return false;
11731 }
11732 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11733 {
11734 return false;
11735 }
11736 get_ignore_noop();
11737 key.clear();
11738 }
11739 }
11740
11741 return sax->end_object();
11742 }
11743
11744 // Note, no reader for UBJSON binary types is implemented because they do
11745 // not exist
11746
11747 bool get_ubjson_high_precision_number()
11748 {
11749 // get size of following number string
11750 std::size_t size{};
11751 bool no_ndarray = true;
11752 auto res = get_ubjson_size_value(size, no_ndarray);
11753 if (JSON_HEDLEY_UNLIKELY(!res))
11754 {
11755 return res;
11756 }
11757
11758 // get number string
11759 std::vector<char> number_vector;
11760 for (std::size_t i = 0; i < size; ++i)
11761 {
11762 get();
11763 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11764 {
11765 return false;
11766 }
11767 number_vector.push_back(static_cast<char>(current));
11768 }
11769
11770 // parse number string
11771 using ia_type = decltype(detail::input_adapter(number_vector));
11772 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11773 const auto result_number = number_lexer.scan();
11774 const auto number_string = number_lexer.get_token_string();
11775 const auto result_remainder = number_lexer.scan();
11776
11777 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11778
11779 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11780 {
11781 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11782 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11783 }
11784
11785 switch (result_number)
11786 {
11787 case token_type::value_integer:
11788 return sax->number_integer(number_lexer.get_number_integer());
11789 case token_type::value_unsigned:
11790 return sax->number_unsigned(number_lexer.get_number_unsigned());
11791 case token_type::value_float:
11792 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11793 case token_type::uninitialized:
11794 case token_type::literal_true:
11795 case token_type::literal_false:
11796 case token_type::literal_null:
11797 case token_type::value_string:
11798 case token_type::begin_array:
11799 case token_type::begin_object:
11800 case token_type::end_array:
11801 case token_type::end_object:
11802 case token_type::name_separator:
11803 case token_type::value_separator:
11804 case token_type::parse_error:
11805 case token_type::end_of_input:
11806 case token_type::literal_or_value:
11807 default:
11808 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11809 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11810 }
11811 }
11812
11814 // Utility functions //
11816
11826 char_int_type get()
11827 {
11828 ++chars_read;
11829 return current = ia.get_character();
11830 }
11831
11835 char_int_type get_ignore_noop()
11836 {
11837 do
11838 {
11839 get();
11840 }
11841 while (current == 'N');
11842
11843 return current;
11844 }
11845
11846 /*
11847 @brief read a number from the input
11848
11849 @tparam NumberType the type of the number
11850 @param[in] format the current format (for diagnostics)
11851 @param[out] result number of type @a NumberType
11852
11853 @return whether conversion completed
11854
11855 @note This function needs to respect the system's endianness, because
11856 bytes in CBOR, MessagePack, and UBJSON are stored in network order
11857 (big endian) and therefore need reordering on little endian systems.
11858 On the other hand, BSON and BJData use little endian and should reorder
11859 on big endian systems.
11860 */
11861 template<typename NumberType, bool InputIsLittleEndian = false>
11862 bool get_number(const input_format_t format, NumberType& result)
11863 {
11864 // step 1: read input into array with system's byte order
11865 std::array<std::uint8_t, sizeof(NumberType)> vec{};
11866 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11867 {
11868 get();
11869 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11870 {
11871 return false;
11872 }
11873
11874 // reverse byte order prior to conversion if necessary
11875 if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11876 {
11877 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11878 }
11879 else
11880 {
11881 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11882 }
11883 }
11884
11885 // step 2: convert array into number of type T and return
11886 std::memcpy(&result, vec.data(), sizeof(NumberType));
11887 return true;
11888 }
11889
11904 template<typename NumberType>
11905 bool get_string(const input_format_t format,
11906 const NumberType len,
11907 string_t& result)
11908 {
11909 bool success = true;
11910 for (NumberType i = 0; i < len; i++)
11911 {
11912 get();
11913 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11914 {
11915 success = false;
11916 break;
11917 }
11918 result.push_back(static_cast<typename string_t::value_type>(current));
11919 }
11920 return success;
11921 }
11922
11937 template<typename NumberType>
11938 bool get_binary(const input_format_t format,
11939 const NumberType len,
11940 binary_t& result)
11941 {
11942 bool success = true;
11943 for (NumberType i = 0; i < len; i++)
11944 {
11945 get();
11946 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11947 {
11948 success = false;
11949 break;
11950 }
11951 result.push_back(static_cast<std::uint8_t>(current));
11952 }
11953 return success;
11954 }
11955
11962 bool unexpect_eof(const input_format_t format, const char* context) const
11963 {
11964 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11965 {
11966 return sax->parse_error(chars_read, "<end of file>",
11967 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11968 }
11969 return true;
11970 }
11971
11975 std::string get_token_string() const
11976 {
11977 std::array<char, 3> cr{{}};
11978 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11979 return std::string{cr.data()};
11980 }
11981
11988 std::string exception_message(const input_format_t format,
11989 const std::string& detail,
11990 const std::string& context) const
11991 {
11992 std::string error_msg = "syntax error while parsing ";
11993
11994 switch (format)
11995 {
11997 error_msg += "CBOR";
11998 break;
11999
12001 error_msg += "MessagePack";
12002 break;
12003
12005 error_msg += "UBJSON";
12006 break;
12007
12009 error_msg += "BSON";
12010 break;
12011
12013 error_msg += "BJData";
12014 break;
12015
12016 case input_format_t::json: // LCOV_EXCL_LINE
12017 default: // LCOV_EXCL_LINE
12018 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12019 }
12020
12021 return concat(error_msg, ' ', context, ": ", detail);
12022 }
12023
12024 private:
12025 static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1);
12026
12028 InputAdapterType ia;
12029
12031 char_int_type current = std::char_traits<char_type>::eof();
12032
12034 std::size_t chars_read = 0;
12035
12037 const bool is_little_endian = little_endianness();
12038
12040 const input_format_t input_format = input_format_t::json;
12041
12043 json_sax_t* sax = nullptr;
12044
12045 // excluded markers in bjdata optimized type
12046#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12047 make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12048
12049#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12050 make_array<bjd_type>( \
12051 bjd_type{'C', "char"}, \
12052 bjd_type{'D', "double"}, \
12053 bjd_type{'I', "int16"}, \
12054 bjd_type{'L', "int64"}, \
12055 bjd_type{'M', "uint64"}, \
12056 bjd_type{'U', "uint8"}, \
12057 bjd_type{'d', "single"}, \
12058 bjd_type{'i', "int8"}, \
12059 bjd_type{'l', "int32"}, \
12060 bjd_type{'m', "uint32"}, \
12061 bjd_type{'u', "uint16"})
12062
12064 // lookup tables
12065 // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12066 const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12068
12069 using bjd_type = std::pair<char_int_type, string_t>;
12070 // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12071 const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map =
12073
12074#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12075#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12076};
12077
12078#ifndef JSON_HAS_CPP_17
12079 template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12080 constexpr std::size_t binary_reader<BasicJsonType, InputAdapterType, SAX>::npos;
12081#endif
12082
12083} // namespace detail
12085
12086// #include <nlohmann/detail/input/input_adapters.hpp>
12087
12088// #include <nlohmann/detail/input/lexer.hpp>
12089
12090// #include <nlohmann/detail/input/parser.hpp>
12091// __ _____ _____ _____
12092// __| | __| | | | JSON for Modern C++
12093// | | |__ | | | | | | version 3.11.2
12094// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12095//
12096// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12097// SPDX-License-Identifier: MIT
12098
12099
12100
12101#include <cmath> // isfinite
12102#include <cstdint> // uint8_t
12103#include <functional> // function
12104#include <string> // string
12105#include <utility> // move
12106#include <vector> // vector
12107
12108// #include <nlohmann/detail/exceptions.hpp>
12109
12110// #include <nlohmann/detail/input/input_adapters.hpp>
12111
12112// #include <nlohmann/detail/input/json_sax.hpp>
12113
12114// #include <nlohmann/detail/input/lexer.hpp>
12115
12116// #include <nlohmann/detail/macro_scope.hpp>
12117
12118// #include <nlohmann/detail/meta/is_sax.hpp>
12119
12120// #include <nlohmann/detail/string_concat.hpp>
12121
12122// #include <nlohmann/detail/value_t.hpp>
12123
12124
12126namespace detail
12127{
12129// parser //
12131
12132enum class parse_event_t : std::uint8_t
12133{
12137 object_end,
12141 array_end,
12143 key,
12145 value
12146};
12147
12148template<typename BasicJsonType>
12150 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12151
12157template<typename BasicJsonType, typename InputAdapterType>
12159{
12160 using number_integer_t = typename BasicJsonType::number_integer_t;
12161 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12162 using number_float_t = typename BasicJsonType::number_float_t;
12163 using string_t = typename BasicJsonType::string_t;
12165 using token_type = typename lexer_t::token_type;
12166
12167 public:
12169 explicit parser(InputAdapterType&& adapter,
12170 const parser_callback_t<BasicJsonType> cb = nullptr,
12171 const bool allow_exceptions_ = true,
12172 const bool skip_comments = false)
12173 : callback(cb)
12174 , m_lexer(std::move(adapter), skip_comments)
12175 , allow_exceptions(allow_exceptions_)
12176 {
12177 // read first token
12178 get_token();
12179 }
12180
12191 void parse(const bool strict, BasicJsonType& result)
12192 {
12193 if (callback)
12194 {
12195 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
12196 sax_parse_internal(&sdp);
12197
12198 // in strict mode, input must be completely read
12199 if (strict && (get_token() != token_type::end_of_input))
12200 {
12201 sdp.parse_error(m_lexer.get_position(),
12202 m_lexer.get_token_string(),
12203 parse_error::create(101, m_lexer.get_position(),
12204 exception_message(token_type::end_of_input, "value"), nullptr));
12205 }
12206
12207 // in case of an error, return discarded value
12208 if (sdp.is_errored())
12209 {
12210 result = value_t::discarded;
12211 return;
12212 }
12213
12214 // set top-level value to null if it was discarded by the callback
12215 // function
12216 if (result.is_discarded())
12217 {
12218 result = nullptr;
12219 }
12220 }
12221 else
12222 {
12223 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
12224 sax_parse_internal(&sdp);
12225
12226 // in strict mode, input must be completely read
12227 if (strict && (get_token() != token_type::end_of_input))
12228 {
12229 sdp.parse_error(m_lexer.get_position(),
12230 m_lexer.get_token_string(),
12231 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12232 }
12233
12234 // in case of an error, return discarded value
12235 if (sdp.is_errored())
12236 {
12237 result = value_t::discarded;
12238 return;
12239 }
12240 }
12241
12242 result.assert_invariant();
12243 }
12244
12251 bool accept(const bool strict = true)
12252 {
12254 return sax_parse(&sax_acceptor, strict);
12255 }
12256
12257 template<typename SAX>
12259 bool sax_parse(SAX* sax, const bool strict = true)
12260 {
12262 const bool result = sax_parse_internal(sax);
12263
12264 // strict mode: next byte must be EOF
12265 if (result && strict && (get_token() != token_type::end_of_input))
12266 {
12267 return sax->parse_error(m_lexer.get_position(),
12268 m_lexer.get_token_string(),
12269 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12270 }
12271
12272 return result;
12273 }
12274
12275 private:
12276 template<typename SAX>
12278 bool sax_parse_internal(SAX* sax)
12279 {
12280 // stack to remember the hierarchy of structured values we are parsing
12281 // true = array; false = object
12282 std::vector<bool> states;
12283 // value to avoid a goto (see comment where set to true)
12284 bool skip_to_state_evaluation = false;
12285
12286 while (true)
12287 {
12288 if (!skip_to_state_evaluation)
12289 {
12290 // invariant: get_token() was called before each iteration
12291 switch (last_token)
12292 {
12293 case token_type::begin_object:
12294 {
12295 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
12296 {
12297 return false;
12298 }
12299
12300 // closing } -> we are done
12301 if (get_token() == token_type::end_object)
12302 {
12303 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12304 {
12305 return false;
12306 }
12307 break;
12308 }
12309
12310 // parse key
12311 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
12312 {
12313 return sax->parse_error(m_lexer.get_position(),
12314 m_lexer.get_token_string(),
12315 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12316 }
12317 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12318 {
12319 return false;
12320 }
12321
12322 // parse separator (:)
12323 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12324 {
12325 return sax->parse_error(m_lexer.get_position(),
12326 m_lexer.get_token_string(),
12327 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12328 }
12329
12330 // remember we are now inside an object
12331 states.push_back(false);
12332
12333 // parse values
12334 get_token();
12335 continue;
12336 }
12337
12338 case token_type::begin_array:
12339 {
12340 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
12341 {
12342 return false;
12343 }
12344
12345 // closing ] -> we are done
12346 if (get_token() == token_type::end_array)
12347 {
12348 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12349 {
12350 return false;
12351 }
12352 break;
12353 }
12354
12355 // remember we are now inside an array
12356 states.push_back(true);
12357
12358 // parse values (no need to call get_token)
12359 continue;
12360 }
12361
12362 case token_type::value_float:
12363 {
12364 const auto res = m_lexer.get_number_float();
12365
12366 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
12367 {
12368 return sax->parse_error(m_lexer.get_position(),
12369 m_lexer.get_token_string(),
12370 out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
12371 }
12372
12373 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
12374 {
12375 return false;
12376 }
12377
12378 break;
12379 }
12380
12381 case token_type::literal_false:
12382 {
12383 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
12384 {
12385 return false;
12386 }
12387 break;
12388 }
12389
12390 case token_type::literal_null:
12391 {
12392 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
12393 {
12394 return false;
12395 }
12396 break;
12397 }
12398
12399 case token_type::literal_true:
12400 {
12401 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
12402 {
12403 return false;
12404 }
12405 break;
12406 }
12407
12408 case token_type::value_integer:
12409 {
12410 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
12411 {
12412 return false;
12413 }
12414 break;
12415 }
12416
12417 case token_type::value_string:
12418 {
12419 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
12420 {
12421 return false;
12422 }
12423 break;
12424 }
12425
12426 case token_type::value_unsigned:
12427 {
12428 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12429 {
12430 return false;
12431 }
12432 break;
12433 }
12434
12435 case token_type::parse_error:
12436 {
12437 // using "uninitialized" to avoid "expected" message
12438 return sax->parse_error(m_lexer.get_position(),
12439 m_lexer.get_token_string(),
12440 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12441 }
12442
12443 case token_type::uninitialized:
12444 case token_type::end_array:
12445 case token_type::end_object:
12446 case token_type::name_separator:
12447 case token_type::value_separator:
12448 case token_type::end_of_input:
12449 case token_type::literal_or_value:
12450 default: // the last token was unexpected
12451 {
12452 return sax->parse_error(m_lexer.get_position(),
12453 m_lexer.get_token_string(),
12454 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12455 }
12456 }
12457 }
12458 else
12459 {
12460 skip_to_state_evaluation = false;
12461 }
12462
12463 // we reached this line after we successfully parsed a value
12464 if (states.empty())
12465 {
12466 // empty stack: we reached the end of the hierarchy: done
12467 return true;
12468 }
12469
12470 if (states.back()) // array
12471 {
12472 // comma -> next value
12473 if (get_token() == token_type::value_separator)
12474 {
12475 // parse a new value
12476 get_token();
12477 continue;
12478 }
12479
12480 // closing ]
12481 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12482 {
12483 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12484 {
12485 return false;
12486 }
12487
12488 // We are done with this array. Before we can parse a
12489 // new value, we need to evaluate the new state first.
12490 // By setting skip_to_state_evaluation to false, we
12491 // are effectively jumping to the beginning of this if.
12492 JSON_ASSERT(!states.empty());
12493 states.pop_back();
12494 skip_to_state_evaluation = true;
12495 continue;
12496 }
12497
12498 return sax->parse_error(m_lexer.get_position(),
12499 m_lexer.get_token_string(),
12500 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12501 }
12502
12503 // states.back() is false -> object
12504
12505 // comma -> next value
12506 if (get_token() == token_type::value_separator)
12507 {
12508 // parse key
12509 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
12510 {
12511 return sax->parse_error(m_lexer.get_position(),
12512 m_lexer.get_token_string(),
12513 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12514 }
12515
12516 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12517 {
12518 return false;
12519 }
12520
12521 // parse separator (:)
12522 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12523 {
12524 return sax->parse_error(m_lexer.get_position(),
12525 m_lexer.get_token_string(),
12526 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12527 }
12528
12529 // parse values
12530 get_token();
12531 continue;
12532 }
12533
12534 // closing }
12535 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12536 {
12537 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12538 {
12539 return false;
12540 }
12541
12542 // We are done with this object. Before we can parse a
12543 // new value, we need to evaluate the new state first.
12544 // By setting skip_to_state_evaluation to false, we
12545 // are effectively jumping to the beginning of this if.
12546 JSON_ASSERT(!states.empty());
12547 states.pop_back();
12548 skip_to_state_evaluation = true;
12549 continue;
12550 }
12551
12552 return sax->parse_error(m_lexer.get_position(),
12553 m_lexer.get_token_string(),
12554 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12555 }
12556 }
12557
12559 token_type get_token()
12560 {
12561 return last_token = m_lexer.scan();
12562 }
12563
12564 std::string exception_message(const token_type expected, const std::string& context)
12565 {
12566 std::string error_msg = "syntax error ";
12567
12568 if (!context.empty())
12569 {
12570 error_msg += concat("while parsing ", context, ' ');
12571 }
12572
12573 error_msg += "- ";
12574
12575 if (last_token == token_type::parse_error)
12576 {
12577 error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12578 m_lexer.get_token_string(), '\'');
12579 }
12580 else
12581 {
12582 error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12583 }
12584
12585 if (expected != token_type::uninitialized)
12586 {
12587 error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12588 }
12589
12590 return error_msg;
12591 }
12592
12593 private:
12595 const parser_callback_t<BasicJsonType> callback = nullptr;
12597 token_type last_token = token_type::uninitialized;
12599 lexer_t m_lexer;
12601 const bool allow_exceptions = true;
12602};
12603
12604} // namespace detail
12606
12607// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12608// __ _____ _____ _____
12609// __| | __| | | | JSON for Modern C++
12610// | | |__ | | | | | | version 3.11.2
12611// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12612//
12613// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12614// SPDX-License-Identifier: MIT
12615
12616
12617
12618// #include <nlohmann/detail/abi_macros.hpp>
12619
12620// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12621// __ _____ _____ _____
12622// __| | __| | | | JSON for Modern C++
12623// | | |__ | | | | | | version 3.11.2
12624// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12625//
12626// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12627// SPDX-License-Identifier: MIT
12628
12629
12630
12631#include <cstddef> // ptrdiff_t
12632#include <limits> // numeric_limits
12633
12634// #include <nlohmann/detail/macro_scope.hpp>
12635
12636
12638namespace detail
12639{
12640
12641/*
12642@brief an iterator for primitive JSON types
12643
12644This class models an iterator for primitive JSON types (boolean, number,
12645string). It's only purpose is to allow the iterator/const_iterator classes
12646to "iterate" over primitive values. Internally, the iterator is modeled by
12647a `difference_type` variable. Value begin_value (`0`) models the begin,
12648end_value (`1`) models past the end.
12649*/
12651{
12652 private:
12653 using difference_type = std::ptrdiff_t;
12654 static constexpr difference_type begin_value = 0;
12655 static constexpr difference_type end_value = begin_value + 1;
12656
12659 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12660
12661 public:
12662 constexpr difference_type get_value() const noexcept
12663 {
12664 return m_it;
12665 }
12666
12668 void set_begin() noexcept
12669 {
12670 m_it = begin_value;
12671 }
12672
12674 void set_end() noexcept
12675 {
12676 m_it = end_value;
12677 }
12678
12680 constexpr bool is_begin() const noexcept
12681 {
12682 return m_it == begin_value;
12683 }
12684
12686 constexpr bool is_end() const noexcept
12687 {
12688 return m_it == end_value;
12689 }
12690
12691 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12692 {
12693 return lhs.m_it == rhs.m_it;
12694 }
12695
12696 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12697 {
12698 return lhs.m_it < rhs.m_it;
12699 }
12700
12701 primitive_iterator_t operator+(difference_type n) noexcept
12702 {
12703 auto result = *this;
12704 result += n;
12705 return result;
12706 }
12707
12708 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12709 {
12710 return lhs.m_it - rhs.m_it;
12711 }
12712
12714 {
12715 ++m_it;
12716 return *this;
12717 }
12718
12719 primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
12720 {
12721 auto result = *this;
12722 ++m_it;
12723 return result;
12724 }
12725
12727 {
12728 --m_it;
12729 return *this;
12730 }
12731
12732 primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
12733 {
12734 auto result = *this;
12735 --m_it;
12736 return result;
12737 }
12738
12739 primitive_iterator_t& operator+=(difference_type n) noexcept
12740 {
12741 m_it += n;
12742 return *this;
12743 }
12744
12745 primitive_iterator_t& operator-=(difference_type n) noexcept
12746 {
12747 m_it -= n;
12748 return *this;
12749 }
12750};
12751
12752} // namespace detail
12754
12755
12757namespace detail
12758{
12759
12766template<typename BasicJsonType> struct internal_iterator
12767{
12769 typename BasicJsonType::object_t::iterator object_iterator {};
12771 typename BasicJsonType::array_t::iterator array_iterator {};
12774};
12775
12776} // namespace detail
12778
12779// #include <nlohmann/detail/iterators/iter_impl.hpp>
12780// __ _____ _____ _____
12781// __| | __| | | | JSON for Modern C++
12782// | | |__ | | | | | | version 3.11.2
12783// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12784//
12785// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
12786// SPDX-License-Identifier: MIT
12787
12788
12789
12790#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12791#include <type_traits> // conditional, is_const, remove_const
12792
12793// #include <nlohmann/detail/exceptions.hpp>
12794
12795// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12796
12797// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12798
12799// #include <nlohmann/detail/macro_scope.hpp>
12800
12801// #include <nlohmann/detail/meta/cpp_future.hpp>
12802
12803// #include <nlohmann/detail/meta/type_traits.hpp>
12804
12805// #include <nlohmann/detail/value_t.hpp>
12806
12807
12809namespace detail
12810{
12811
12812// forward declare, to be able to friend it later on
12813template<typename IteratorType> class iteration_proxy;
12814template<typename IteratorType> class iteration_proxy_value;
12815
12832template<typename BasicJsonType>
12833class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12834{
12836 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12838 friend other_iter_impl;
12839 friend BasicJsonType;
12842
12843 using object_t = typename BasicJsonType::object_t;
12844 using array_t = typename BasicJsonType::array_t;
12845 // make sure BasicJsonType is basic_json or const basic_json
12847 "iter_impl only accepts (const) basic_json");
12848 // superficial check for the LegacyBidirectionalIterator named requirement
12849 static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12850 && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12851 "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12852
12853 public:
12859 using iterator_category = std::bidirectional_iterator_tag;
12860
12862 using value_type = typename BasicJsonType::value_type;
12864 using difference_type = typename BasicJsonType::difference_type;
12866 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12867 typename BasicJsonType::const_pointer,
12868 typename BasicJsonType::pointer>::type;
12871 typename std::conditional<std::is_const<BasicJsonType>::value,
12872 typename BasicJsonType::const_reference,
12873 typename BasicJsonType::reference>::type;
12874
12875 iter_impl() = default;
12876 ~iter_impl() = default;
12877 iter_impl(iter_impl&&) noexcept = default;
12878 iter_impl& operator=(iter_impl&&) noexcept = default;
12879
12886 explicit iter_impl(pointer object) noexcept : m_object(object)
12887 {
12888 JSON_ASSERT(m_object != nullptr);
12889
12890 switch (m_object->m_type)
12891 {
12892 case value_t::object:
12893 {
12894 m_it.object_iterator = typename object_t::iterator();
12895 break;
12896 }
12897
12898 case value_t::array:
12899 {
12900 m_it.array_iterator = typename array_t::iterator();
12901 break;
12902 }
12903
12904 case value_t::null:
12905 case value_t::string:
12906 case value_t::boolean:
12910 case value_t::binary:
12911 case value_t::discarded:
12912 default:
12913 {
12915 break;
12916 }
12917 }
12918 }
12919
12937 : m_object(other.m_object), m_it(other.m_it)
12938 {}
12939
12947 {
12948 if (&other != this)
12949 {
12950 m_object = other.m_object;
12951 m_it = other.m_it;
12952 }
12953 return *this;
12954 }
12955
12961 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
12962 : m_object(other.m_object), m_it(other.m_it)
12963 {}
12964
12971 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12972 {
12973 m_object = other.m_object;
12974 m_it = other.m_it;
12975 return *this;
12976 }
12977
12983 void set_begin() noexcept
12984 {
12985 JSON_ASSERT(m_object != nullptr);
12986
12987 switch (m_object->m_type)
12988 {
12989 case value_t::object:
12990 {
12991 m_it.object_iterator = m_object->m_value.object->begin();
12992 break;
12993 }
12994
12995 case value_t::array:
12996 {
12997 m_it.array_iterator = m_object->m_value.array->begin();
12998 break;
12999 }
13000
13001 case value_t::null:
13002 {
13003 // set to end so begin()==end() is true: null is empty
13005 break;
13006 }
13007
13008 case value_t::string:
13009 case value_t::boolean:
13013 case value_t::binary:
13014 case value_t::discarded:
13015 default:
13016 {
13018 break;
13019 }
13020 }
13021 }
13022
13027 void set_end() noexcept
13028 {
13029 JSON_ASSERT(m_object != nullptr);
13030
13031 switch (m_object->m_type)
13032 {
13033 case value_t::object:
13034 {
13035 m_it.object_iterator = m_object->m_value.object->end();
13036 break;
13037 }
13038
13039 case value_t::array:
13040 {
13041 m_it.array_iterator = m_object->m_value.array->end();
13042 break;
13043 }
13044
13045 case value_t::null:
13046 case value_t::string:
13047 case value_t::boolean:
13051 case value_t::binary:
13052 case value_t::discarded:
13053 default:
13054 {
13056 break;
13057 }
13058 }
13059 }
13060
13061 public:
13067 {
13068 JSON_ASSERT(m_object != nullptr);
13069
13070 switch (m_object->m_type)
13071 {
13072 case value_t::object:
13073 {
13074 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
13075 return m_it.object_iterator->second;
13076 }
13077
13078 case value_t::array:
13079 {
13080 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
13081 return *m_it.array_iterator;
13082 }
13083
13084 case value_t::null:
13085 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13086
13087 case value_t::string:
13088 case value_t::boolean:
13092 case value_t::binary:
13093 case value_t::discarded:
13094 default:
13095 {
13097 {
13098 return *m_object;
13099 }
13100
13101 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13102 }
13103 }
13104 }
13105
13111 {
13112 JSON_ASSERT(m_object != nullptr);
13113
13114 switch (m_object->m_type)
13115 {
13116 case value_t::object:
13117 {
13118 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
13119 return &(m_it.object_iterator->second);
13120 }
13121
13122 case value_t::array:
13123 {
13124 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
13125 return &*m_it.array_iterator;
13126 }
13127
13128 case value_t::null:
13129 case value_t::string:
13130 case value_t::boolean:
13134 case value_t::binary:
13135 case value_t::discarded:
13136 default:
13137 {
13139 {
13140 return m_object;
13141 }
13142
13143 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13144 }
13145 }
13146 }
13147
13152 iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13153 {
13154 auto result = *this;
13155 ++(*this);
13156 return result;
13157 }
13158
13164 {
13165 JSON_ASSERT(m_object != nullptr);
13166
13167 switch (m_object->m_type)
13168 {
13169 case value_t::object:
13170 {
13171 std::advance(m_it.object_iterator, 1);
13172 break;
13173 }
13174
13175 case value_t::array:
13176 {
13177 std::advance(m_it.array_iterator, 1);
13178 break;
13179 }
13180
13181 case value_t::null:
13182 case value_t::string:
13183 case value_t::boolean:
13187 case value_t::binary:
13188 case value_t::discarded:
13189 default:
13190 {
13192 break;
13193 }
13194 }
13195
13196 return *this;
13197 }
13198
13203 iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13204 {
13205 auto result = *this;
13206 --(*this);
13207 return result;
13208 }
13209
13215 {
13216 JSON_ASSERT(m_object != nullptr);
13217
13218 switch (m_object->m_type)
13219 {
13220 case value_t::object:
13221 {
13222 std::advance(m_it.object_iterator, -1);
13223 break;
13224 }
13225
13226 case value_t::array:
13227 {
13228 std::advance(m_it.array_iterator, -1);
13229 break;
13230 }
13231
13232 case value_t::null:
13233 case value_t::string:
13234 case value_t::boolean:
13238 case value_t::binary:
13239 case value_t::discarded:
13240 default:
13241 {
13243 break;
13244 }
13245 }
13246
13247 return *this;
13248 }
13249
13254 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
13255 bool operator==(const IterImpl& other) const
13256 {
13257 // if objects are not the same, the comparison is undefined
13258 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13259 {
13260 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13261 }
13262
13263 JSON_ASSERT(m_object != nullptr);
13264
13265 switch (m_object->m_type)
13266 {
13267 case value_t::object:
13268 return (m_it.object_iterator == other.m_it.object_iterator);
13269
13270 case value_t::array:
13271 return (m_it.array_iterator == other.m_it.array_iterator);
13272
13273 case value_t::null:
13274 case value_t::string:
13275 case value_t::boolean:
13279 case value_t::binary:
13280 case value_t::discarded:
13281 default:
13282 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
13283 }
13284 }
13285
13290 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
13291 bool operator!=(const IterImpl& other) const
13292 {
13293 return !operator==(other);
13294 }
13295
13300 bool operator<(const iter_impl& other) const
13301 {
13302 // if objects are not the same, the comparison is undefined
13303 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13304 {
13305 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13306 }
13307
13308 JSON_ASSERT(m_object != nullptr);
13309
13310 switch (m_object->m_type)
13311 {
13312 case value_t::object:
13313 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
13314
13315 case value_t::array:
13316 return (m_it.array_iterator < other.m_it.array_iterator);
13317
13318 case value_t::null:
13319 case value_t::string:
13320 case value_t::boolean:
13324 case value_t::binary:
13325 case value_t::discarded:
13326 default:
13328 }
13329 }
13330
13335 bool operator<=(const iter_impl& other) const
13336 {
13337 return !other.operator < (*this);
13338 }
13339
13344 bool operator>(const iter_impl& other) const
13345 {
13346 return !operator<=(other);
13347 }
13348
13353 bool operator>=(const iter_impl& other) const
13354 {
13355 return !operator<(other);
13356 }
13357
13363 {
13364 JSON_ASSERT(m_object != nullptr);
13365
13366 switch (m_object->m_type)
13367 {
13368 case value_t::object:
13369 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13370
13371 case value_t::array:
13372 {
13373 std::advance(m_it.array_iterator, i);
13374 break;
13375 }
13376
13377 case value_t::null:
13378 case value_t::string:
13379 case value_t::boolean:
13383 case value_t::binary:
13384 case value_t::discarded:
13385 default:
13386 {
13388 break;
13389 }
13390 }
13391
13392 return *this;
13393 }
13394
13400 {
13401 return operator+=(-i);
13402 }
13403
13409 {
13410 auto result = *this;
13411 result += i;
13412 return result;
13413 }
13414
13420 {
13421 auto result = it;
13422 result += i;
13423 return result;
13424 }
13425
13431 {
13432 auto result = *this;
13433 result -= i;
13434 return result;
13435 }
13436
13442 {
13443 JSON_ASSERT(m_object != nullptr);
13444
13445 switch (m_object->m_type)
13446 {
13447 case value_t::object:
13448 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13449
13450 case value_t::array:
13451 return m_it.array_iterator - other.m_it.array_iterator;
13452
13453 case value_t::null:
13454 case value_t::string:
13455 case value_t::boolean:
13459 case value_t::binary:
13460 case value_t::discarded:
13461 default:
13463 }
13464 }
13465
13471 {
13472 JSON_ASSERT(m_object != nullptr);
13473
13474 switch (m_object->m_type)
13475 {
13476 case value_t::object:
13477 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13478
13479 case value_t::array:
13480 return *std::next(m_it.array_iterator, n);
13481
13482 case value_t::null:
13483 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13484
13485 case value_t::string:
13486 case value_t::boolean:
13490 case value_t::binary:
13491 case value_t::discarded:
13492 default:
13493 {
13495 {
13496 return *m_object;
13497 }
13498
13499 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13500 }
13501 }
13502 }
13503
13508 const typename object_t::key_type& key() const
13509 {
13510 JSON_ASSERT(m_object != nullptr);
13511
13512 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13513 {
13514 return m_it.object_iterator->first;
13515 }
13516
13517 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13518 }
13519
13525 {
13526 return operator*();
13527 }
13528
13531 pointer m_object = nullptr;
13534};
13535
13536} // namespace detail
13538
13539// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13540
13541// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13542// __ _____ _____ _____
13543// __| | __| | | | JSON for Modern C++
13544// | | |__ | | | | | | version 3.11.2
13545// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13546//
13547// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13548// SPDX-License-Identifier: MIT
13549
13550
13551
13552#include <cstddef> // ptrdiff_t
13553#include <iterator> // reverse_iterator
13554#include <utility> // declval
13555
13556// #include <nlohmann/detail/abi_macros.hpp>
13557
13558
13560namespace detail
13561{
13562
13564// reverse_iterator //
13566
13585template<typename Base>
13586class json_reverse_iterator : public std::reverse_iterator<Base>
13587{
13588 public:
13589 using difference_type = std::ptrdiff_t;
13591 using base_iterator = std::reverse_iterator<Base>;
13593 using reference = typename Base::reference;
13594
13596 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13597 : base_iterator(it) {}
13598
13600 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13601
13603 json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13604 {
13605 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13606 }
13607
13610 {
13611 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13612 }
13613
13615 json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13616 {
13617 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13618 }
13619
13622 {
13623 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13624 }
13625
13628 {
13629 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13630 }
13631
13634 {
13635 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13636 }
13637
13640 {
13641 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13642 }
13643
13646 {
13647 return base_iterator(*this) - base_iterator(other);
13648 }
13649
13652 {
13653 return *(this->operator+(n));
13654 }
13655
13657 auto key() const -> decltype(std::declval<Base>().key())
13658 {
13659 auto it = --this->base();
13660 return it.key();
13661 }
13662
13665 {
13666 auto it = --this->base();
13667 return it.operator * ();
13668 }
13669};
13670
13671} // namespace detail
13673
13674// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13675
13676// #include <nlohmann/detail/json_pointer.hpp>
13677// __ _____ _____ _____
13678// __| | __| | | | JSON for Modern C++
13679// | | |__ | | | | | | version 3.11.2
13680// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13681//
13682// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
13683// SPDX-License-Identifier: MIT
13684
13685
13686
13687#include <algorithm> // all_of
13688#include <cctype> // isdigit
13689#include <cerrno> // errno, ERANGE
13690#include <cstdlib> // strtoull
13691#ifndef JSON_NO_IO
13692 #include <iosfwd> // ostream
13693#endif // JSON_NO_IO
13694#include <limits> // max
13695#include <numeric> // accumulate
13696#include <string> // string
13697#include <utility> // move
13698#include <vector> // vector
13699
13700// #include <nlohmann/detail/exceptions.hpp>
13701
13702// #include <nlohmann/detail/macro_scope.hpp>
13703
13704// #include <nlohmann/detail/string_concat.hpp>
13705
13706// #include <nlohmann/detail/string_escape.hpp>
13707
13708// #include <nlohmann/detail/value_t.hpp>
13709
13710
13712
13715template<typename RefStringType>
13717{
13718 // allow basic_json to access private members
13720 friend class basic_json;
13721
13722 template<typename>
13723 friend class json_pointer;
13724
13725 template<typename T>
13726 struct string_t_helper
13727 {
13728 using type = T;
13729 };
13730
13732 struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
13733 {
13734 using type = StringType;
13735 };
13736
13737 public:
13738 // for backwards compatibility accept BasicJsonType
13739 using string_t = typename string_t_helper<RefStringType>::type;
13740
13743 explicit json_pointer(const string_t& s = "")
13744 : reference_tokens(split(s))
13745 {}
13746
13750 {
13751 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13752 string_t{},
13753 [](const string_t& a, const string_t& b)
13754 {
13755 return detail::concat(a, '/', detail::escape(b));
13756 });
13757 }
13758
13762 operator string_t() const
13763 {
13764 return to_string();
13765 }
13766
13767#ifndef JSON_NO_IO
13770 friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13771 {
13772 o << ptr.to_string();
13773 return o;
13774 }
13775#endif
13776
13780 {
13781 reference_tokens.insert(reference_tokens.end(),
13782 ptr.reference_tokens.begin(),
13783 ptr.reference_tokens.end());
13784 return *this;
13785 }
13786
13790 {
13791 push_back(std::move(token));
13792 return *this;
13793 }
13794
13797 json_pointer& operator/=(std::size_t array_idx)
13798 {
13799 return *this /= std::to_string(array_idx);
13800 }
13801
13805 const json_pointer& rhs)
13806 {
13807 return json_pointer(lhs) /= rhs;
13808 }
13809
13812 friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13813 {
13814 return json_pointer(lhs) /= std::move(token);
13815 }
13816
13819 friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13820 {
13821 return json_pointer(lhs) /= array_idx;
13822 }
13823
13827 {
13828 if (empty())
13829 {
13830 return *this;
13831 }
13832
13833 json_pointer res = *this;
13834 res.pop_back();
13835 return res;
13836 }
13837
13841 {
13843 {
13844 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13845 }
13846
13847 reference_tokens.pop_back();
13848 }
13849
13852 const string_t& back() const
13853 {
13855 {
13856 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13857 }
13858
13859 return reference_tokens.back();
13860 }
13861
13864 void push_back(const string_t& token)
13865 {
13866 reference_tokens.push_back(token);
13867 }
13868
13871 void push_back(string_t&& token)
13872 {
13873 reference_tokens.push_back(std::move(token));
13874 }
13875
13878 bool empty() const noexcept
13879 {
13880 return reference_tokens.empty();
13881 }
13882
13883 private:
13894 template<typename BasicJsonType>
13895 static typename BasicJsonType::size_type array_index(const string_t& s)
13896 {
13897 using size_type = typename BasicJsonType::size_type;
13898
13899 // error condition (cf. RFC 6901, Sect. 4)
13900 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13901 {
13902 JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13903 }
13904
13905 // error condition (cf. RFC 6901, Sect. 4)
13906 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13907 {
13908 JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13909 }
13910
13911 const char* p = s.c_str();
13912 char* p_end = nullptr;
13913 errno = 0; // strtoull doesn't reset errno
13914 unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13915 if (p == p_end // invalid input or empty string
13916 || errno == ERANGE // out of range
13917 || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13918 {
13919 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13920 }
13921
13922 // only triggered on special platforms (like 32bit), see also
13923 // https://github.com/nlohmann/json/pull/2203
13924 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13925 {
13926 JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13927 }
13928
13929 return static_cast<size_type>(res);
13930 }
13931
13933 json_pointer top() const
13934 {
13936 {
13937 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13938 }
13939
13940 json_pointer result = *this;
13941 result.reference_tokens = {reference_tokens[0]};
13942 return result;
13943 }
13944
13945 private:
13954 template<typename BasicJsonType>
13955 BasicJsonType& get_and_create(BasicJsonType& j) const
13956 {
13957 auto* result = &j;
13958
13959 // in case no reference tokens exist, return a reference to the JSON value
13960 // j which will be overwritten by a primitive value
13961 for (const auto& reference_token : reference_tokens)
13962 {
13963 switch (result->type())
13964 {
13966 {
13967 if (reference_token == "0")
13968 {
13969 // start a new array if reference token is 0
13970 result = &result->operator[](0);
13971 }
13972 else
13973 {
13974 // start a new object otherwise
13975 result = &result->operator[](reference_token);
13976 }
13977 break;
13978 }
13979
13981 {
13982 // create an entry in the object
13983 result = &result->operator[](reference_token);
13984 break;
13985 }
13986
13988 {
13989 // create an entry in the array
13990 result = &result->operator[](array_index<BasicJsonType>(reference_token));
13991 break;
13992 }
13993
13994 /*
13995 The following code is only reached if there exists a reference
13996 token _and_ the current value is primitive. In this case, we have
13997 an error situation, because primitive values may only occur as
13998 single value; that is, with an empty list of reference tokens.
13999 */
14007 default:
14008 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14009 }
14010 }
14011
14012 return *result;
14013 }
14014
14034 template<typename BasicJsonType>
14035 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14036 {
14037 for (const auto& reference_token : reference_tokens)
14038 {
14039 // convert null values to arrays or objects before continuing
14040 if (ptr->is_null())
14041 {
14042 // check if reference token is a number
14043 const bool nums =
14044 std::all_of(reference_token.begin(), reference_token.end(),
14045 [](const unsigned char x)
14046 {
14047 return std::isdigit(x);
14048 });
14049
14050 // change value to array for numbers or "-" or to object otherwise
14051 *ptr = (nums || reference_token == "-")
14054 }
14055
14056 switch (ptr->type())
14057 {
14059 {
14060 // use unchecked object access
14061 ptr = &ptr->operator[](reference_token);
14062 break;
14063 }
14064
14066 {
14067 if (reference_token == "-")
14068 {
14069 // explicitly treat "-" as index beyond the end
14070 ptr = &ptr->operator[](ptr->m_value.array->size());
14071 }
14072 else
14073 {
14074 // convert array index to number; unchecked access
14075 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14076 }
14077 break;
14078 }
14079
14088 default:
14089 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14090 }
14091 }
14092
14093 return *ptr;
14094 }
14095
14102 template<typename BasicJsonType>
14103 BasicJsonType& get_checked(BasicJsonType* ptr) const
14104 {
14105 for (const auto& reference_token : reference_tokens)
14106 {
14107 switch (ptr->type())
14108 {
14110 {
14111 // note: at performs range check
14112 ptr = &ptr->at(reference_token);
14113 break;
14114 }
14115
14117 {
14118 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14119 {
14120 // "-" always fails the range check
14122 "array index '-' (", std::to_string(ptr->m_value.array->size()),
14123 ") is out of range"), ptr));
14124 }
14125
14126 // note: at performs range check
14127 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14128 break;
14129 }
14130
14139 default:
14140 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14141 }
14142 }
14143
14144 return *ptr;
14145 }
14146
14160 template<typename BasicJsonType>
14161 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14162 {
14163 for (const auto& reference_token : reference_tokens)
14164 {
14165 switch (ptr->type())
14166 {
14168 {
14169 // use unchecked object access
14170 ptr = &ptr->operator[](reference_token);
14171 break;
14172 }
14173
14175 {
14176 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14177 {
14178 // "-" cannot be used for const access
14179 JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr));
14180 }
14181
14182 // use unchecked array access
14183 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14184 break;
14185 }
14186
14195 default:
14196 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14197 }
14198 }
14199
14200 return *ptr;
14201 }
14202
14209 template<typename BasicJsonType>
14210 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
14211 {
14212 for (const auto& reference_token : reference_tokens)
14213 {
14214 switch (ptr->type())
14215 {
14217 {
14218 // note: at performs range check
14219 ptr = &ptr->at(reference_token);
14220 break;
14221 }
14222
14224 {
14225 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14226 {
14227 // "-" always fails the range check
14229 "array index '-' (", std::to_string(ptr->m_value.array->size()),
14230 ") is out of range"), ptr));
14231 }
14232
14233 // note: at performs range check
14234 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14235 break;
14236 }
14237
14246 default:
14247 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14248 }
14249 }
14250
14251 return *ptr;
14252 }
14253
14258 template<typename BasicJsonType>
14259 bool contains(const BasicJsonType* ptr) const
14260 {
14261 for (const auto& reference_token : reference_tokens)
14262 {
14263 switch (ptr->type())
14264 {
14266 {
14267 if (!ptr->contains(reference_token))
14268 {
14269 // we did not find the key in the object
14270 return false;
14271 }
14272
14273 ptr = &ptr->operator[](reference_token);
14274 break;
14275 }
14276
14278 {
14279 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14280 {
14281 // "-" always fails the range check
14282 return false;
14283 }
14284 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
14285 {
14286 // invalid char
14287 return false;
14288 }
14289 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
14290 {
14291 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
14292 {
14293 // first char should be between '1' and '9'
14294 return false;
14295 }
14296 for (std::size_t i = 1; i < reference_token.size(); i++)
14297 {
14298 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
14299 {
14300 // other char should be between '0' and '9'
14301 return false;
14302 }
14303 }
14304 }
14305
14306 const auto idx = array_index<BasicJsonType>(reference_token);
14307 if (idx >= ptr->size())
14308 {
14309 // index out of range
14310 return false;
14311 }
14312
14313 ptr = &ptr->operator[](idx);
14314 break;
14315 }
14316
14325 default:
14326 {
14327 // we do not expect primitive values if there is still a
14328 // reference token to process
14329 return false;
14330 }
14331 }
14332 }
14333
14334 // no reference token left means we found a primitive value
14335 return true;
14336 }
14337
14347 static std::vector<string_t> split(const string_t& reference_string)
14348 {
14349 std::vector<string_t> result;
14350
14351 // special case: empty reference string -> no reference tokens
14352 if (reference_string.empty())
14353 {
14354 return result;
14355 }
14356
14357 // check if nonempty reference string begins with slash
14358 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
14359 {
14360 JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
14361 }
14362
14363 // extract the reference tokens:
14364 // - slash: position of the last read slash (or end of string)
14365 // - start: position after the previous slash
14366 for (
14367 // search for the first slash after the first character
14368 std::size_t slash = reference_string.find_first_of('/', 1),
14369 // set the beginning of the first reference token
14370 start = 1;
14371 // we can stop if start == 0 (if slash == string_t::npos)
14372 start != 0;
14373 // set the beginning of the next reference token
14374 // (will eventually be 0 if slash == string_t::npos)
14375 start = (slash == string_t::npos) ? 0 : slash + 1,
14376 // find next slash
14377 slash = reference_string.find_first_of('/', start))
14378 {
14379 // use the text between the beginning of the reference token
14380 // (start) and the last slash (slash).
14381 auto reference_token = reference_string.substr(start, slash - start);
14382
14383 // check reference tokens are properly escaped
14384 for (std::size_t pos = reference_token.find_first_of('~');
14385 pos != string_t::npos;
14386 pos = reference_token.find_first_of('~', pos + 1))
14387 {
14388 JSON_ASSERT(reference_token[pos] == '~');
14389
14390 // ~ must be followed by 0 or 1
14391 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
14392 (reference_token[pos + 1] != '0' &&
14393 reference_token[pos + 1] != '1')))
14394 {
14395 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
14396 }
14397 }
14398
14399 // finally, store the reference token
14400 detail::unescape(reference_token);
14401 result.push_back(reference_token);
14402 }
14403
14404 return result;
14405 }
14406
14407 private:
14415 template<typename BasicJsonType>
14416 static void flatten(const string_t& reference_string,
14417 const BasicJsonType& value,
14418 BasicJsonType& result)
14419 {
14420 switch (value.type())
14421 {
14423 {
14424 if (value.m_value.array->empty())
14425 {
14426 // flatten empty array as null
14427 result[reference_string] = nullptr;
14428 }
14429 else
14430 {
14431 // iterate array and use index as reference string
14432 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
14433 {
14434 flatten(detail::concat(reference_string, '/', std::to_string(i)),
14435 value.m_value.array->operator[](i), result);
14436 }
14437 }
14438 break;
14439 }
14440
14442 {
14443 if (value.m_value.object->empty())
14444 {
14445 // flatten empty object as null
14446 result[reference_string] = nullptr;
14447 }
14448 else
14449 {
14450 // iterate object and use keys as reference string
14451 for (const auto& element : *value.m_value.object)
14452 {
14453 flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
14454 }
14455 }
14456 break;
14457 }
14458
14467 default:
14468 {
14469 // add primitive value with its reference string
14470 result[reference_string] = value;
14471 break;
14472 }
14473 }
14474 }
14475
14486 template<typename BasicJsonType>
14487 static BasicJsonType
14488 unflatten(const BasicJsonType& value)
14489 {
14490 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14491 {
14492 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14493 }
14494
14495 BasicJsonType result;
14496
14497 // iterate the JSON object values
14498 for (const auto& element : *value.m_value.object)
14499 {
14500 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14501 {
14502 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14503 }
14504
14505 // assign value to reference pointed to by JSON pointer; Note that if
14506 // the JSON pointer is "" (i.e., points to the whole value), function
14507 // get_and_create returns a reference to result itself. An assignment
14508 // will then create a primitive value.
14509 json_pointer(element.first).get_and_create(result) = element.second;
14510 }
14511
14512 return result;
14513 }
14514
14515 // can't use conversion operator because of ambiguity
14516 json_pointer<string_t> convert() const&
14517 {
14519 result.reference_tokens = reference_tokens;
14520 return result;
14521 }
14522
14523 json_pointer<string_t> convert()&&
14524 {
14526 result.reference_tokens = std::move(reference_tokens);
14527 return result;
14528 }
14529
14530 public:
14531#if JSON_HAS_THREE_WAY_COMPARISON
14534 template<typename RefStringTypeRhs>
14535 bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
14536 {
14537 return reference_tokens == rhs.reference_tokens;
14538 }
14539
14542 JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
14543 bool operator==(const string_t& rhs) const
14544 {
14545 return *this == json_pointer(rhs);
14546 }
14547
14549 template<typename RefStringTypeRhs>
14550 std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
14551 {
14552 return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
14553 }
14554#else
14557 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14558 // NOLINTNEXTLINE(readability-redundant-declaration)
14559 friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14560 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14561
14564 template<typename RefStringTypeLhs, typename StringType>
14565 // NOLINTNEXTLINE(readability-redundant-declaration)
14566 friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14567 const StringType& rhs);
14568
14571 template<typename RefStringTypeRhs, typename StringType>
14572 // NOLINTNEXTLINE(readability-redundant-declaration)
14573 friend bool operator==(const StringType& lhs,
14575
14578 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14579 // NOLINTNEXTLINE(readability-redundant-declaration)
14580 friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14581 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14582
14585 template<typename RefStringTypeLhs, typename StringType>
14586 // NOLINTNEXTLINE(readability-redundant-declaration)
14587 friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14588 const StringType& rhs);
14589
14592 template<typename RefStringTypeRhs, typename StringType>
14593 // NOLINTNEXTLINE(readability-redundant-declaration)
14594 friend bool operator!=(const StringType& lhs,
14596
14598 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14599 // NOLINTNEXTLINE(readability-redundant-declaration)
14600 friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14601 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14602#endif
14603
14604 private:
14606 std::vector<string_t> reference_tokens;
14607};
14608
14609#if !JSON_HAS_THREE_WAY_COMPARISON
14610// functions cannot be defined inside class due to ODR violations
14611template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14613 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14614{
14615 return lhs.reference_tokens == rhs.reference_tokens;
14616}
14617
14618template<typename RefStringTypeLhs,
14619 typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14621inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14622 const StringType& rhs)
14623{
14624 return lhs == json_pointer<RefStringTypeLhs>(rhs);
14625}
14626
14627template<typename RefStringTypeRhs,
14628 typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14630inline bool operator==(const StringType& lhs,
14631 const json_pointer<RefStringTypeRhs>& rhs)
14632{
14633 return json_pointer<RefStringTypeRhs>(lhs) == rhs;
14634}
14635
14636template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14638 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14639{
14640 return !(lhs == rhs);
14641}
14642
14643template<typename RefStringTypeLhs,
14644 typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14646inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14647 const StringType& rhs)
14648{
14649 return !(lhs == rhs);
14650}
14651
14652template<typename RefStringTypeRhs,
14653 typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14655inline bool operator!=(const StringType& lhs,
14656 const json_pointer<RefStringTypeRhs>& rhs)
14657{
14658 return !(lhs == rhs);
14659}
14660
14661template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14663 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14664{
14665 return lhs.reference_tokens < rhs.reference_tokens;
14666}
14667#endif
14668
14670
14671// #include <nlohmann/detail/json_ref.hpp>
14672// __ _____ _____ _____
14673// __| | __| | | | JSON for Modern C++
14674// | | |__ | | | | | | version 3.11.2
14675// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14676//
14677// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14678// SPDX-License-Identifier: MIT
14679
14680
14681
14682#include <initializer_list>
14683#include <utility>
14684
14685// #include <nlohmann/detail/abi_macros.hpp>
14686
14687// #include <nlohmann/detail/meta/type_traits.hpp>
14688
14689
14691namespace detail
14692{
14693
14694template<typename BasicJsonType>
14696{
14697 public:
14698 using value_type = BasicJsonType;
14699
14701 : owned_value(std::move(value))
14702 {}
14703
14705 : value_ref(&value)
14706 {}
14707
14708 json_ref(std::initializer_list<json_ref> init)
14709 : owned_value(init)
14710 {}
14711
14712 template <
14713 class... Args,
14714 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14715 json_ref(Args && ... args)
14716 : owned_value(std::forward<Args>(args)...)
14717 {}
14718
14719 // class should be movable only
14720 json_ref(json_ref&&) noexcept = default;
14721 json_ref(const json_ref&) = delete;
14722 json_ref& operator=(const json_ref&) = delete;
14723 json_ref& operator=(json_ref&&) = delete;
14724 ~json_ref() = default;
14725
14727 {
14728 if (value_ref == nullptr)
14729 {
14730 return std::move(owned_value);
14731 }
14732 return *value_ref;
14733 }
14734
14735 value_type const& operator*() const
14736 {
14737 return value_ref ? *value_ref : owned_value;
14738 }
14739
14740 value_type const* operator->() const
14741 {
14742 return &** this;
14743 }
14744
14745 private:
14746 mutable value_type owned_value = nullptr;
14747 value_type const* value_ref = nullptr;
14748};
14749
14750} // namespace detail
14752
14753// #include <nlohmann/detail/macro_scope.hpp>
14754
14755// #include <nlohmann/detail/string_concat.hpp>
14756
14757// #include <nlohmann/detail/string_escape.hpp>
14758
14759// #include <nlohmann/detail/meta/cpp_future.hpp>
14760
14761// #include <nlohmann/detail/meta/type_traits.hpp>
14762
14763// #include <nlohmann/detail/output/binary_writer.hpp>
14764// __ _____ _____ _____
14765// __| | __| | | | JSON for Modern C++
14766// | | |__ | | | | | | version 3.11.2
14767// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14768//
14769// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14770// SPDX-License-Identifier: MIT
14771
14772
14773
14774#include <algorithm> // reverse
14775#include <array> // array
14776#include <map> // map
14777#include <cmath> // isnan, isinf
14778#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14779#include <cstring> // memcpy
14780#include <limits> // numeric_limits
14781#include <string> // string
14782#include <utility> // move
14783#include <vector> // vector
14784
14785// #include <nlohmann/detail/input/binary_reader.hpp>
14786
14787// #include <nlohmann/detail/macro_scope.hpp>
14788
14789// #include <nlohmann/detail/output/output_adapters.hpp>
14790// __ _____ _____ _____
14791// __| | __| | | | JSON for Modern C++
14792// | | |__ | | | | | | version 3.11.2
14793// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14794//
14795// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
14796// SPDX-License-Identifier: MIT
14797
14798
14799
14800#include <algorithm> // copy
14801#include <cstddef> // size_t
14802#include <iterator> // back_inserter
14803#include <memory> // shared_ptr, make_shared
14804#include <string> // basic_string
14805#include <vector> // vector
14806
14807#ifndef JSON_NO_IO
14808 #include <ios> // streamsize
14809 #include <ostream> // basic_ostream
14810#endif // JSON_NO_IO
14811
14812// #include <nlohmann/detail/macro_scope.hpp>
14813
14814
14816namespace detail
14817{
14818
14820template<typename CharType> struct output_adapter_protocol
14821{
14822 virtual void write_character(CharType c) = 0;
14823 virtual void write_characters(const CharType* s, std::size_t length) = 0;
14824 virtual ~output_adapter_protocol() = default;
14825
14830 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
14831};
14832
14834template<typename CharType>
14835using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14836
14838template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14840{
14841 public:
14842 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14843 : v(vec)
14844 {}
14845
14846 void write_character(CharType c) override
14847 {
14848 v.push_back(c);
14849 }
14850
14852 void write_characters(const CharType* s, std::size_t length) override
14853 {
14854 v.insert(v.end(), s, s + length);
14855 }
14856
14857 private:
14858 std::vector<CharType, AllocatorType>& v;
14859};
14860
14861#ifndef JSON_NO_IO
14863template<typename CharType>
14865{
14866 public:
14867 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14868 : stream(s)
14869 {}
14870
14871 void write_character(CharType c) override
14872 {
14873 stream.put(c);
14874 }
14875
14877 void write_characters(const CharType* s, std::size_t length) override
14878 {
14879 stream.write(s, static_cast<std::streamsize>(length));
14880 }
14881
14882 private:
14883 std::basic_ostream<CharType>& stream;
14884};
14885#endif // JSON_NO_IO
14886
14888template<typename CharType, typename StringType = std::basic_string<CharType>>
14890{
14891 public:
14892 explicit output_string_adapter(StringType& s) noexcept
14893 : str(s)
14894 {}
14895
14896 void write_character(CharType c) override
14897 {
14898 str.push_back(c);
14899 }
14900
14902 void write_characters(const CharType* s, std::size_t length) override
14903 {
14904 str.append(s, length);
14905 }
14906
14907 private:
14908 StringType& str;
14909};
14910
14911template<typename CharType, typename StringType = std::basic_string<CharType>>
14913{
14914 public:
14915 template<typename AllocatorType = std::allocator<CharType>>
14916 output_adapter(std::vector<CharType, AllocatorType>& vec)
14917 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
14918
14919#ifndef JSON_NO_IO
14920 output_adapter(std::basic_ostream<CharType>& s)
14921 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
14922#endif // JSON_NO_IO
14923
14924 output_adapter(StringType& s)
14925 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
14926
14928 {
14929 return oa;
14930 }
14931
14932 private:
14933 output_adapter_t<CharType> oa = nullptr;
14934};
14935
14936} // namespace detail
14938
14939// #include <nlohmann/detail/string_concat.hpp>
14940
14941
14943namespace detail
14944{
14945
14947// binary writer //
14949
14953template<typename BasicJsonType, typename CharType>
14955{
14956 using string_t = typename BasicJsonType::string_t;
14957 using binary_t = typename BasicJsonType::binary_t;
14958 using number_float_t = typename BasicJsonType::number_float_t;
14959
14960 public:
14966 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
14967 {
14968 JSON_ASSERT(oa);
14969 }
14970
14975 void write_bson(const BasicJsonType& j)
14976 {
14977 switch (j.type())
14978 {
14979 case value_t::object:
14980 {
14981 write_bson_object(*j.m_value.object);
14982 break;
14983 }
14984
14985 case value_t::null:
14986 case value_t::array:
14987 case value_t::string:
14988 case value_t::boolean:
14989 case value_t::number_integer:
14990 case value_t::number_unsigned:
14991 case value_t::number_float:
14992 case value_t::binary:
14993 case value_t::discarded:
14994 default:
14995 {
14996 JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
14997 }
14998 }
14999 }
15000
15004 void write_cbor(const BasicJsonType& j)
15005 {
15006 switch (j.type())
15007 {
15008 case value_t::null:
15009 {
15010 oa->write_character(to_char_type(0xF6));
15011 break;
15012 }
15013
15014 case value_t::boolean:
15015 {
15016 oa->write_character(j.m_value.boolean
15017 ? to_char_type(0xF5)
15018 : to_char_type(0xF4));
15019 break;
15020 }
15021
15022 case value_t::number_integer:
15023 {
15024 if (j.m_value.number_integer >= 0)
15025 {
15026 // CBOR does not differentiate between positive signed
15027 // integers and unsigned integers. Therefore, we used the
15028 // code from the value_t::number_unsigned case here.
15029 if (j.m_value.number_integer <= 0x17)
15030 {
15031 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15032 }
15033 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15034 {
15035 oa->write_character(to_char_type(0x18));
15036 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15037 }
15038 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15039 {
15040 oa->write_character(to_char_type(0x19));
15041 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
15042 }
15043 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15044 {
15045 oa->write_character(to_char_type(0x1A));
15046 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
15047 }
15048 else
15049 {
15050 oa->write_character(to_char_type(0x1B));
15051 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
15052 }
15053 }
15054 else
15055 {
15056 // The conversions below encode the sign in the first
15057 // byte, and the value is converted to a positive number.
15058 const auto positive_number = -1 - j.m_value.number_integer;
15059 if (j.m_value.number_integer >= -24)
15060 {
15061 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15062 }
15063 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15064 {
15065 oa->write_character(to_char_type(0x38));
15066 write_number(static_cast<std::uint8_t>(positive_number));
15067 }
15068 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15069 {
15070 oa->write_character(to_char_type(0x39));
15071 write_number(static_cast<std::uint16_t>(positive_number));
15072 }
15073 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15074 {
15075 oa->write_character(to_char_type(0x3A));
15076 write_number(static_cast<std::uint32_t>(positive_number));
15077 }
15078 else
15079 {
15080 oa->write_character(to_char_type(0x3B));
15081 write_number(static_cast<std::uint64_t>(positive_number));
15082 }
15083 }
15084 break;
15085 }
15086
15087 case value_t::number_unsigned:
15088 {
15089 if (j.m_value.number_unsigned <= 0x17)
15090 {
15091 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
15092 }
15093 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15094 {
15095 oa->write_character(to_char_type(0x18));
15096 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
15097 }
15098 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15099 {
15100 oa->write_character(to_char_type(0x19));
15101 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
15102 }
15103 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15104 {
15105 oa->write_character(to_char_type(0x1A));
15106 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
15107 }
15108 else
15109 {
15110 oa->write_character(to_char_type(0x1B));
15111 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
15112 }
15113 break;
15114 }
15115
15116 case value_t::number_float:
15117 {
15118 if (std::isnan(j.m_value.number_float))
15119 {
15120 // NaN is 0xf97e00 in CBOR
15121 oa->write_character(to_char_type(0xF9));
15122 oa->write_character(to_char_type(0x7E));
15123 oa->write_character(to_char_type(0x00));
15124 }
15125 else if (std::isinf(j.m_value.number_float))
15126 {
15127 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
15128 oa->write_character(to_char_type(0xf9));
15129 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
15130 oa->write_character(to_char_type(0x00));
15131 }
15132 else
15133 {
15134 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
15135 }
15136 break;
15137 }
15138
15139 case value_t::string:
15140 {
15141 // step 1: write control byte and the string length
15142 const auto N = j.m_value.string->size();
15143 if (N <= 0x17)
15144 {
15145 write_number(static_cast<std::uint8_t>(0x60 + N));
15146 }
15147 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15148 {
15149 oa->write_character(to_char_type(0x78));
15150 write_number(static_cast<std::uint8_t>(N));
15151 }
15152 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15153 {
15154 oa->write_character(to_char_type(0x79));
15155 write_number(static_cast<std::uint16_t>(N));
15156 }
15157 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15158 {
15159 oa->write_character(to_char_type(0x7A));
15160 write_number(static_cast<std::uint32_t>(N));
15161 }
15162 // LCOV_EXCL_START
15163 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15164 {
15165 oa->write_character(to_char_type(0x7B));
15166 write_number(static_cast<std::uint64_t>(N));
15167 }
15168 // LCOV_EXCL_STOP
15169
15170 // step 2: write the string
15171 oa->write_characters(
15172 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15173 j.m_value.string->size());
15174 break;
15175 }
15176
15177 case value_t::array:
15178 {
15179 // step 1: write control byte and the array size
15180 const auto N = j.m_value.array->size();
15181 if (N <= 0x17)
15182 {
15183 write_number(static_cast<std::uint8_t>(0x80 + N));
15184 }
15185 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15186 {
15187 oa->write_character(to_char_type(0x98));
15188 write_number(static_cast<std::uint8_t>(N));
15189 }
15190 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15191 {
15192 oa->write_character(to_char_type(0x99));
15193 write_number(static_cast<std::uint16_t>(N));
15194 }
15195 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15196 {
15197 oa->write_character(to_char_type(0x9A));
15198 write_number(static_cast<std::uint32_t>(N));
15199 }
15200 // LCOV_EXCL_START
15201 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15202 {
15203 oa->write_character(to_char_type(0x9B));
15204 write_number(static_cast<std::uint64_t>(N));
15205 }
15206 // LCOV_EXCL_STOP
15207
15208 // step 2: write each element
15209 for (const auto& el : *j.m_value.array)
15210 {
15211 write_cbor(el);
15212 }
15213 break;
15214 }
15215
15216 case value_t::binary:
15217 {
15218 if (j.m_value.binary->has_subtype())
15219 {
15220 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
15221 {
15222 write_number(static_cast<std::uint8_t>(0xd8));
15223 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
15224 }
15225 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
15226 {
15227 write_number(static_cast<std::uint8_t>(0xd9));
15228 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
15229 }
15230 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
15231 {
15232 write_number(static_cast<std::uint8_t>(0xda));
15233 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
15234 }
15235 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
15236 {
15237 write_number(static_cast<std::uint8_t>(0xdb));
15238 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
15239 }
15240 }
15241
15242 // step 1: write control byte and the binary array size
15243 const auto N = j.m_value.binary->size();
15244 if (N <= 0x17)
15245 {
15246 write_number(static_cast<std::uint8_t>(0x40 + N));
15247 }
15248 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15249 {
15250 oa->write_character(to_char_type(0x58));
15251 write_number(static_cast<std::uint8_t>(N));
15252 }
15253 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15254 {
15255 oa->write_character(to_char_type(0x59));
15256 write_number(static_cast<std::uint16_t>(N));
15257 }
15258 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15259 {
15260 oa->write_character(to_char_type(0x5A));
15261 write_number(static_cast<std::uint32_t>(N));
15262 }
15263 // LCOV_EXCL_START
15264 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15265 {
15266 oa->write_character(to_char_type(0x5B));
15267 write_number(static_cast<std::uint64_t>(N));
15268 }
15269 // LCOV_EXCL_STOP
15270
15271 // step 2: write each element
15272 oa->write_characters(
15273 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15274 N);
15275
15276 break;
15277 }
15278
15279 case value_t::object:
15280 {
15281 // step 1: write control byte and the object size
15282 const auto N = j.m_value.object->size();
15283 if (N <= 0x17)
15284 {
15285 write_number(static_cast<std::uint8_t>(0xA0 + N));
15286 }
15287 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15288 {
15289 oa->write_character(to_char_type(0xB8));
15290 write_number(static_cast<std::uint8_t>(N));
15291 }
15292 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15293 {
15294 oa->write_character(to_char_type(0xB9));
15295 write_number(static_cast<std::uint16_t>(N));
15296 }
15297 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15298 {
15299 oa->write_character(to_char_type(0xBA));
15300 write_number(static_cast<std::uint32_t>(N));
15301 }
15302 // LCOV_EXCL_START
15303 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15304 {
15305 oa->write_character(to_char_type(0xBB));
15306 write_number(static_cast<std::uint64_t>(N));
15307 }
15308 // LCOV_EXCL_STOP
15309
15310 // step 2: write each element
15311 for (const auto& el : *j.m_value.object)
15312 {
15313 write_cbor(el.first);
15314 write_cbor(el.second);
15315 }
15316 break;
15317 }
15318
15319 case value_t::discarded:
15320 default:
15321 break;
15322 }
15323 }
15324
15328 void write_msgpack(const BasicJsonType& j)
15329 {
15330 switch (j.type())
15331 {
15332 case value_t::null: // nil
15333 {
15334 oa->write_character(to_char_type(0xC0));
15335 break;
15336 }
15337
15338 case value_t::boolean: // true and false
15339 {
15340 oa->write_character(j.m_value.boolean
15341 ? to_char_type(0xC3)
15342 : to_char_type(0xC2));
15343 break;
15344 }
15345
15346 case value_t::number_integer:
15347 {
15348 if (j.m_value.number_integer >= 0)
15349 {
15350 // MessagePack does not differentiate between positive
15351 // signed integers and unsigned integers. Therefore, we used
15352 // the code from the value_t::number_unsigned case here.
15353 if (j.m_value.number_unsigned < 128)
15354 {
15355 // positive fixnum
15356 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15357 }
15358 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15359 {
15360 // uint 8
15361 oa->write_character(to_char_type(0xCC));
15362 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15363 }
15364 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15365 {
15366 // uint 16
15367 oa->write_character(to_char_type(0xCD));
15368 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
15369 }
15370 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15371 {
15372 // uint 32
15373 oa->write_character(to_char_type(0xCE));
15374 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
15375 }
15376 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15377 {
15378 // uint 64
15379 oa->write_character(to_char_type(0xCF));
15380 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
15381 }
15382 }
15383 else
15384 {
15385 if (j.m_value.number_integer >= -32)
15386 {
15387 // negative fixnum
15388 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
15389 }
15390 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
15391 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15392 {
15393 // int 8
15394 oa->write_character(to_char_type(0xD0));
15395 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
15396 }
15397 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
15398 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15399 {
15400 // int 16
15401 oa->write_character(to_char_type(0xD1));
15402 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
15403 }
15404 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
15405 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15406 {
15407 // int 32
15408 oa->write_character(to_char_type(0xD2));
15409 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
15410 }
15411 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
15412 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15413 {
15414 // int 64
15415 oa->write_character(to_char_type(0xD3));
15416 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
15417 }
15418 }
15419 break;
15420 }
15421
15422 case value_t::number_unsigned:
15423 {
15424 if (j.m_value.number_unsigned < 128)
15425 {
15426 // positive fixnum
15427 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15428 }
15429 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15430 {
15431 // uint 8
15432 oa->write_character(to_char_type(0xCC));
15433 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
15434 }
15435 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15436 {
15437 // uint 16
15438 oa->write_character(to_char_type(0xCD));
15439 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
15440 }
15441 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15442 {
15443 // uint 32
15444 oa->write_character(to_char_type(0xCE));
15445 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
15446 }
15447 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15448 {
15449 // uint 64
15450 oa->write_character(to_char_type(0xCF));
15451 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
15452 }
15453 break;
15454 }
15455
15456 case value_t::number_float:
15457 {
15458 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
15459 break;
15460 }
15461
15462 case value_t::string:
15463 {
15464 // step 1: write control byte and the string length
15465 const auto N = j.m_value.string->size();
15466 if (N <= 31)
15467 {
15468 // fixstr
15469 write_number(static_cast<std::uint8_t>(0xA0 | N));
15470 }
15471 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15472 {
15473 // str 8
15474 oa->write_character(to_char_type(0xD9));
15475 write_number(static_cast<std::uint8_t>(N));
15476 }
15477 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15478 {
15479 // str 16
15480 oa->write_character(to_char_type(0xDA));
15481 write_number(static_cast<std::uint16_t>(N));
15482 }
15483 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15484 {
15485 // str 32
15486 oa->write_character(to_char_type(0xDB));
15487 write_number(static_cast<std::uint32_t>(N));
15488 }
15489
15490 // step 2: write the string
15491 oa->write_characters(
15492 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15493 j.m_value.string->size());
15494 break;
15495 }
15496
15497 case value_t::array:
15498 {
15499 // step 1: write control byte and the array size
15500 const auto N = j.m_value.array->size();
15501 if (N <= 15)
15502 {
15503 // fixarray
15504 write_number(static_cast<std::uint8_t>(0x90 | N));
15505 }
15506 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15507 {
15508 // array 16
15509 oa->write_character(to_char_type(0xDC));
15510 write_number(static_cast<std::uint16_t>(N));
15511 }
15512 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15513 {
15514 // array 32
15515 oa->write_character(to_char_type(0xDD));
15516 write_number(static_cast<std::uint32_t>(N));
15517 }
15518
15519 // step 2: write each element
15520 for (const auto& el : *j.m_value.array)
15521 {
15522 write_msgpack(el);
15523 }
15524 break;
15525 }
15526
15527 case value_t::binary:
15528 {
15529 // step 0: determine if the binary type has a set subtype to
15530 // determine whether or not to use the ext or fixext types
15531 const bool use_ext = j.m_value.binary->has_subtype();
15532
15533 // step 1: write control byte and the byte string length
15534 const auto N = j.m_value.binary->size();
15535 if (N <= (std::numeric_limits<std::uint8_t>::max)())
15536 {
15537 std::uint8_t output_type{};
15538 bool fixed = true;
15539 if (use_ext)
15540 {
15541 switch (N)
15542 {
15543 case 1:
15544 output_type = 0xD4; // fixext 1
15545 break;
15546 case 2:
15547 output_type = 0xD5; // fixext 2
15548 break;
15549 case 4:
15550 output_type = 0xD6; // fixext 4
15551 break;
15552 case 8:
15553 output_type = 0xD7; // fixext 8
15554 break;
15555 case 16:
15556 output_type = 0xD8; // fixext 16
15557 break;
15558 default:
15559 output_type = 0xC7; // ext 8
15560 fixed = false;
15561 break;
15562 }
15563
15564 }
15565 else
15566 {
15567 output_type = 0xC4; // bin 8
15568 fixed = false;
15569 }
15570
15571 oa->write_character(to_char_type(output_type));
15572 if (!fixed)
15573 {
15574 write_number(static_cast<std::uint8_t>(N));
15575 }
15576 }
15577 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15578 {
15579 std::uint8_t output_type = use_ext
15580 ? 0xC8 // ext 16
15581 : 0xC5; // bin 16
15582
15583 oa->write_character(to_char_type(output_type));
15584 write_number(static_cast<std::uint16_t>(N));
15585 }
15586 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15587 {
15588 std::uint8_t output_type = use_ext
15589 ? 0xC9 // ext 32
15590 : 0xC6; // bin 32
15591
15592 oa->write_character(to_char_type(output_type));
15593 write_number(static_cast<std::uint32_t>(N));
15594 }
15595
15596 // step 1.5: if this is an ext type, write the subtype
15597 if (use_ext)
15598 {
15599 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
15600 }
15601
15602 // step 2: write the byte string
15603 oa->write_characters(
15604 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15605 N);
15606
15607 break;
15608 }
15609
15610 case value_t::object:
15611 {
15612 // step 1: write control byte and the object size
15613 const auto N = j.m_value.object->size();
15614 if (N <= 15)
15615 {
15616 // fixmap
15617 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15618 }
15619 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15620 {
15621 // map 16
15622 oa->write_character(to_char_type(0xDE));
15623 write_number(static_cast<std::uint16_t>(N));
15624 }
15625 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15626 {
15627 // map 32
15628 oa->write_character(to_char_type(0xDF));
15629 write_number(static_cast<std::uint32_t>(N));
15630 }
15631
15632 // step 2: write each element
15633 for (const auto& el : *j.m_value.object)
15634 {
15635 write_msgpack(el.first);
15636 write_msgpack(el.second);
15637 }
15638 break;
15639 }
15640
15641 case value_t::discarded:
15642 default:
15643 break;
15644 }
15645 }
15646
15654 void write_ubjson(const BasicJsonType& j, const bool use_count,
15655 const bool use_type, const bool add_prefix = true,
15656 const bool use_bjdata = false)
15657 {
15658 switch (j.type())
15659 {
15660 case value_t::null:
15661 {
15662 if (add_prefix)
15663 {
15664 oa->write_character(to_char_type('Z'));
15665 }
15666 break;
15667 }
15668
15669 case value_t::boolean:
15670 {
15671 if (add_prefix)
15672 {
15673 oa->write_character(j.m_value.boolean
15674 ? to_char_type('T')
15675 : to_char_type('F'));
15676 }
15677 break;
15678 }
15679
15680 case value_t::number_integer:
15681 {
15682 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
15683 break;
15684 }
15685
15686 case value_t::number_unsigned:
15687 {
15688 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
15689 break;
15690 }
15691
15692 case value_t::number_float:
15693 {
15694 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
15695 break;
15696 }
15697
15698 case value_t::string:
15699 {
15700 if (add_prefix)
15701 {
15702 oa->write_character(to_char_type('S'));
15703 }
15704 write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata);
15705 oa->write_characters(
15706 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15707 j.m_value.string->size());
15708 break;
15709 }
15710
15711 case value_t::array:
15712 {
15713 if (add_prefix)
15714 {
15715 oa->write_character(to_char_type('['));
15716 }
15717
15718 bool prefix_required = true;
15719 if (use_type && !j.m_value.array->empty())
15720 {
15721 JSON_ASSERT(use_count);
15722 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15723 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15724 [this, first_prefix, use_bjdata](const BasicJsonType & v)
15725 {
15726 return ubjson_prefix(v, use_bjdata) == first_prefix;
15727 });
15728
15729 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15730
15731 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15732 {
15733 prefix_required = false;
15734 oa->write_character(to_char_type('$'));
15735 oa->write_character(first_prefix);
15736 }
15737 }
15738
15739 if (use_count)
15740 {
15741 oa->write_character(to_char_type('#'));
15742 write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata);
15743 }
15744
15745 for (const auto& el : *j.m_value.array)
15746 {
15747 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15748 }
15749
15750 if (!use_count)
15751 {
15752 oa->write_character(to_char_type(']'));
15753 }
15754
15755 break;
15756 }
15757
15758 case value_t::binary:
15759 {
15760 if (add_prefix)
15761 {
15762 oa->write_character(to_char_type('['));
15763 }
15764
15765 if (use_type && !j.m_value.binary->empty())
15766 {
15767 JSON_ASSERT(use_count);
15768 oa->write_character(to_char_type('$'));
15769 oa->write_character('U');
15770 }
15771
15772 if (use_count)
15773 {
15774 oa->write_character(to_char_type('#'));
15775 write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata);
15776 }
15777
15778 if (use_type)
15779 {
15780 oa->write_characters(
15781 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15782 j.m_value.binary->size());
15783 }
15784 else
15785 {
15786 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
15787 {
15788 oa->write_character(to_char_type('U'));
15789 oa->write_character(j.m_value.binary->data()[i]);
15790 }
15791 }
15792
15793 if (!use_count)
15794 {
15795 oa->write_character(to_char_type(']'));
15796 }
15797
15798 break;
15799 }
15800
15801 case value_t::object:
15802 {
15803 if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end())
15804 {
15805 if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15806 {
15807 break;
15808 }
15809 }
15810
15811 if (add_prefix)
15812 {
15813 oa->write_character(to_char_type('{'));
15814 }
15815
15816 bool prefix_required = true;
15817 if (use_type && !j.m_value.object->empty())
15818 {
15819 JSON_ASSERT(use_count);
15820 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15821 const bool same_prefix = std::all_of(j.begin(), j.end(),
15822 [this, first_prefix, use_bjdata](const BasicJsonType & v)
15823 {
15824 return ubjson_prefix(v, use_bjdata) == first_prefix;
15825 });
15826
15827 std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15828
15829 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15830 {
15831 prefix_required = false;
15832 oa->write_character(to_char_type('$'));
15833 oa->write_character(first_prefix);
15834 }
15835 }
15836
15837 if (use_count)
15838 {
15839 oa->write_character(to_char_type('#'));
15840 write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata);
15841 }
15842
15843 for (const auto& el : *j.m_value.object)
15844 {
15845 write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15846 oa->write_characters(
15847 reinterpret_cast<const CharType*>(el.first.c_str()),
15848 el.first.size());
15849 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15850 }
15851
15852 if (!use_count)
15853 {
15854 oa->write_character(to_char_type('}'));
15855 }
15856
15857 break;
15858 }
15859
15860 case value_t::discarded:
15861 default:
15862 break;
15863 }
15864 }
15865
15866 private:
15868 // BSON //
15870
15875 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
15876 {
15877 const auto it = name.find(static_cast<typename string_t::value_type>(0));
15878 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
15879 {
15880 JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
15881 static_cast<void>(j);
15882 }
15883
15884 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
15885 }
15886
15890 void write_bson_entry_header(const string_t& name,
15891 const std::uint8_t element_type)
15892 {
15893 oa->write_character(to_char_type(element_type)); // boolean
15894 oa->write_characters(
15895 reinterpret_cast<const CharType*>(name.c_str()),
15896 name.size() + 1u);
15897 }
15898
15902 void write_bson_boolean(const string_t& name,
15903 const bool value)
15904 {
15905 write_bson_entry_header(name, 0x08);
15906 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
15907 }
15908
15912 void write_bson_double(const string_t& name,
15913 const double value)
15914 {
15915 write_bson_entry_header(name, 0x01);
15916 write_number<double>(value, true);
15917 }
15918
15922 static std::size_t calc_bson_string_size(const string_t& value)
15923 {
15924 return sizeof(std::int32_t) + value.size() + 1ul;
15925 }
15926
15930 void write_bson_string(const string_t& name,
15931 const string_t& value)
15932 {
15933 write_bson_entry_header(name, 0x02);
15934
15935 write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15936 oa->write_characters(
15937 reinterpret_cast<const CharType*>(value.c_str()),
15938 value.size() + 1);
15939 }
15940
15944 void write_bson_null(const string_t& name)
15945 {
15946 write_bson_entry_header(name, 0x0A);
15947 }
15948
15952 static std::size_t calc_bson_integer_size(const std::int64_t value)
15953 {
15954 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
15955 ? sizeof(std::int32_t)
15956 : sizeof(std::int64_t);
15957 }
15958
15962 void write_bson_integer(const string_t& name,
15963 const std::int64_t value)
15964 {
15965 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
15966 {
15967 write_bson_entry_header(name, 0x10); // int32
15968 write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
15969 }
15970 else
15971 {
15972 write_bson_entry_header(name, 0x12); // int64
15973 write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
15974 }
15975 }
15976
15980 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
15981 {
15982 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15983 ? sizeof(std::int32_t)
15984 : sizeof(std::int64_t);
15985 }
15986
15990 void write_bson_unsigned(const string_t& name,
15991 const BasicJsonType& j)
15992 {
15993 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15994 {
15995 write_bson_entry_header(name, 0x10 /* int32 */);
15996 write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true);
15997 }
15998 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15999 {
16000 write_bson_entry_header(name, 0x12 /* int64 */);
16001 write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true);
16002 }
16003 else
16004 {
16005 JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
16006 }
16007 }
16008
16012 void write_bson_object_entry(const string_t& name,
16013 const typename BasicJsonType::object_t& value)
16014 {
16015 write_bson_entry_header(name, 0x03); // object
16016 write_bson_object(value);
16017 }
16018
16022 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16023 {
16024 std::size_t array_index = 0ul;
16025
16026 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
16027 {
16028 return result + calc_bson_element_size(std::to_string(array_index++), el);
16029 });
16030
16031 return sizeof(std::int32_t) + embedded_document_size + 1ul;
16032 }
16033
16037 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16038 {
16039 return sizeof(std::int32_t) + value.size() + 1ul;
16040 }
16041
16045 void write_bson_array(const string_t& name,
16046 const typename BasicJsonType::array_t& value)
16047 {
16048 write_bson_entry_header(name, 0x04); // array
16049 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16050
16051 std::size_t array_index = 0ul;
16052
16053 for (const auto& el : value)
16054 {
16055 write_bson_element(std::to_string(array_index++), el);
16056 }
16057
16058 oa->write_character(to_char_type(0x00));
16059 }
16060
16064 void write_bson_binary(const string_t& name,
16065 const binary_t& value)
16066 {
16067 write_bson_entry_header(name, 0x05);
16068
16069 write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16070 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16071
16072 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16073 }
16074
16079 static std::size_t calc_bson_element_size(const string_t& name,
16080 const BasicJsonType& j)
16081 {
16082 const auto header_size = calc_bson_entry_header_size(name, j);
16083 switch (j.type())
16084 {
16085 case value_t::object:
16086 return header_size + calc_bson_object_size(*j.m_value.object);
16087
16088 case value_t::array:
16089 return header_size + calc_bson_array_size(*j.m_value.array);
16090
16091 case value_t::binary:
16092 return header_size + calc_bson_binary_size(*j.m_value.binary);
16093
16094 case value_t::boolean:
16095 return header_size + 1ul;
16096
16097 case value_t::number_float:
16098 return header_size + 8ul;
16099
16100 case value_t::number_integer:
16101 return header_size + calc_bson_integer_size(j.m_value.number_integer);
16102
16103 case value_t::number_unsigned:
16104 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
16105
16106 case value_t::string:
16107 return header_size + calc_bson_string_size(*j.m_value.string);
16108
16109 case value_t::null:
16110 return header_size + 0ul;
16111
16112 // LCOV_EXCL_START
16113 case value_t::discarded:
16114 default:
16115 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16116 return 0ul;
16117 // LCOV_EXCL_STOP
16118 }
16119 }
16120
16127 void write_bson_element(const string_t& name,
16128 const BasicJsonType& j)
16129 {
16130 switch (j.type())
16131 {
16132 case value_t::object:
16133 return write_bson_object_entry(name, *j.m_value.object);
16134
16135 case value_t::array:
16136 return write_bson_array(name, *j.m_value.array);
16137
16138 case value_t::binary:
16139 return write_bson_binary(name, *j.m_value.binary);
16140
16141 case value_t::boolean:
16142 return write_bson_boolean(name, j.m_value.boolean);
16143
16144 case value_t::number_float:
16145 return write_bson_double(name, j.m_value.number_float);
16146
16147 case value_t::number_integer:
16148 return write_bson_integer(name, j.m_value.number_integer);
16149
16150 case value_t::number_unsigned:
16151 return write_bson_unsigned(name, j);
16152
16153 case value_t::string:
16154 return write_bson_string(name, *j.m_value.string);
16155
16156 case value_t::null:
16157 return write_bson_null(name);
16158
16159 // LCOV_EXCL_START
16160 case value_t::discarded:
16161 default:
16162 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16163 return;
16164 // LCOV_EXCL_STOP
16165 }
16166 }
16167
16174 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
16175 {
16176 std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
16177 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
16178 {
16179 return result += calc_bson_element_size(el.first, el.second);
16180 });
16181
16182 return sizeof(std::int32_t) + document_size + 1ul;
16183 }
16184
16189 void write_bson_object(const typename BasicJsonType::object_t& value)
16190 {
16191 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
16192
16193 for (const auto& el : value)
16194 {
16195 write_bson_element(el.first, el.second);
16196 }
16197
16198 oa->write_character(to_char_type(0x00));
16199 }
16200
16202 // CBOR //
16204
16205 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
16206 {
16207 return to_char_type(0xFA); // Single-Precision Float
16208 }
16209
16210 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
16211 {
16212 return to_char_type(0xFB); // Double-Precision Float
16213 }
16214
16216 // MsgPack //
16218
16219 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
16220 {
16221 return to_char_type(0xCA); // float 32
16222 }
16223
16224 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
16225 {
16226 return to_char_type(0xCB); // float 64
16227 }
16228
16230 // UBJSON //
16232
16233 // UBJSON: write number (floating point)
16234 template<typename NumberType, typename std::enable_if<
16235 std::is_floating_point<NumberType>::value, int>::type = 0>
16236 void write_number_with_ubjson_prefix(const NumberType n,
16237 const bool add_prefix,
16238 const bool use_bjdata)
16239 {
16240 if (add_prefix)
16241 {
16242 oa->write_character(get_ubjson_float_prefix(n));
16243 }
16244 write_number(n, use_bjdata);
16245 }
16246
16247 // UBJSON: write number (unsigned integer)
16248 template<typename NumberType, typename std::enable_if<
16249 std::is_unsigned<NumberType>::value, int>::type = 0>
16250 void write_number_with_ubjson_prefix(const NumberType n,
16251 const bool add_prefix,
16252 const bool use_bjdata)
16253 {
16254 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16255 {
16256 if (add_prefix)
16257 {
16258 oa->write_character(to_char_type('i')); // int8
16259 }
16260 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16261 }
16262 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
16263 {
16264 if (add_prefix)
16265 {
16266 oa->write_character(to_char_type('U')); // uint8
16267 }
16268 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16269 }
16270 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16271 {
16272 if (add_prefix)
16273 {
16274 oa->write_character(to_char_type('I')); // int16
16275 }
16276 write_number(static_cast<std::int16_t>(n), use_bjdata);
16277 }
16278 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
16279 {
16280 if (add_prefix)
16281 {
16282 oa->write_character(to_char_type('u')); // uint16 - bjdata only
16283 }
16284 write_number(static_cast<std::uint16_t>(n), use_bjdata);
16285 }
16286 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16287 {
16288 if (add_prefix)
16289 {
16290 oa->write_character(to_char_type('l')); // int32
16291 }
16292 write_number(static_cast<std::int32_t>(n), use_bjdata);
16293 }
16294 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
16295 {
16296 if (add_prefix)
16297 {
16298 oa->write_character(to_char_type('m')); // uint32 - bjdata only
16299 }
16300 write_number(static_cast<std::uint32_t>(n), use_bjdata);
16301 }
16302 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16303 {
16304 if (add_prefix)
16305 {
16306 oa->write_character(to_char_type('L')); // int64
16307 }
16308 write_number(static_cast<std::int64_t>(n), use_bjdata);
16309 }
16310 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
16311 {
16312 if (add_prefix)
16313 {
16314 oa->write_character(to_char_type('M')); // uint64 - bjdata only
16315 }
16316 write_number(static_cast<std::uint64_t>(n), use_bjdata);
16317 }
16318 else
16319 {
16320 if (add_prefix)
16321 {
16322 oa->write_character(to_char_type('H')); // high-precision number
16323 }
16324
16325 const auto number = BasicJsonType(n).dump();
16326 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16327 for (std::size_t i = 0; i < number.size(); ++i)
16328 {
16329 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16330 }
16331 }
16332 }
16333
16334 // UBJSON: write number (signed integer)
16335 template < typename NumberType, typename std::enable_if <
16336 std::is_signed<NumberType>::value&&
16337 !std::is_floating_point<NumberType>::value, int >::type = 0 >
16338 void write_number_with_ubjson_prefix(const NumberType n,
16339 const bool add_prefix,
16340 const bool use_bjdata)
16341 {
16342 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
16343 {
16344 if (add_prefix)
16345 {
16346 oa->write_character(to_char_type('i')); // int8
16347 }
16348 write_number(static_cast<std::int8_t>(n), use_bjdata);
16349 }
16350 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)()))
16351 {
16352 if (add_prefix)
16353 {
16354 oa->write_character(to_char_type('U')); // uint8
16355 }
16356 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16357 }
16358 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
16359 {
16360 if (add_prefix)
16361 {
16362 oa->write_character(to_char_type('I')); // int16
16363 }
16364 write_number(static_cast<std::int16_t>(n), use_bjdata);
16365 }
16366 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
16367 {
16368 if (add_prefix)
16369 {
16370 oa->write_character(to_char_type('u')); // uint16 - bjdata only
16371 }
16372 write_number(static_cast<uint16_t>(n), use_bjdata);
16373 }
16374 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
16375 {
16376 if (add_prefix)
16377 {
16378 oa->write_character(to_char_type('l')); // int32
16379 }
16380 write_number(static_cast<std::int32_t>(n), use_bjdata);
16381 }
16382 else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
16383 {
16384 if (add_prefix)
16385 {
16386 oa->write_character(to_char_type('m')); // uint32 - bjdata only
16387 }
16388 write_number(static_cast<uint32_t>(n), use_bjdata);
16389 }
16390 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
16391 {
16392 if (add_prefix)
16393 {
16394 oa->write_character(to_char_type('L')); // int64
16395 }
16396 write_number(static_cast<std::int64_t>(n), use_bjdata);
16397 }
16398 // LCOV_EXCL_START
16399 else
16400 {
16401 if (add_prefix)
16402 {
16403 oa->write_character(to_char_type('H')); // high-precision number
16404 }
16405
16406 const auto number = BasicJsonType(n).dump();
16407 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16408 for (std::size_t i = 0; i < number.size(); ++i)
16409 {
16410 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16411 }
16412 }
16413 // LCOV_EXCL_STOP
16414 }
16415
16419 CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
16420 {
16421 switch (j.type())
16422 {
16423 case value_t::null:
16424 return 'Z';
16425
16426 case value_t::boolean:
16427 return j.m_value.boolean ? 'T' : 'F';
16428
16429 case value_t::number_integer:
16430 {
16431 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)())
16432 {
16433 return 'i';
16434 }
16435 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)())
16436 {
16437 return 'U';
16438 }
16439 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)())
16440 {
16441 return 'I';
16442 }
16443 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
16444 {
16445 return 'u';
16446 }
16447 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)())
16448 {
16449 return 'l';
16450 }
16451 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
16452 {
16453 return 'm';
16454 }
16455 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)())
16456 {
16457 return 'L';
16458 }
16459 // anything else is treated as high-precision number
16460 return 'H'; // LCOV_EXCL_LINE
16461 }
16462
16463 case value_t::number_unsigned:
16464 {
16465 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16466 {
16467 return 'i';
16468 }
16469 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
16470 {
16471 return 'U';
16472 }
16473 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16474 {
16475 return 'I';
16476 }
16477 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
16478 {
16479 return 'u';
16480 }
16481 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16482 {
16483 return 'l';
16484 }
16485 if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
16486 {
16487 return 'm';
16488 }
16489 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16490 {
16491 return 'L';
16492 }
16493 if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16494 {
16495 return 'M';
16496 }
16497 // anything else is treated as high-precision number
16498 return 'H'; // LCOV_EXCL_LINE
16499 }
16500
16501 case value_t::number_float:
16502 return get_ubjson_float_prefix(j.m_value.number_float);
16503
16504 case value_t::string:
16505 return 'S';
16506
16507 case value_t::array: // fallthrough
16508 case value_t::binary:
16509 return '[';
16510
16511 case value_t::object:
16512 return '{';
16513
16514 case value_t::discarded:
16515 default: // discarded values
16516 return 'N';
16517 }
16518 }
16519
16520 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
16521 {
16522 return 'd'; // float 32
16523 }
16524
16525 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
16526 {
16527 return 'D'; // float 64
16528 }
16529
16533 bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
16534 {
16535 std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
16536 {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
16537 };
16538
16539 string_t key = "_ArrayType_";
16540 auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
16541 if (it == bjdtype.end())
16542 {
16543 return true;
16544 }
16545 CharType dtype = it->second;
16546
16547 key = "_ArraySize_";
16548 std::size_t len = (value.at(key).empty() ? 0 : 1);
16549 for (const auto& el : value.at(key))
16550 {
16551 len *= static_cast<std::size_t>(el.m_value.number_unsigned);
16552 }
16553
16554 key = "_ArrayData_";
16555 if (value.at(key).size() != len)
16556 {
16557 return true;
16558 }
16559
16560 oa->write_character('[');
16561 oa->write_character('$');
16562 oa->write_character(dtype);
16563 oa->write_character('#');
16564
16565 key = "_ArraySize_";
16566 write_ubjson(value.at(key), use_count, use_type, true, true);
16567
16568 key = "_ArrayData_";
16569 if (dtype == 'U' || dtype == 'C')
16570 {
16571 for (const auto& el : value.at(key))
16572 {
16573 write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true);
16574 }
16575 }
16576 else if (dtype == 'i')
16577 {
16578 for (const auto& el : value.at(key))
16579 {
16580 write_number(static_cast<std::int8_t>(el.m_value.number_integer), true);
16581 }
16582 }
16583 else if (dtype == 'u')
16584 {
16585 for (const auto& el : value.at(key))
16586 {
16587 write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true);
16588 }
16589 }
16590 else if (dtype == 'I')
16591 {
16592 for (const auto& el : value.at(key))
16593 {
16594 write_number(static_cast<std::int16_t>(el.m_value.number_integer), true);
16595 }
16596 }
16597 else if (dtype == 'm')
16598 {
16599 for (const auto& el : value.at(key))
16600 {
16601 write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true);
16602 }
16603 }
16604 else if (dtype == 'l')
16605 {
16606 for (const auto& el : value.at(key))
16607 {
16608 write_number(static_cast<std::int32_t>(el.m_value.number_integer), true);
16609 }
16610 }
16611 else if (dtype == 'M')
16612 {
16613 for (const auto& el : value.at(key))
16614 {
16615 write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true);
16616 }
16617 }
16618 else if (dtype == 'L')
16619 {
16620 for (const auto& el : value.at(key))
16621 {
16622 write_number(static_cast<std::int64_t>(el.m_value.number_integer), true);
16623 }
16624 }
16625 else if (dtype == 'd')
16626 {
16627 for (const auto& el : value.at(key))
16628 {
16629 write_number(static_cast<float>(el.m_value.number_float), true);
16630 }
16631 }
16632 else if (dtype == 'D')
16633 {
16634 for (const auto& el : value.at(key))
16635 {
16636 write_number(static_cast<double>(el.m_value.number_float), true);
16637 }
16638 }
16639 return false;
16640 }
16641
16643 // Utility functions //
16645
16646 /*
16647 @brief write a number to output input
16648 @param[in] n number of type @a NumberType
16649 @param[in] OutputIsLittleEndian Set to true if output data is
16650 required to be little endian
16651 @tparam NumberType the type of the number
16652
16653 @note This function needs to respect the system's endianness, because bytes
16654 in CBOR, MessagePack, and UBJSON are stored in network order (big
16655 endian) and therefore need reordering on little endian systems.
16656 On the other hand, BSON and BJData use little endian and should reorder
16657 on big endian systems.
16658 */
16659 template<typename NumberType>
16660 void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16661 {
16662 // step 1: write number to array of length NumberType
16663 std::array<CharType, sizeof(NumberType)> vec{};
16664 std::memcpy(vec.data(), &n, sizeof(NumberType));
16665
16666 // step 2: write array to output (with possible reordering)
16667 if (is_little_endian != OutputIsLittleEndian)
16668 {
16669 // reverse byte order prior to conversion if necessary
16670 std::reverse(vec.begin(), vec.end());
16671 }
16672
16673 oa->write_characters(vec.data(), sizeof(NumberType));
16674 }
16675
16676 void write_compact_float(const number_float_t n, detail::input_format_t format)
16677 {
16678#ifdef __GNUC__
16679#pragma GCC diagnostic push
16680#pragma GCC diagnostic ignored "-Wfloat-equal"
16681#endif
16682 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16683 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16684 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16685 {
16686 oa->write_character(format == detail::input_format_t::cbor
16687 ? get_cbor_float_prefix(static_cast<float>(n))
16688 : get_msgpack_float_prefix(static_cast<float>(n)));
16689 write_number(static_cast<float>(n));
16690 }
16691 else
16692 {
16693 oa->write_character(format == detail::input_format_t::cbor
16694 ? get_cbor_float_prefix(n)
16695 : get_msgpack_float_prefix(n));
16696 write_number(n);
16697 }
16698#ifdef __GNUC__
16699#pragma GCC diagnostic pop
16700#endif
16701 }
16702
16703 public:
16704 // The following to_char_type functions are implement the conversion
16705 // between uint8_t and CharType. In case CharType is not unsigned,
16706 // such a conversion is required to allow values greater than 128.
16707 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16708 template < typename C = CharType,
16709 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
16710 static constexpr CharType to_char_type(std::uint8_t x) noexcept
16711 {
16712 return *reinterpret_cast<char*>(&x);
16713 }
16714
16715 template < typename C = CharType,
16716 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
16717 static CharType to_char_type(std::uint8_t x) noexcept
16718 {
16719 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16720 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16721 CharType result;
16722 std::memcpy(&result, &x, sizeof(x));
16723 return result;
16724 }
16725
16726 template<typename C = CharType,
16728 static constexpr CharType to_char_type(std::uint8_t x) noexcept
16729 {
16730 return x;
16731 }
16732
16733 template < typename InputCharType, typename C = CharType,
16734 enable_if_t <
16735 std::is_signed<C>::value &&
16736 std::is_signed<char>::value &&
16737 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
16738 > * = nullptr >
16739 static constexpr CharType to_char_type(InputCharType x) noexcept
16740 {
16741 return x;
16742 }
16743
16744 private:
16746 const bool is_little_endian = little_endianness();
16747
16749 output_adapter_t<CharType> oa = nullptr;
16750};
16751
16752} // namespace detail
16754
16755// #include <nlohmann/detail/output/output_adapters.hpp>
16756
16757// #include <nlohmann/detail/output/serializer.hpp>
16758// __ _____ _____ _____
16759// __| | __| | | | JSON for Modern C++
16760// | | |__ | | | | | | version 3.11.2
16761// |_____|_____|_____|_|___| https://github.com/nlohmann/json
16762//
16763// SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
16764// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16765// SPDX-License-Identifier: MIT
16766
16767
16768
16769#include <algorithm> // reverse, remove, fill, find, none_of
16770#include <array> // array
16771#include <clocale> // localeconv, lconv
16772#include <cmath> // labs, isfinite, isnan, signbit
16773#include <cstddef> // size_t, ptrdiff_t
16774#include <cstdint> // uint8_t
16775#include <cstdio> // snprintf
16776#include <limits> // numeric_limits
16777#include <string> // string, char_traits
16778#include <iomanip> // setfill, setw
16779#include <type_traits> // is_same
16780#include <utility> // move
16781
16782// #include <nlohmann/detail/conversions/to_chars.hpp>
16783// __ _____ _____ _____
16784// __| | __| | | | JSON for Modern C++
16785// | | |__ | | | | | | version 3.11.2
16786// |_____|_____|_____|_|___| https://github.com/nlohmann/json
16787//
16788// SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
16789// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
16790// SPDX-License-Identifier: MIT
16791
16792
16793
16794#include <array> // array
16795#include <cmath> // signbit, isfinite
16796#include <cstdint> // intN_t, uintN_t
16797#include <cstring> // memcpy, memmove
16798#include <limits> // numeric_limits
16799#include <type_traits> // conditional
16800
16801// #include <nlohmann/detail/macro_scope.hpp>
16802
16803
16805namespace detail
16806{
16807
16827namespace dtoa_impl
16828{
16829
16830template<typename Target, typename Source>
16831Target reinterpret_bits(const Source source)
16832{
16833 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16834
16835 Target target;
16836 std::memcpy(&target, &source, sizeof(Source));
16837 return target;
16838}
16839
16840struct diyfp // f * 2^e
16841{
16842 static constexpr int kPrecision = 64; // = q
16843
16844 std::uint64_t f = 0;
16845 int e = 0;
16846
16847 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16848
16853 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16854 {
16855 JSON_ASSERT(x.e == y.e);
16856 JSON_ASSERT(x.f >= y.f);
16857
16858 return {x.f - y.f, x.e};
16859 }
16860
16865 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16866 {
16867 static_assert(kPrecision == 64, "internal error");
16868
16869 // Computes:
16870 // f = round((x.f * y.f) / 2^q)
16871 // e = x.e + y.e + q
16872
16873 // Emulate the 64-bit * 64-bit multiplication:
16874 //
16875 // p = u * v
16876 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
16877 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
16878 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
16879 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
16880 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
16881 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
16882 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
16883 //
16884 // (Since Q might be larger than 2^32 - 1)
16885 //
16886 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
16887 //
16888 // (Q_hi + H does not overflow a 64-bit int)
16889 //
16890 // = p_lo + 2^64 p_hi
16891
16892 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
16893 const std::uint64_t u_hi = x.f >> 32u;
16894 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
16895 const std::uint64_t v_hi = y.f >> 32u;
16896
16897 const std::uint64_t p0 = u_lo * v_lo;
16898 const std::uint64_t p1 = u_lo * v_hi;
16899 const std::uint64_t p2 = u_hi * v_lo;
16900 const std::uint64_t p3 = u_hi * v_hi;
16901
16902 const std::uint64_t p0_hi = p0 >> 32u;
16903 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
16904 const std::uint64_t p1_hi = p1 >> 32u;
16905 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
16906 const std::uint64_t p2_hi = p2 >> 32u;
16907
16908 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
16909
16910 // The full product might now be computed as
16911 //
16912 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
16913 // p_lo = p0_lo + (Q << 32)
16914 //
16915 // But in this particular case here, the full p_lo is not required.
16916 // Effectively we only need to add the highest bit in p_lo to p_hi (and
16917 // Q_hi + 1 does not overflow).
16918
16919 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
16920
16921 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
16922
16923 return {h, x.e + y.e + 64};
16924 }
16925
16930 static diyfp normalize(diyfp x) noexcept
16931 {
16932 JSON_ASSERT(x.f != 0);
16933
16934 while ((x.f >> 63u) == 0)
16935 {
16936 x.f <<= 1u;
16937 x.e--;
16938 }
16939
16940 return x;
16941 }
16942
16947 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
16948 {
16949 const int delta = x.e - target_exponent;
16950
16951 JSON_ASSERT(delta >= 0);
16952 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16953
16954 return {x.f << delta, target_exponent};
16955 }
16956};
16957
16959{
16963};
16964
16971template<typename FloatType>
16973{
16974 JSON_ASSERT(std::isfinite(value));
16975 JSON_ASSERT(value > 0);
16976
16977 // Convert the IEEE representation into a diyfp.
16978 //
16979 // If v is denormal:
16980 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
16981 // If v is normalized:
16982 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
16983
16984 static_assert(std::numeric_limits<FloatType>::is_iec559,
16985 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
16986
16987 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
16988 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
16989 constexpr int kMinExp = 1 - kBias;
16990 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
16991
16992 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
16993
16994 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
16995 const std::uint64_t E = bits >> (kPrecision - 1);
16996 const std::uint64_t F = bits & (kHiddenBit - 1);
16997
16998 const bool is_denormal = E == 0;
16999 const diyfp v = is_denormal
17000 ? diyfp(F, kMinExp)
17001 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17002
17003 // Compute the boundaries m- and m+ of the floating-point value
17004 // v = f * 2^e.
17005 //
17006 // Determine v- and v+, the floating-point predecessor and successor if v,
17007 // respectively.
17008 //
17009 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17010 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17011 //
17012 // v+ = v + 2^e
17013 //
17014 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17015 // between m- and m+ round to v, regardless of how the input rounding
17016 // algorithm breaks ties.
17017 //
17018 // ---+-------------+-------------+-------------+-------------+--- (A)
17019 // v- m- v m+ v+
17020 //
17021 // -----------------+------+------+-------------+-------------+--- (B)
17022 // v- m- v m+ v+
17023
17024 const bool lower_boundary_is_closer = F == 0 && E > 1;
17025 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
17026 const diyfp m_minus = lower_boundary_is_closer
17027 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
17028 : diyfp(2 * v.f - 1, v.e - 1); // (A)
17029
17030 // Determine the normalized w+ = m+.
17031 const diyfp w_plus = diyfp::normalize(m_plus);
17032
17033 // Determine w- = m- such that e_(w-) = e_(w+).
17034 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17035
17036 return {diyfp::normalize(v), w_minus, w_plus};
17037}
17038
17039// Given normalized diyfp w, Grisu needs to find a (normalized) cached
17040// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17041// within a certain range [alpha, gamma] (Definition 3.2 from [1])
17042//
17043// alpha <= e = e_c + e_w + q <= gamma
17044//
17045// or
17046//
17047// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17048// <= f_c * f_w * 2^gamma
17049//
17050// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17051//
17052// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17053//
17054// or
17055//
17056// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17057//
17058// The choice of (alpha,gamma) determines the size of the table and the form of
17059// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17060// in practice:
17061//
17062// The idea is to cut the number c * w = f * 2^e into two parts, which can be
17063// processed independently: An integral part p1, and a fractional part p2:
17064//
17065// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17066// = (f div 2^-e) + (f mod 2^-e) * 2^e
17067// = p1 + p2 * 2^e
17068//
17069// The conversion of p1 into decimal form requires a series of divisions and
17070// modulos by (a power of) 10. These operations are faster for 32-bit than for
17071// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17072// achieved by choosing
17073//
17074// -e >= 32 or e <= -32 := gamma
17075//
17076// In order to convert the fractional part
17077//
17078// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
17079//
17080// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
17081// d[-i] are extracted in order:
17082//
17083// (10 * p2) div 2^-e = d[-1]
17084// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
17085//
17086// The multiplication by 10 must not overflow. It is sufficient to choose
17087//
17088// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
17089//
17090// Since p2 = f mod 2^-e < 2^-e,
17091//
17092// -e <= 60 or e >= -60 := alpha
17093
17094constexpr int kAlpha = -60;
17095constexpr int kGamma = -32;
17096
17097struct cached_power // c = f * 2^e ~= 10^k
17098{
17099 std::uint64_t f;
17100 int e;
17101 int k;
17102};
17103
17112{
17113 // Now
17114 //
17115 // alpha <= e_c + e + q <= gamma (1)
17116 // ==> f_c * 2^alpha <= c * 2^e * 2^q
17117 //
17118 // and since the c's are normalized, 2^(q-1) <= f_c,
17119 //
17120 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
17121 // ==> 2^(alpha - e - 1) <= c
17122 //
17123 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
17124 //
17125 // k = ceil( log_10( 2^(alpha - e - 1) ) )
17126 // = ceil( (alpha - e - 1) * log_10(2) )
17127 //
17128 // From the paper:
17129 // "In theory the result of the procedure could be wrong since c is rounded,
17130 // and the computation itself is approximated [...]. In practice, however,
17131 // this simple function is sufficient."
17132 //
17133 // For IEEE double precision floating-point numbers converted into
17134 // normalized diyfp's w = f * 2^e, with q = 64,
17135 //
17136 // e >= -1022 (min IEEE exponent)
17137 // -52 (p - 1)
17138 // -52 (p - 1, possibly normalize denormal IEEE numbers)
17139 // -11 (normalize the diyfp)
17140 // = -1137
17141 //
17142 // and
17143 //
17144 // e <= +1023 (max IEEE exponent)
17145 // -52 (p - 1)
17146 // -11 (normalize the diyfp)
17147 // = 960
17148 //
17149 // This binary exponent range [-1137,960] results in a decimal exponent
17150 // range [-307,324]. One does not need to store a cached power for each
17151 // k in this range. For each such k it suffices to find a cached power
17152 // such that the exponent of the product lies in [alpha,gamma].
17153 // This implies that the difference of the decimal exponents of adjacent
17154 // table entries must be less than or equal to
17155 //
17156 // floor( (gamma - alpha) * log_10(2) ) = 8.
17157 //
17158 // (A smaller distance gamma-alpha would require a larger table.)
17159
17160 // NB:
17161 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
17162
17163 constexpr int kCachedPowersMinDecExp = -300;
17164 constexpr int kCachedPowersDecStep = 8;
17165
17166 static constexpr std::array<cached_power, 79> kCachedPowers =
17167 {
17168 {
17169 { 0xAB70FE17C79AC6CA, -1060, -300 },
17170 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
17171 { 0xBE5691EF416BD60C, -1007, -284 },
17172 { 0x8DD01FAD907FFC3C, -980, -276 },
17173 { 0xD3515C2831559A83, -954, -268 },
17174 { 0x9D71AC8FADA6C9B5, -927, -260 },
17175 { 0xEA9C227723EE8BCB, -901, -252 },
17176 { 0xAECC49914078536D, -874, -244 },
17177 { 0x823C12795DB6CE57, -847, -236 },
17178 { 0xC21094364DFB5637, -821, -228 },
17179 { 0x9096EA6F3848984F, -794, -220 },
17180 { 0xD77485CB25823AC7, -768, -212 },
17181 { 0xA086CFCD97BF97F4, -741, -204 },
17182 { 0xEF340A98172AACE5, -715, -196 },
17183 { 0xB23867FB2A35B28E, -688, -188 },
17184 { 0x84C8D4DFD2C63F3B, -661, -180 },
17185 { 0xC5DD44271AD3CDBA, -635, -172 },
17186 { 0x936B9FCEBB25C996, -608, -164 },
17187 { 0xDBAC6C247D62A584, -582, -156 },
17188 { 0xA3AB66580D5FDAF6, -555, -148 },
17189 { 0xF3E2F893DEC3F126, -529, -140 },
17190 { 0xB5B5ADA8AAFF80B8, -502, -132 },
17191 { 0x87625F056C7C4A8B, -475, -124 },
17192 { 0xC9BCFF6034C13053, -449, -116 },
17193 { 0x964E858C91BA2655, -422, -108 },
17194 { 0xDFF9772470297EBD, -396, -100 },
17195 { 0xA6DFBD9FB8E5B88F, -369, -92 },
17196 { 0xF8A95FCF88747D94, -343, -84 },
17197 { 0xB94470938FA89BCF, -316, -76 },
17198 { 0x8A08F0F8BF0F156B, -289, -68 },
17199 { 0xCDB02555653131B6, -263, -60 },
17200 { 0x993FE2C6D07B7FAC, -236, -52 },
17201 { 0xE45C10C42A2B3B06, -210, -44 },
17202 { 0xAA242499697392D3, -183, -36 },
17203 { 0xFD87B5F28300CA0E, -157, -28 },
17204 { 0xBCE5086492111AEB, -130, -20 },
17205 { 0x8CBCCC096F5088CC, -103, -12 },
17206 { 0xD1B71758E219652C, -77, -4 },
17207 { 0x9C40000000000000, -50, 4 },
17208 { 0xE8D4A51000000000, -24, 12 },
17209 { 0xAD78EBC5AC620000, 3, 20 },
17210 { 0x813F3978F8940984, 30, 28 },
17211 { 0xC097CE7BC90715B3, 56, 36 },
17212 { 0x8F7E32CE7BEA5C70, 83, 44 },
17213 { 0xD5D238A4ABE98068, 109, 52 },
17214 { 0x9F4F2726179A2245, 136, 60 },
17215 { 0xED63A231D4C4FB27, 162, 68 },
17216 { 0xB0DE65388CC8ADA8, 189, 76 },
17217 { 0x83C7088E1AAB65DB, 216, 84 },
17218 { 0xC45D1DF942711D9A, 242, 92 },
17219 { 0x924D692CA61BE758, 269, 100 },
17220 { 0xDA01EE641A708DEA, 295, 108 },
17221 { 0xA26DA3999AEF774A, 322, 116 },
17222 { 0xF209787BB47D6B85, 348, 124 },
17223 { 0xB454E4A179DD1877, 375, 132 },
17224 { 0x865B86925B9BC5C2, 402, 140 },
17225 { 0xC83553C5C8965D3D, 428, 148 },
17226 { 0x952AB45CFA97A0B3, 455, 156 },
17227 { 0xDE469FBD99A05FE3, 481, 164 },
17228 { 0xA59BC234DB398C25, 508, 172 },
17229 { 0xF6C69A72A3989F5C, 534, 180 },
17230 { 0xB7DCBF5354E9BECE, 561, 188 },
17231 { 0x88FCF317F22241E2, 588, 196 },
17232 { 0xCC20CE9BD35C78A5, 614, 204 },
17233 { 0x98165AF37B2153DF, 641, 212 },
17234 { 0xE2A0B5DC971F303A, 667, 220 },
17235 { 0xA8D9D1535CE3B396, 694, 228 },
17236 { 0xFB9B7CD9A4A7443C, 720, 236 },
17237 { 0xBB764C4CA7A44410, 747, 244 },
17238 { 0x8BAB8EEFB6409C1A, 774, 252 },
17239 { 0xD01FEF10A657842C, 800, 260 },
17240 { 0x9B10A4E5E9913129, 827, 268 },
17241 { 0xE7109BFBA19C0C9D, 853, 276 },
17242 { 0xAC2820D9623BF429, 880, 284 },
17243 { 0x80444B5E7AA7CF85, 907, 292 },
17244 { 0xBF21E44003ACDD2D, 933, 300 },
17245 { 0x8E679C2F5E44FF8F, 960, 308 },
17246 { 0xD433179D9C8CB841, 986, 316 },
17247 { 0x9E19DB92B4E31BA9, 1013, 324 },
17248 }
17249 };
17250
17251 // This computation gives exactly the same results for k as
17252 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
17253 // for |e| <= 1500, but doesn't require floating-point operations.
17254 // NB: log_10(2) ~= 78913 / 2^18
17255 JSON_ASSERT(e >= -1500);
17256 JSON_ASSERT(e <= 1500);
17257 const int f = kAlpha - e - 1;
17258 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
17259
17260 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
17261 JSON_ASSERT(index >= 0);
17262 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
17263
17264 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
17265 JSON_ASSERT(kAlpha <= cached.e + e + 64);
17266 JSON_ASSERT(kGamma >= cached.e + e + 64);
17267
17268 return cached;
17269}
17270
17275inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
17276{
17277 // LCOV_EXCL_START
17278 if (n >= 1000000000)
17279 {
17280 pow10 = 1000000000;
17281 return 10;
17282 }
17283 // LCOV_EXCL_STOP
17284 if (n >= 100000000)
17285 {
17286 pow10 = 100000000;
17287 return 9;
17288 }
17289 if (n >= 10000000)
17290 {
17291 pow10 = 10000000;
17292 return 8;
17293 }
17294 if (n >= 1000000)
17295 {
17296 pow10 = 1000000;
17297 return 7;
17298 }
17299 if (n >= 100000)
17300 {
17301 pow10 = 100000;
17302 return 6;
17303 }
17304 if (n >= 10000)
17305 {
17306 pow10 = 10000;
17307 return 5;
17308 }
17309 if (n >= 1000)
17310 {
17311 pow10 = 1000;
17312 return 4;
17313 }
17314 if (n >= 100)
17315 {
17316 pow10 = 100;
17317 return 3;
17318 }
17319 if (n >= 10)
17320 {
17321 pow10 = 10;
17322 return 2;
17323 }
17324
17325 pow10 = 1;
17326 return 1;
17327}
17328
17329inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
17330 std::uint64_t rest, std::uint64_t ten_k)
17331{
17332 JSON_ASSERT(len >= 1);
17333 JSON_ASSERT(dist <= delta);
17334 JSON_ASSERT(rest <= delta);
17335 JSON_ASSERT(ten_k > 0);
17336
17337 // <--------------------------- delta ---->
17338 // <---- dist --------->
17339 // --------------[------------------+-------------------]--------------
17340 // M- w M+
17341 //
17342 // ten_k
17343 // <------>
17344 // <---- rest ---->
17345 // --------------[------------------+----+--------------]--------------
17346 // w V
17347 // = buf * 10^k
17348 //
17349 // ten_k represents a unit-in-the-last-place in the decimal representation
17350 // stored in buf.
17351 // Decrement buf by ten_k while this takes buf closer to w.
17352
17353 // The tests are written in this order to avoid overflow in unsigned
17354 // integer arithmetic.
17355
17356 while (rest < dist
17357 && delta - rest >= ten_k
17358 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
17359 {
17360 JSON_ASSERT(buf[len - 1] != '0');
17361 buf[len - 1]--;
17362 rest += ten_k;
17363 }
17364}
17365
17370inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
17371 diyfp M_minus, diyfp w, diyfp M_plus)
17372{
17373 static_assert(kAlpha >= -60, "internal error");
17374 static_assert(kGamma <= -32, "internal error");
17375
17376 // Generates the digits (and the exponent) of a decimal floating-point
17377 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
17378 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
17379 //
17380 // <--------------------------- delta ---->
17381 // <---- dist --------->
17382 // --------------[------------------+-------------------]--------------
17383 // M- w M+
17384 //
17385 // Grisu2 generates the digits of M+ from left to right and stops as soon as
17386 // V is in [M-,M+].
17387
17388 JSON_ASSERT(M_plus.e >= kAlpha);
17389 JSON_ASSERT(M_plus.e <= kGamma);
17390
17391 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
17392 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
17393
17394 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
17395 //
17396 // M+ = f * 2^e
17397 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
17398 // = ((p1 ) * 2^-e + (p2 )) * 2^e
17399 // = p1 + p2 * 2^e
17400
17401 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
17402
17403 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.)
17404 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
17405
17406 // 1)
17407 //
17408 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
17409
17410 JSON_ASSERT(p1 > 0);
17411
17412 std::uint32_t pow10{};
17413 const int k = find_largest_pow10(p1, pow10);
17414
17415 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
17416 //
17417 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
17418 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
17419 //
17420 // M+ = p1 + p2 * 2^e
17421 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
17422 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
17423 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
17424 //
17425 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
17426 //
17427 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
17428 //
17429 // but stop as soon as
17430 //
17431 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
17432
17433 int n = k;
17434 while (n > 0)
17435 {
17436 // Invariants:
17437 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
17438 // pow10 = 10^(n-1) <= p1 < 10^n
17439 //
17440 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
17441 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
17442 //
17443 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
17444 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
17445 //
17446 JSON_ASSERT(d <= 9);
17447 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17448 //
17449 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
17450 //
17451 p1 = r;
17452 n--;
17453 //
17454 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
17455 // pow10 = 10^n
17456 //
17457
17458 // Now check if enough digits have been generated.
17459 // Compute
17460 //
17461 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
17462 //
17463 // Note:
17464 // Since rest and delta share the same exponent e, it suffices to
17465 // compare the significands.
17466 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
17467 if (rest <= delta)
17468 {
17469 // V = buffer * 10^n, with M- <= V <= M+.
17470
17471 decimal_exponent += n;
17472
17473 // We may now just stop. But instead look if the buffer could be
17474 // decremented to bring V closer to w.
17475 //
17476 // pow10 = 10^n is now 1 ulp in the decimal representation V.
17477 // The rounding procedure works with diyfp's with an implicit
17478 // exponent of e.
17479 //
17480 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
17481 //
17482 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
17483 grisu2_round(buffer, length, dist, delta, rest, ten_n);
17484
17485 return;
17486 }
17487
17488 pow10 /= 10;
17489 //
17490 // pow10 = 10^(n-1) <= p1 < 10^n
17491 // Invariants restored.
17492 }
17493
17494 // 2)
17495 //
17496 // The digits of the integral part have been generated:
17497 //
17498 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
17499 // = buffer + p2 * 2^e
17500 //
17501 // Now generate the digits of the fractional part p2 * 2^e.
17502 //
17503 // Note:
17504 // No decimal point is generated: the exponent is adjusted instead.
17505 //
17506 // p2 actually represents the fraction
17507 //
17508 // p2 * 2^e
17509 // = p2 / 2^-e
17510 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
17511 //
17512 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
17513 //
17514 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
17515 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
17516 //
17517 // using
17518 //
17519 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
17520 // = ( d) * 2^-e + ( r)
17521 //
17522 // or
17523 // 10^m * p2 * 2^e = d + r * 2^e
17524 //
17525 // i.e.
17526 //
17527 // M+ = buffer + p2 * 2^e
17528 // = buffer + 10^-m * (d + r * 2^e)
17529 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
17530 //
17531 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
17532
17533 JSON_ASSERT(p2 > delta);
17534
17535 int m = 0;
17536 for (;;)
17537 {
17538 // Invariant:
17539 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
17540 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
17541 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
17542 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
17543 //
17544 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
17545 p2 *= 10;
17546 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
17547 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
17548 //
17549 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
17550 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
17551 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
17552 //
17553 JSON_ASSERT(d <= 9);
17554 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17555 //
17556 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
17557 //
17558 p2 = r;
17559 m++;
17560 //
17561 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
17562 // Invariant restored.
17563
17564 // Check if enough digits have been generated.
17565 //
17566 // 10^-m * p2 * 2^e <= delta * 2^e
17567 // p2 * 2^e <= 10^m * delta * 2^e
17568 // p2 <= 10^m * delta
17569 delta *= 10;
17570 dist *= 10;
17571 if (p2 <= delta)
17572 {
17573 break;
17574 }
17575 }
17576
17577 // V = buffer * 10^-m, with M- <= V <= M+.
17578
17579 decimal_exponent -= m;
17580
17581 // 1 ulp in the decimal representation is now 10^-m.
17582 // Since delta and dist are now scaled by 10^m, we need to do the
17583 // same with ulp in order to keep the units in sync.
17584 //
17585 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
17586 //
17587 const std::uint64_t ten_m = one.f;
17588 grisu2_round(buffer, length, dist, delta, p2, ten_m);
17589
17590 // By construction this algorithm generates the shortest possible decimal
17591 // number (Loitsch, Theorem 6.2) which rounds back to w.
17592 // For an input number of precision p, at least
17593 //
17594 // N = 1 + ceil(p * log_10(2))
17595 //
17596 // decimal digits are sufficient to identify all binary floating-point
17597 // numbers (Matula, "In-and-Out conversions").
17598 // This implies that the algorithm does not produce more than N decimal
17599 // digits.
17600 //
17601 // N = 17 for p = 53 (IEEE double precision)
17602 // N = 9 for p = 24 (IEEE single precision)
17603}
17604
17611inline void grisu2(char* buf, int& len, int& decimal_exponent,
17612 diyfp m_minus, diyfp v, diyfp m_plus)
17613{
17614 JSON_ASSERT(m_plus.e == m_minus.e);
17615 JSON_ASSERT(m_plus.e == v.e);
17616
17617 // --------(-----------------------+-----------------------)-------- (A)
17618 // m- v m+
17619 //
17620 // --------------------(-----------+-----------------------)-------- (B)
17621 // m- v m+
17622 //
17623 // First scale v (and m- and m+) such that the exponent is in the range
17624 // [alpha, gamma].
17625
17626 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17627
17628 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17629
17630 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17631 const diyfp w = diyfp::mul(v, c_minus_k);
17632 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17633 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17634
17635 // ----(---+---)---------------(---+---)---------------(---+---)----
17636 // w- w w+
17637 // = c*m- = c*v = c*m+
17638 //
17639 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17640 // w+ are now off by a small amount.
17641 // In fact:
17642 //
17643 // w - v * 10^k < 1 ulp
17644 //
17645 // To account for this inaccuracy, add resp. subtract 1 ulp.
17646 //
17647 // --------+---[---------------(---+---)---------------]---+--------
17648 // w- M- w M+ w+
17649 //
17650 // Now any number in [M-, M+] (bounds included) will round to w when input,
17651 // regardless of how the input rounding algorithm breaks ties.
17652 //
17653 // And digit_gen generates the shortest possible such number in [M-, M+].
17654 // Note that this does not mean that Grisu2 always generates the shortest
17655 // possible number in the interval (m-, m+).
17656 const diyfp M_minus(w_minus.f + 1, w_minus.e);
17657 const diyfp M_plus (w_plus.f - 1, w_plus.e );
17658
17659 decimal_exponent = -cached.k; // = -(-k) = k
17660
17661 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17662}
17663
17669template<typename FloatType>
17671void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17672{
17673 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17674 "internal error: not enough precision");
17675
17676 JSON_ASSERT(std::isfinite(value));
17677 JSON_ASSERT(value > 0);
17678
17679 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17680 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17681 // decimal representations are not exactly "short".
17682 //
17683 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17684 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17685 // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17686 // does.
17687 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17688 // representation using the corresponding std::from_chars function recovers value exactly". That
17689 // indicates that single precision floating-point numbers should be recovered using
17690 // 'std::strtof'.
17691 //
17692 // NB: If the neighbors are computed for single-precision numbers, there is a single float
17693 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17694 // value is off by 1 ulp.
17695#if 0
17696 const boundaries w = compute_boundaries(static_cast<double>(value));
17697#else
17699#endif
17700
17701 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17702}
17703
17711inline char* append_exponent(char* buf, int e)
17712{
17713 JSON_ASSERT(e > -1000);
17714 JSON_ASSERT(e < 1000);
17715
17716 if (e < 0)
17717 {
17718 e = -e;
17719 *buf++ = '-';
17720 }
17721 else
17722 {
17723 *buf++ = '+';
17724 }
17725
17726 auto k = static_cast<std::uint32_t>(e);
17727 if (k < 10)
17728 {
17729 // Always print at least two digits in the exponent.
17730 // This is for compatibility with printf("%g").
17731 *buf++ = '0';
17732 *buf++ = static_cast<char>('0' + k);
17733 }
17734 else if (k < 100)
17735 {
17736 *buf++ = static_cast<char>('0' + k / 10);
17737 k %= 10;
17738 *buf++ = static_cast<char>('0' + k);
17739 }
17740 else
17741 {
17742 *buf++ = static_cast<char>('0' + k / 100);
17743 k %= 100;
17744 *buf++ = static_cast<char>('0' + k / 10);
17745 k %= 10;
17746 *buf++ = static_cast<char>('0' + k);
17747 }
17748
17749 return buf;
17750}
17751
17763inline char* format_buffer(char* buf, int len, int decimal_exponent,
17764 int min_exp, int max_exp)
17765{
17766 JSON_ASSERT(min_exp < 0);
17767 JSON_ASSERT(max_exp > 0);
17768
17769 const int k = len;
17770 const int n = len + decimal_exponent;
17771
17772 // v = buf * 10^(n-k)
17773 // k is the length of the buffer (number of decimal digits)
17774 // n is the position of the decimal point relative to the start of the buffer.
17775
17776 if (k <= n && n <= max_exp)
17777 {
17778 // digits[000]
17779 // len <= max_exp + 2
17780
17781 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17782 // Make it look like a floating-point number (#362, #378)
17783 buf[n + 0] = '.';
17784 buf[n + 1] = '0';
17785 return buf + (static_cast<size_t>(n) + 2);
17786 }
17787
17788 if (0 < n && n <= max_exp)
17789 {
17790 // dig.its
17791 // len <= max_digits10 + 1
17792
17793 JSON_ASSERT(k > n);
17794
17795 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17796 buf[n] = '.';
17797 return buf + (static_cast<size_t>(k) + 1U);
17798 }
17799
17800 if (min_exp < n && n <= 0)
17801 {
17802 // 0.[000]digits
17803 // len <= 2 + (-min_exp - 1) + max_digits10
17804
17805 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17806 buf[0] = '0';
17807 buf[1] = '.';
17808 std::memset(buf + 2, '0', static_cast<size_t>(-n));
17809 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17810 }
17811
17812 if (k == 1)
17813 {
17814 // dE+123
17815 // len <= 1 + 5
17816
17817 buf += 1;
17818 }
17819 else
17820 {
17821 // d.igitsE+123
17822 // len <= max_digits10 + 1 + 5
17823
17824 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17825 buf[1] = '.';
17826 buf += 1 + static_cast<size_t>(k);
17827 }
17828
17829 *buf++ = 'e';
17830 return append_exponent(buf, n - 1);
17831}
17832
17833} // namespace dtoa_impl
17834
17845template<typename FloatType>
17848char* to_chars(char* first, const char* last, FloatType value)
17849{
17850 static_cast<void>(last); // maybe unused - fix warning
17851 JSON_ASSERT(std::isfinite(value));
17852
17853 // Use signbit(value) instead of (value < 0) since signbit works for -0.
17854 if (std::signbit(value))
17855 {
17856 value = -value;
17857 *first++ = '-';
17858 }
17859
17860#ifdef __GNUC__
17861#pragma GCC diagnostic push
17862#pragma GCC diagnostic ignored "-Wfloat-equal"
17863#endif
17864 if (value == 0) // +-0
17865 {
17866 *first++ = '0';
17867 // Make it look like a floating-point number (#362, #378)
17868 *first++ = '.';
17869 *first++ = '0';
17870 return first;
17871 }
17872#ifdef __GNUC__
17873#pragma GCC diagnostic pop
17874#endif
17875
17876 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
17877
17878 // Compute v = buffer * 10^decimal_exponent.
17879 // The decimal digits are stored in the buffer, which needs to be interpreted
17880 // as an unsigned decimal integer.
17881 // len is the length of the buffer, i.e. the number of decimal digits.
17882 int len = 0;
17883 int decimal_exponent = 0;
17884 dtoa_impl::grisu2(first, len, decimal_exponent, value);
17885
17886 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
17887
17888 // Format the buffer like printf("%.*g", prec, value)
17889 constexpr int kMinExp = -4;
17890 // Use digits10 here to increase compatibility with version 2.
17891 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
17892
17893 JSON_ASSERT(last - first >= kMaxExp + 2);
17894 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
17895 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
17896
17897 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
17898}
17899
17900} // namespace detail
17902
17903// #include <nlohmann/detail/exceptions.hpp>
17904
17905// #include <nlohmann/detail/macro_scope.hpp>
17906
17907// #include <nlohmann/detail/meta/cpp_future.hpp>
17908
17909// #include <nlohmann/detail/output/binary_writer.hpp>
17910
17911// #include <nlohmann/detail/output/output_adapters.hpp>
17912
17913// #include <nlohmann/detail/string_concat.hpp>
17914
17915// #include <nlohmann/detail/value_t.hpp>
17916
17917
17919namespace detail
17920{
17921
17923// serialization //
17925
17928{
17929 strict,
17930 replace,
17931 ignore
17932};
17933
17934template<typename BasicJsonType>
17936{
17937 using string_t = typename BasicJsonType::string_t;
17938 using number_float_t = typename BasicJsonType::number_float_t;
17939 using number_integer_t = typename BasicJsonType::number_integer_t;
17940 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17941 using binary_char_t = typename BasicJsonType::binary_t::value_type;
17942 static constexpr std::uint8_t UTF8_ACCEPT = 0;
17943 static constexpr std::uint8_t UTF8_REJECT = 1;
17944
17945 public:
17953 : o(std::move(s))
17954 , loc(std::localeconv())
17955 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
17956 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
17957 , indent_char(ichar)
17959 , error_handler(error_handler_)
17960 {}
17961
17962 // delete because of pointer members
17963 serializer(const serializer&) = delete;
17967 ~serializer() = default;
17968
17991 void dump(const BasicJsonType& val,
17992 const bool pretty_print,
17993 const bool ensure_ascii,
17994 const unsigned int indent_step,
17995 const unsigned int current_indent = 0)
17996 {
17997 switch (val.m_type)
17998 {
17999 case value_t::object:
18000 {
18001 if (val.m_value.object->empty())
18002 {
18003 o->write_characters("{}", 2);
18004 return;
18005 }
18006
18007 if (pretty_print)
18008 {
18009 o->write_characters("{\n", 2);
18010
18011 // variable to hold indentation for recursive calls
18012 const auto new_indent = current_indent + indent_step;
18013 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18014 {
18015 indent_string.resize(indent_string.size() * 2, ' ');
18016 }
18017
18018 // first n-1 elements
18019 auto i = val.m_value.object->cbegin();
18020 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
18021 {
18022 o->write_characters(indent_string.c_str(), new_indent);
18023 o->write_character('\"');
18024 dump_escaped(i->first, ensure_ascii);
18025 o->write_characters("\": ", 3);
18026 dump(i->second, true, ensure_ascii, indent_step, new_indent);
18027 o->write_characters(",\n", 2);
18028 }
18029
18030 // last element
18031 JSON_ASSERT(i != val.m_value.object->cend());
18032 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
18033 o->write_characters(indent_string.c_str(), new_indent);
18034 o->write_character('\"');
18035 dump_escaped(i->first, ensure_ascii);
18036 o->write_characters("\": ", 3);
18037 dump(i->second, true, ensure_ascii, indent_step, new_indent);
18038
18039 o->write_character('\n');
18040 o->write_characters(indent_string.c_str(), current_indent);
18041 o->write_character('}');
18042 }
18043 else
18044 {
18045 o->write_character('{');
18046
18047 // first n-1 elements
18048 auto i = val.m_value.object->cbegin();
18049 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
18050 {
18051 o->write_character('\"');
18052 dump_escaped(i->first, ensure_ascii);
18053 o->write_characters("\":", 2);
18054 dump(i->second, false, ensure_ascii, indent_step, current_indent);
18055 o->write_character(',');
18056 }
18057
18058 // last element
18059 JSON_ASSERT(i != val.m_value.object->cend());
18060 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
18061 o->write_character('\"');
18062 dump_escaped(i->first, ensure_ascii);
18063 o->write_characters("\":", 2);
18064 dump(i->second, false, ensure_ascii, indent_step, current_indent);
18065
18066 o->write_character('}');
18067 }
18068
18069 return;
18070 }
18071
18072 case value_t::array:
18073 {
18074 if (val.m_value.array->empty())
18075 {
18076 o->write_characters("[]", 2);
18077 return;
18078 }
18079
18080 if (pretty_print)
18081 {
18082 o->write_characters("[\n", 2);
18083
18084 // variable to hold indentation for recursive calls
18085 const auto new_indent = current_indent + indent_step;
18086 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18087 {
18088 indent_string.resize(indent_string.size() * 2, ' ');
18089 }
18090
18091 // first n-1 elements
18092 for (auto i = val.m_value.array->cbegin();
18093 i != val.m_value.array->cend() - 1; ++i)
18094 {
18095 o->write_characters(indent_string.c_str(), new_indent);
18096 dump(*i, true, ensure_ascii, indent_step, new_indent);
18097 o->write_characters(",\n", 2);
18098 }
18099
18100 // last element
18101 JSON_ASSERT(!val.m_value.array->empty());
18102 o->write_characters(indent_string.c_str(), new_indent);
18103 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
18104
18105 o->write_character('\n');
18106 o->write_characters(indent_string.c_str(), current_indent);
18107 o->write_character(']');
18108 }
18109 else
18110 {
18111 o->write_character('[');
18112
18113 // first n-1 elements
18114 for (auto i = val.m_value.array->cbegin();
18115 i != val.m_value.array->cend() - 1; ++i)
18116 {
18117 dump(*i, false, ensure_ascii, indent_step, current_indent);
18118 o->write_character(',');
18119 }
18120
18121 // last element
18122 JSON_ASSERT(!val.m_value.array->empty());
18123 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
18124
18125 o->write_character(']');
18126 }
18127
18128 return;
18129 }
18130
18131 case value_t::string:
18132 {
18133 o->write_character('\"');
18134 dump_escaped(*val.m_value.string, ensure_ascii);
18135 o->write_character('\"');
18136 return;
18137 }
18138
18139 case value_t::binary:
18140 {
18141 if (pretty_print)
18142 {
18143 o->write_characters("{\n", 2);
18144
18145 // variable to hold indentation for recursive calls
18146 const auto new_indent = current_indent + indent_step;
18147 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18148 {
18149 indent_string.resize(indent_string.size() * 2, ' ');
18150 }
18151
18152 o->write_characters(indent_string.c_str(), new_indent);
18153
18154 o->write_characters("\"bytes\": [", 10);
18155
18156 if (!val.m_value.binary->empty())
18157 {
18158 for (auto i = val.m_value.binary->cbegin();
18159 i != val.m_value.binary->cend() - 1; ++i)
18160 {
18161 dump_integer(*i);
18162 o->write_characters(", ", 2);
18163 }
18164 dump_integer(val.m_value.binary->back());
18165 }
18166
18167 o->write_characters("],\n", 3);
18168 o->write_characters(indent_string.c_str(), new_indent);
18169
18170 o->write_characters("\"subtype\": ", 11);
18171 if (val.m_value.binary->has_subtype())
18172 {
18173 dump_integer(val.m_value.binary->subtype());
18174 }
18175 else
18176 {
18177 o->write_characters("null", 4);
18178 }
18179 o->write_character('\n');
18180 o->write_characters(indent_string.c_str(), current_indent);
18181 o->write_character('}');
18182 }
18183 else
18184 {
18185 o->write_characters("{\"bytes\":[", 10);
18186
18187 if (!val.m_value.binary->empty())
18188 {
18189 for (auto i = val.m_value.binary->cbegin();
18190 i != val.m_value.binary->cend() - 1; ++i)
18191 {
18192 dump_integer(*i);
18193 o->write_character(',');
18194 }
18195 dump_integer(val.m_value.binary->back());
18196 }
18197
18198 o->write_characters("],\"subtype\":", 12);
18199 if (val.m_value.binary->has_subtype())
18200 {
18201 dump_integer(val.m_value.binary->subtype());
18202 o->write_character('}');
18203 }
18204 else
18205 {
18206 o->write_characters("null}", 5);
18207 }
18208 }
18209 return;
18210 }
18211
18212 case value_t::boolean:
18213 {
18214 if (val.m_value.boolean)
18215 {
18216 o->write_characters("true", 4);
18217 }
18218 else
18219 {
18220 o->write_characters("false", 5);
18221 }
18222 return;
18223 }
18224
18226 {
18227 dump_integer(val.m_value.number_integer);
18228 return;
18229 }
18230
18232 {
18233 dump_integer(val.m_value.number_unsigned);
18234 return;
18235 }
18236
18238 {
18239 dump_float(val.m_value.number_float);
18240 return;
18241 }
18242
18243 case value_t::discarded:
18244 {
18245 o->write_characters("<discarded>", 11);
18246 return;
18247 }
18248
18249 case value_t::null:
18250 {
18251 o->write_characters("null", 4);
18252 return;
18253 }
18254
18255 default: // LCOV_EXCL_LINE
18256 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18257 }
18258 }
18259
18275 void dump_escaped(const string_t& s, const bool ensure_ascii)
18276 {
18277 std::uint32_t codepoint{};
18278 std::uint8_t state = UTF8_ACCEPT;
18279 std::size_t bytes = 0; // number of bytes written to string_buffer
18280
18281 // number of bytes written at the point of the last valid byte
18283 std::size_t undumped_chars = 0;
18284
18285 for (std::size_t i = 0; i < s.size(); ++i)
18286 {
18287 const auto byte = static_cast<std::uint8_t>(s[i]);
18288
18289 switch (decode(state, codepoint, byte))
18290 {
18291 case UTF8_ACCEPT: // decode found a new code point
18292 {
18293 switch (codepoint)
18294 {
18295 case 0x08: // backspace
18296 {
18297 string_buffer[bytes++] = '\\';
18298 string_buffer[bytes++] = 'b';
18299 break;
18300 }
18301
18302 case 0x09: // horizontal tab
18303 {
18304 string_buffer[bytes++] = '\\';
18305 string_buffer[bytes++] = 't';
18306 break;
18307 }
18308
18309 case 0x0A: // newline
18310 {
18311 string_buffer[bytes++] = '\\';
18312 string_buffer[bytes++] = 'n';
18313 break;
18314 }
18315
18316 case 0x0C: // formfeed
18317 {
18318 string_buffer[bytes++] = '\\';
18319 string_buffer[bytes++] = 'f';
18320 break;
18321 }
18322
18323 case 0x0D: // carriage return
18324 {
18325 string_buffer[bytes++] = '\\';
18326 string_buffer[bytes++] = 'r';
18327 break;
18328 }
18329
18330 case 0x22: // quotation mark
18331 {
18332 string_buffer[bytes++] = '\\';
18333 string_buffer[bytes++] = '\"';
18334 break;
18335 }
18336
18337 case 0x5C: // reverse solidus
18338 {
18339 string_buffer[bytes++] = '\\';
18340 string_buffer[bytes++] = '\\';
18341 break;
18342 }
18343
18344 default:
18345 {
18346 // escape control characters (0x00..0x1F) or, if
18347 // ensure_ascii parameter is used, non-ASCII characters
18348 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
18349 {
18350 if (codepoint <= 0xFFFF)
18351 {
18352 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18353 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
18354 static_cast<std::uint16_t>(codepoint)));
18355 bytes += 6;
18356 }
18357 else
18358 {
18359 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18360 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
18361 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
18362 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
18363 bytes += 12;
18364 }
18365 }
18366 else
18367 {
18368 // copy byte to buffer (all previous bytes
18369 // been copied have in default case above)
18370 string_buffer[bytes++] = s[i];
18371 }
18372 break;
18373 }
18374 }
18375
18376 // write buffer and reset index; there must be 13 bytes
18377 // left, as this is the maximal number of bytes to be
18378 // written ("\uxxxx\uxxxx\0") for one code point
18379 if (string_buffer.size() - bytes < 13)
18380 {
18381 o->write_characters(string_buffer.data(), bytes);
18382 bytes = 0;
18383 }
18384
18385 // remember the byte position of this accept
18387 undumped_chars = 0;
18388 break;
18389 }
18390
18391 case UTF8_REJECT: // decode found invalid UTF-8 byte
18392 {
18393 switch (error_handler)
18394 {
18396 {
18397 JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
18398 }
18399
18402 {
18403 // in case we saw this character the first time, we
18404 // would like to read it again, because the byte
18405 // may be OK for itself, but just not OK for the
18406 // previous sequence
18407 if (undumped_chars > 0)
18408 {
18409 --i;
18410 }
18411
18412 // reset length buffer to the last accepted index;
18413 // thus removing/ignoring the invalid characters
18415
18417 {
18418 // add a replacement character
18419 if (ensure_ascii)
18420 {
18421 string_buffer[bytes++] = '\\';
18422 string_buffer[bytes++] = 'u';
18423 string_buffer[bytes++] = 'f';
18424 string_buffer[bytes++] = 'f';
18425 string_buffer[bytes++] = 'f';
18426 string_buffer[bytes++] = 'd';
18427 }
18428 else
18429 {
18433 }
18434
18435 // write buffer and reset index; there must be 13 bytes
18436 // left, as this is the maximal number of bytes to be
18437 // written ("\uxxxx\uxxxx\0") for one code point
18438 if (string_buffer.size() - bytes < 13)
18439 {
18440 o->write_characters(string_buffer.data(), bytes);
18441 bytes = 0;
18442 }
18443
18445 }
18446
18447 undumped_chars = 0;
18448
18449 // continue processing the string
18450 state = UTF8_ACCEPT;
18451 break;
18452 }
18453
18454 default: // LCOV_EXCL_LINE
18455 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18456 }
18457 break;
18458 }
18459
18460 default: // decode found yet incomplete multi-byte code point
18461 {
18462 if (!ensure_ascii)
18463 {
18464 // code point will not be escaped - copy byte to buffer
18465 string_buffer[bytes++] = s[i];
18466 }
18468 break;
18469 }
18470 }
18471 }
18472
18473 // we finished processing the string
18474 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
18475 {
18476 // write buffer
18477 if (bytes > 0)
18478 {
18479 o->write_characters(string_buffer.data(), bytes);
18480 }
18481 }
18482 else
18483 {
18484 // we finish reading, but do not accept: string was incomplete
18485 switch (error_handler)
18486 {
18488 {
18489 JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
18490 }
18491
18493 {
18494 // write all accepted bytes
18495 o->write_characters(string_buffer.data(), bytes_after_last_accept);
18496 break;
18497 }
18498
18500 {
18501 // write all accepted bytes
18502 o->write_characters(string_buffer.data(), bytes_after_last_accept);
18503 // add a replacement character
18504 if (ensure_ascii)
18505 {
18506 o->write_characters("\\ufffd", 6);
18507 }
18508 else
18509 {
18510 o->write_characters("\xEF\xBF\xBD", 3);
18511 }
18512 break;
18513 }
18514
18515 default: // LCOV_EXCL_LINE
18516 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18517 }
18518 }
18519 }
18520
18521 private:
18530 inline unsigned int count_digits(number_unsigned_t x) noexcept
18531 {
18532 unsigned int n_digits = 1;
18533 for (;;)
18534 {
18535 if (x < 10)
18536 {
18537 return n_digits;
18538 }
18539 if (x < 100)
18540 {
18541 return n_digits + 1;
18542 }
18543 if (x < 1000)
18544 {
18545 return n_digits + 2;
18546 }
18547 if (x < 10000)
18548 {
18549 return n_digits + 3;
18550 }
18551 x = x / 10000u;
18552 n_digits += 4;
18553 }
18554 }
18555
18561 static std::string hex_bytes(std::uint8_t byte)
18562 {
18563 std::string result = "FF";
18564 constexpr const char* nibble_to_hex = "0123456789ABCDEF";
18565 result[0] = nibble_to_hex[byte / 16];
18566 result[1] = nibble_to_hex[byte % 16];
18567 return result;
18568 }
18569
18570 // templates to avoid warnings about useless casts
18571 template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
18572 bool is_negative_number(NumberType x)
18573 {
18574 return x < 0;
18575 }
18576
18577 template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
18578 bool is_negative_number(NumberType /*unused*/)
18579 {
18580 return false;
18581 }
18582
18592 template < typename NumberType, detail::enable_if_t <
18593 std::is_integral<NumberType>::value ||
18594 std::is_same<NumberType, number_unsigned_t>::value ||
18595 std::is_same<NumberType, number_integer_t>::value ||
18596 std::is_same<NumberType, binary_char_t>::value,
18597 int > = 0 >
18598 void dump_integer(NumberType x)
18599 {
18600 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
18601 {
18602 {
18603 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
18604 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
18605 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
18606 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
18607 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
18608 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
18609 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
18610 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
18611 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
18612 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
18613 }
18614 };
18615
18616 // special case for "0"
18617 if (x == 0)
18618 {
18619 o->write_character('0');
18620 return;
18621 }
18622
18623 // use a pointer to fill the buffer
18624 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18625
18626 number_unsigned_t abs_value;
18627
18628 unsigned int n_chars{};
18629
18630 if (is_negative_number(x))
18631 {
18632 *buffer_ptr = '-';
18633 abs_value = remove_sign(static_cast<number_integer_t>(x));
18634
18635 // account one more byte for the minus sign
18636 n_chars = 1 + count_digits(abs_value);
18637 }
18638 else
18639 {
18640 abs_value = static_cast<number_unsigned_t>(x);
18641 n_chars = count_digits(abs_value);
18642 }
18643
18644 // spare 1 byte for '\0'
18645 JSON_ASSERT(n_chars < number_buffer.size() - 1);
18646
18647 // jump to the end to generate the string from backward,
18648 // so we later avoid reversing the result
18649 buffer_ptr += n_chars;
18650
18651 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18652 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18653 while (abs_value >= 100)
18654 {
18655 const auto digits_index = static_cast<unsigned>((abs_value % 100));
18656 abs_value /= 100;
18657 *(--buffer_ptr) = digits_to_99[digits_index][1];
18658 *(--buffer_ptr) = digits_to_99[digits_index][0];
18659 }
18660
18661 if (abs_value >= 10)
18662 {
18663 const auto digits_index = static_cast<unsigned>(abs_value);
18664 *(--buffer_ptr) = digits_to_99[digits_index][1];
18665 *(--buffer_ptr) = digits_to_99[digits_index][0];
18666 }
18667 else
18668 {
18669 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18670 }
18671
18672 o->write_characters(number_buffer.data(), n_chars);
18673 }
18674
18683 void dump_float(number_float_t x)
18684 {
18685 // NaN / inf
18686 if (!std::isfinite(x))
18687 {
18688 o->write_characters("null", 4);
18689 return;
18690 }
18691
18692 // If number_float_t is an IEEE-754 single or double precision number,
18693 // use the Grisu2 algorithm to produce short numbers which are
18694 // guaranteed to round-trip, using strtof and strtod, resp.
18695 //
18696 // NB: The test below works if <long double> == <double>.
18697 static constexpr bool is_ieee_single_or_double
18698 = (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) ||
18699 (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);
18700
18701 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18702 }
18703
18704 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18705 {
18706 auto* begin = number_buffer.data();
18707 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18708
18709 o->write_characters(begin, static_cast<size_t>(end - begin));
18710 }
18711
18712 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18713 {
18714 // get number of digits for a float -> text -> float round-trip
18715 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18716
18717 // the actual conversion
18718 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18719 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18720
18721 // negative value indicates an error
18722 JSON_ASSERT(len > 0);
18723 // check if buffer was large enough
18724 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18725
18726 // erase thousands separator
18727 if (thousands_sep != '\0')
18728 {
18729 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18730 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18731 std::fill(end, number_buffer.end(), '\0');
18732 JSON_ASSERT((end - number_buffer.begin()) <= len);
18733 len = (end - number_buffer.begin());
18734 }
18735
18736 // convert decimal point to '.'
18737 if (decimal_point != '\0' && decimal_point != '.')
18738 {
18739 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18740 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18741 if (dec_pos != number_buffer.end())
18742 {
18743 *dec_pos = '.';
18744 }
18745 }
18746
18747 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18748
18749 // determine if we need to append ".0"
18750 const bool value_is_int_like =
18751 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18752 [](char c)
18753 {
18754 return c == '.' || c == 'e';
18755 });
18756
18757 if (value_is_int_like)
18758 {
18759 o->write_characters(".0", 2);
18760 }
18761 }
18762
18784 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18785 {
18786 static const std::array<std::uint8_t, 400> utf8d =
18787 {
18788 {
18789 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
18790 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
18791 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
18792 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
18793 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
18794 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
18795 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
18796 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18797 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18798 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18799 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
18800 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
18801 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
18802 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
18803 }
18804 };
18805
18806 JSON_ASSERT(byte < utf8d.size());
18807 const std::uint8_t type = utf8d[byte];
18808
18809 codep = (state != UTF8_ACCEPT)
18810 ? (byte & 0x3fu) | (codep << 6u)
18811 : (0xFFu >> type) & (byte);
18812
18813 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18814 JSON_ASSERT(index < 400);
18815 state = utf8d[index];
18816 return state;
18817 }
18818
18819 /*
18820 * Overload to make the compiler happy while it is instantiating
18821 * dump_integer for number_unsigned_t.
18822 * Must never be called.
18823 */
18824 number_unsigned_t remove_sign(number_unsigned_t x)
18825 {
18826 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18827 return x; // LCOV_EXCL_LINE
18828 }
18829
18830 /*
18831 * Helper function for dump_integer
18832 *
18833 * This function takes a negative signed integer and returns its absolute
18834 * value as unsigned integer. The plus/minus shuffling is necessary as we can
18835 * not directly remove the sign of an arbitrary signed integer as the
18836 * absolute values of INT_MIN and INT_MAX are usually not the same. See
18837 * #1708 for details.
18838 */
18839 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18840 {
18841 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18842 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18843 }
18844
18845 private:
18847 output_adapter_t<char> o = nullptr;
18848
18850 std::array<char, 64> number_buffer{{}};
18851
18853 const std::lconv* loc = nullptr;
18855 const char thousands_sep = '\0';
18857 const char decimal_point = '\0';
18858
18860 std::array<char, 512> string_buffer{{}};
18861
18863 const char indent_char;
18866
18869};
18870
18871} // namespace detail
18873
18874// #include <nlohmann/detail/value_t.hpp>
18875
18876// #include <nlohmann/json_fwd.hpp>
18877
18878// #include <nlohmann/ordered_map.hpp>
18879// __ _____ _____ _____
18880// __| | __| | | | JSON for Modern C++
18881// | | |__ | | | | | | version 3.11.2
18882// |_____|_____|_____|_|___| https://github.com/nlohmann/json
18883//
18884// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
18885// SPDX-License-Identifier: MIT
18886
18887
18888
18889#include <functional> // equal_to, less
18890#include <initializer_list> // initializer_list
18891#include <iterator> // input_iterator_tag, iterator_traits
18892#include <memory> // allocator
18893#include <stdexcept> // for out_of_range
18894#include <type_traits> // enable_if, is_convertible
18895#include <utility> // pair
18896#include <vector> // vector
18897
18898// #include <nlohmann/detail/macro_scope.hpp>
18899
18900// #include <nlohmann/detail/meta/type_traits.hpp>
18901
18902
18904
18907template <class Key, class T, class IgnoredLess = std::less<Key>,
18908 class Allocator = std::allocator<std::pair<const Key, T>>>
18909 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
18910{
18911 using key_type = Key;
18912 using mapped_type = T;
18913 using Container = std::vector<std::pair<const Key, T>, Allocator>;
18914 using iterator = typename Container::iterator;
18915 using const_iterator = typename Container::const_iterator;
18916 using size_type = typename Container::size_type;
18917 using value_type = typename Container::value_type;
18918#ifdef JSON_HAS_CPP_14
18919 using key_compare = std::equal_to<>;
18920#else
18921 using key_compare = std::equal_to<Key>;
18922#endif
18923
18924 // Explicit constructors instead of `using Container::Container`
18925 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
18926 ordered_map() noexcept(noexcept(Container())) : Container{} {}
18927 explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
18928 template <class It>
18929 ordered_map(It first, It last, const Allocator& alloc = Allocator())
18930 : Container{first, last, alloc} {}
18931 ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
18932 : Container{init, alloc} {}
18933
18934 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
18935 {
18936 for (auto it = this->begin(); it != this->end(); ++it)
18937 {
18938 if (m_compare(it->first, key))
18939 {
18940 return {it, false};
18941 }
18942 }
18943 Container::emplace_back(key, std::forward<T>(t));
18944 return {std::prev(this->end()), true};
18945 }
18946
18947 template<class KeyType, detail::enable_if_t<
18949 std::pair<iterator, bool> emplace(KeyType && key, T && t)
18950 {
18951 for (auto it = this->begin(); it != this->end(); ++it)
18952 {
18953 if (m_compare(it->first, key))
18954 {
18955 return {it, false};
18956 }
18957 }
18958 Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
18959 return {std::prev(this->end()), true};
18960 }
18961
18962 T& operator[](const key_type& key)
18963 {
18964 return emplace(key, T{}).first->second;
18965 }
18966
18967 template<class KeyType, detail::enable_if_t<
18969 T & operator[](KeyType && key)
18970 {
18971 return emplace(std::forward<KeyType>(key), T{}).first->second;
18972 }
18973
18974 const T& operator[](const key_type& key) const
18975 {
18976 return at(key);
18977 }
18978
18979 template<class KeyType, detail::enable_if_t<
18981 const T & operator[](KeyType && key) const
18982 {
18983 return at(std::forward<KeyType>(key));
18984 }
18985
18986 T& at(const key_type& key)
18987 {
18988 for (auto it = this->begin(); it != this->end(); ++it)
18989 {
18990 if (m_compare(it->first, key))
18991 {
18992 return it->second;
18993 }
18994 }
18995
18996 JSON_THROW(std::out_of_range("key not found"));
18997 }
18998
18999 template<class KeyType, detail::enable_if_t<
19001 T & at(KeyType && key)
19002 {
19003 for (auto it = this->begin(); it != this->end(); ++it)
19004 {
19005 if (m_compare(it->first, key))
19006 {
19007 return it->second;
19008 }
19009 }
19010
19011 JSON_THROW(std::out_of_range("key not found"));
19012 }
19013
19014 const T& at(const key_type& key) const
19015 {
19016 for (auto it = this->begin(); it != this->end(); ++it)
19017 {
19018 if (m_compare(it->first, key))
19019 {
19020 return it->second;
19021 }
19022 }
19023
19024 JSON_THROW(std::out_of_range("key not found"));
19025 }
19026
19027 template<class KeyType, detail::enable_if_t<
19029 const T & at(KeyType && key) const
19030 {
19031 for (auto it = this->begin(); it != this->end(); ++it)
19032 {
19033 if (m_compare(it->first, key))
19034 {
19035 return it->second;
19036 }
19037 }
19038
19039 JSON_THROW(std::out_of_range("key not found"));
19040 }
19041
19043 {
19044 for (auto it = this->begin(); it != this->end(); ++it)
19045 {
19046 if (m_compare(it->first, key))
19047 {
19048 // Since we cannot move const Keys, re-construct them in place
19049 for (auto next = it; ++next != this->end(); ++it)
19050 {
19051 it->~value_type(); // Destroy but keep allocation
19052 new (&*it) value_type{std::move(*next)};
19053 }
19054 Container::pop_back();
19055 return 1;
19056 }
19057 }
19058 return 0;
19059 }
19060
19061 template<class KeyType, detail::enable_if_t<
19063 size_type erase(KeyType && key)
19064 {
19065 for (auto it = this->begin(); it != this->end(); ++it)
19066 {
19067 if (m_compare(it->first, key))
19068 {
19069 // Since we cannot move const Keys, re-construct them in place
19070 for (auto next = it; ++next != this->end(); ++it)
19071 {
19072 it->~value_type(); // Destroy but keep allocation
19073 new (&*it) value_type{std::move(*next)};
19074 }
19075 Container::pop_back();
19076 return 1;
19077 }
19078 }
19079 return 0;
19080 }
19081
19083 {
19084 return erase(pos, std::next(pos));
19085 }
19086
19088 {
19089 if (first == last)
19090 {
19091 return first;
19092 }
19093
19094 const auto elements_affected = std::distance(first, last);
19095 const auto offset = std::distance(Container::begin(), first);
19096
19097 // This is the start situation. We need to delete elements_affected
19098 // elements (3 in this example: e, f, g), and need to return an
19099 // iterator past the last deleted element (h in this example).
19100 // Note that offset is the distance from the start of the vector
19101 // to first. We will need this later.
19102
19103 // [ a, b, c, d, e, f, g, h, i, j ]
19104 // ^ ^
19105 // first last
19106
19107 // Since we cannot move const Keys, we re-construct them in place.
19108 // We start at first and re-construct (viz. copy) the elements from
19109 // the back of the vector. Example for first iteration:
19110
19111 // ,--------.
19112 // v | destroy e and re-construct with h
19113 // [ a, b, c, d, e, f, g, h, i, j ]
19114 // ^ ^
19115 // it it + elements_affected
19116
19117 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
19118 {
19119 it->~value_type(); // destroy but keep allocation
19120 new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
19121 }
19122
19123 // [ a, b, c, d, h, i, j, h, i, j ]
19124 // ^ ^
19125 // first last
19126
19127 // remove the unneeded elements at the end of the vector
19128 Container::resize(this->size() - static_cast<size_type>(elements_affected));
19129
19130 // [ a, b, c, d, h, i, j ]
19131 // ^ ^
19132 // first last
19133
19134 // first is now pointing past the last deleted element, but we cannot
19135 // use this iterator, because it may have been invalidated by the
19136 // resize call. Instead, we can return begin() + offset.
19137 return Container::begin() + offset;
19138 }
19139
19140 size_type count(const key_type& key) const
19141 {
19142 for (auto it = this->begin(); it != this->end(); ++it)
19143 {
19144 if (m_compare(it->first, key))
19145 {
19146 return 1;
19147 }
19148 }
19149 return 0;
19150 }
19151
19152 template<class KeyType, detail::enable_if_t<
19154 size_type count(KeyType && key) const
19155 {
19156 for (auto it = this->begin(); it != this->end(); ++it)
19157 {
19158 if (m_compare(it->first, key))
19159 {
19160 return 1;
19161 }
19162 }
19163 return 0;
19164 }
19165
19167 {
19168 for (auto it = this->begin(); it != this->end(); ++it)
19169 {
19170 if (m_compare(it->first, key))
19171 {
19172 return it;
19173 }
19174 }
19175 return Container::end();
19176 }
19177
19178 template<class KeyType, detail::enable_if_t<
19180 iterator find(KeyType && key)
19181 {
19182 for (auto it = this->begin(); it != this->end(); ++it)
19183 {
19184 if (m_compare(it->first, key))
19185 {
19186 return it;
19187 }
19188 }
19189 return Container::end();
19190 }
19191
19192 const_iterator find(const key_type& key) const
19193 {
19194 for (auto it = this->begin(); it != this->end(); ++it)
19195 {
19196 if (m_compare(it->first, key))
19197 {
19198 return it;
19199 }
19200 }
19201 return Container::end();
19202 }
19203
19204 std::pair<iterator, bool> insert( value_type&& value )
19205 {
19206 return emplace(value.first, std::move(value.second));
19207 }
19208
19209 std::pair<iterator, bool> insert( const value_type& value )
19210 {
19211 for (auto it = this->begin(); it != this->end(); ++it)
19212 {
19213 if (m_compare(it->first, value.first))
19214 {
19215 return {it, false};
19216 }
19217 }
19218 Container::push_back(value);
19219 return {--this->end(), true};
19220 }
19221
19222 template<typename InputIt>
19223 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
19224 std::input_iterator_tag>::value>::type;
19225
19226 template<typename InputIt, typename = require_input_iter<InputIt>>
19227 void insert(InputIt first, InputIt last)
19228 {
19229 for (auto it = first; it != last; ++it)
19230 {
19231 insert(*it);
19232 }
19233 }
19234
19235private:
19237};
19238
19240
19241
19242#if defined(JSON_HAS_CPP_17)
19243 #include <any>
19244 #include <string_view>
19245#endif
19246
19253
19273class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
19274{
19275 private:
19276 template<detail::value_t> friend struct detail::external_constructor;
19277
19278 template<typename>
19279 friend class ::nlohmann::json_pointer;
19280 // can be restored when json_pointer backwards compatibility is removed
19281 // friend ::nlohmann::json_pointer<StringType>;
19282
19283 template<typename BasicJsonType, typename InputType>
19284 friend class ::nlohmann::detail::parser;
19285 friend ::nlohmann::detail::serializer<basic_json>;
19286 template<typename BasicJsonType>
19287 friend class ::nlohmann::detail::iter_impl;
19288 template<typename BasicJsonType, typename CharType>
19289 friend class ::nlohmann::detail::binary_writer;
19290 template<typename BasicJsonType, typename InputType, typename SAX>
19291 friend class ::nlohmann::detail::binary_reader;
19292 template<typename BasicJsonType>
19293 friend class ::nlohmann::detail::json_sax_dom_parser;
19294 template<typename BasicJsonType>
19295 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
19296 friend class ::nlohmann::detail::exception;
19297
19299 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
19300
19302 // convenience aliases for types residing in namespace detail;
19303 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
19304
19305 template<typename InputAdapterType>
19306 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
19307 InputAdapterType adapter,
19309 const bool allow_exceptions = true,
19310 const bool ignore_comments = false
19311 )
19312 {
19313 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
19314 std::move(cb), allow_exceptions, ignore_comments);
19315 }
19316
19317 private:
19318 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
19319 template<typename BasicJsonType>
19320 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
19321 template<typename BasicJsonType>
19322 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
19323 template<typename Iterator>
19324 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
19325 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
19326
19327 template<typename CharType>
19328 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
19329
19330 template<typename InputType>
19331 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
19332 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
19333
19335 using serializer = ::nlohmann::detail::serializer<basic_json>;
19336
19337 public:
19340 using json_pointer = ::nlohmann::json_pointer<StringType>;
19341 template<typename T, typename SFINAE>
19342 using json_serializer = JSONSerializer<T, SFINAE>;
19348 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19349
19353
19355 // exceptions //
19357
19361
19368
19370
19371
19373 // container types //
19375
19380
19383
19388
19390 using difference_type = std::ptrdiff_t;
19392 using size_type = std::size_t;
19393
19395 using allocator_type = AllocatorType<basic_json>;
19396
19398 using pointer = typename std::allocator_traits<allocator_type>::pointer;
19400 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19401
19403 using iterator = iter_impl<basic_json>;
19405 using const_iterator = iter_impl<const basic_json>;
19407 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
19409 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
19410
19412
19413
19417 {
19418 return allocator_type();
19419 }
19420
19425 {
19426 basic_json result;
19427
19428 result["copyright"] = "(C) 2013-2022 Niels Lohmann";
19429 result["name"] = "JSON for Modern C++";
19430 result["url"] = "https://github.com/nlohmann/json";
19431 result["version"]["string"] =
19432 detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
19433 std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
19434 std::to_string(NLOHMANN_JSON_VERSION_PATCH));
19435 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
19436 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
19437 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
19438
19439#ifdef _WIN32
19440 result["platform"] = "win32";
19441#elif defined __linux__
19442 result["platform"] = "linux";
19443#elif defined __APPLE__
19444 result["platform"] = "apple";
19445#elif defined __unix__
19446 result["platform"] = "unix";
19447#else
19448 result["platform"] = "unknown";
19449#endif
19450
19451#if defined(__ICC) || defined(__INTEL_COMPILER)
19452 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
19453#elif defined(__clang__)
19454 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
19455#elif defined(__GNUC__) || defined(__GNUG__)
19456 result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
19457 std::to_string(__GNUC__), '.',
19458 std::to_string(__GNUC_MINOR__), '.',
19459 std::to_string(__GNUC_PATCHLEVEL__))
19460 }
19461 };
19462#elif defined(__HP_cc) || defined(__HP_aCC)
19463 result["compiler"] = "hp"
19464#elif defined(__IBMCPP__)
19465 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
19466#elif defined(_MSC_VER)
19467 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
19468#elif defined(__PGI)
19469 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
19470#elif defined(__SUNPRO_CC)
19471 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
19472#else
19473 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
19474#endif
19475
19476
19477#if defined(_MSVC_LANG)
19478 result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
19479#elif defined(__cplusplus)
19480 result["compiler"]["c++"] = std::to_string(__cplusplus);
19481#else
19482 result["compiler"]["c++"] = "unknown";
19483#endif
19484 return result;
19485 }
19486
19487
19489 // JSON value data types //
19491
19496
19501#if defined(JSON_HAS_CPP_14)
19502 // use of transparent comparator avoids unnecessary repeated construction of temporaries
19503 // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
19504 using default_object_comparator_t = std::less<>;
19505#else
19506 using default_object_comparator_t = std::less<StringType>;
19507#endif
19508
19511 using object_t = ObjectType<StringType,
19512 basic_json,
19514 AllocatorType<std::pair<const StringType,
19515 basic_json>>>;
19516
19519 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19520
19523 using string_t = StringType;
19524
19527 using boolean_t = BooleanType;
19528
19531 using number_integer_t = NumberIntegerType;
19532
19535 using number_unsigned_t = NumberUnsignedType;
19536
19539 using number_float_t = NumberFloatType;
19540
19543 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19544
19548
19550
19551 private:
19552
19554 template<typename T, typename... Args>
19556 static T* create(Args&& ... args)
19557 {
19558 AllocatorType<T> alloc;
19559 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
19560
19561 auto deleter = [&](T * obj)
19562 {
19563 AllocatorTraits::deallocate(alloc, obj, 1);
19564 };
19565 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
19566 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
19567 JSON_ASSERT(obj != nullptr);
19568 return obj.release();
19569 }
19570
19572 // JSON value storage //
19574
19601 union json_value
19602 {
19606 array_t* array;
19608 string_t* string;
19610 binary_t* binary;
19612 boolean_t boolean;
19614 number_integer_t number_integer;
19616 number_unsigned_t number_unsigned;
19618 number_float_t number_float;
19619
19621 json_value() = default;
19623 json_value(boolean_t v) noexcept : boolean(v) {}
19625 json_value(number_integer_t v) noexcept : number_integer(v) {}
19627 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
19629 json_value(number_float_t v) noexcept : number_float(v) {}
19631 json_value(value_t t)
19632 {
19633 switch (t)
19634 {
19635 case value_t::object:
19636 {
19637 object = create<object_t>();
19638 break;
19639 }
19640
19641 case value_t::array:
19642 {
19643 array = create<array_t>();
19644 break;
19645 }
19646
19647 case value_t::string:
19648 {
19649 string = create<string_t>("");
19650 break;
19651 }
19652
19653 case value_t::binary:
19654 {
19655 binary = create<binary_t>();
19656 break;
19657 }
19658
19659 case value_t::boolean:
19660 {
19661 boolean = static_cast<boolean_t>(false);
19662 break;
19663 }
19664
19665 case value_t::number_integer:
19666 {
19667 number_integer = static_cast<number_integer_t>(0);
19668 break;
19669 }
19670
19671 case value_t::number_unsigned:
19672 {
19673 number_unsigned = static_cast<number_unsigned_t>(0);
19674 break;
19675 }
19676
19677 case value_t::number_float:
19678 {
19679 number_float = static_cast<number_float_t>(0.0);
19680 break;
19681 }
19682
19683 case value_t::null:
19684 {
19685 object = nullptr; // silence warning, see #821
19686 break;
19687 }
19688
19689 case value_t::discarded:
19690 default:
19691 {
19692 object = nullptr; // silence warning, see #821
19693 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
19694 {
19695 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.2", nullptr)); // LCOV_EXCL_LINE
19696 }
19697 break;
19698 }
19699 }
19700 }
19701
19703 json_value(const string_t& value) : string(create<string_t>(value)) {}
19704
19706 json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19707
19709 json_value(const object_t& value) : object(create<object_t>(value)) {}
19710
19712 json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19713
19715 json_value(const array_t& value) : array(create<array_t>(value)) {}
19716
19718 json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19719
19721 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19722
19724 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19725
19727 json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
19728
19730 json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
19731
19732 void destroy(value_t t)
19733 {
19734 if (t == value_t::array || t == value_t::object)
19735 {
19736 // flatten the current json_value to a heap-allocated stack
19737 std::vector<basic_json> stack;
19738
19739 // move the top-level items to stack
19740 if (t == value_t::array)
19741 {
19742 stack.reserve(array->size());
19743 std::move(array->begin(), array->end(), std::back_inserter(stack));
19744 }
19745 else
19746 {
19747 stack.reserve(object->size());
19748 for (auto&& it : *object)
19749 {
19750 stack.push_back(std::move(it.second));
19751 }
19752 }
19753
19754 while (!stack.empty())
19755 {
19756 // move the last item to local variable to be processed
19757 basic_json current_item(std::move(stack.back()));
19758 stack.pop_back();
19759
19760 // if current_item is array/object, move
19761 // its children to the stack to be processed later
19762 if (current_item.is_array())
19763 {
19764 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
19765
19766 current_item.m_value.array->clear();
19767 }
19768 else if (current_item.is_object())
19769 {
19770 for (auto&& it : *current_item.m_value.object)
19771 {
19772 stack.push_back(std::move(it.second));
19773 }
19774
19775 current_item.m_value.object->clear();
19776 }
19777
19778 // it's now safe that current_item get destructed
19779 // since it doesn't have any children
19780 }
19781 }
19782
19783 switch (t)
19784 {
19785 case value_t::object:
19786 {
19787 AllocatorType<object_t> alloc;
19788 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19789 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19790 break;
19791 }
19792
19793 case value_t::array:
19794 {
19795 AllocatorType<array_t> alloc;
19796 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19797 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19798 break;
19799 }
19800
19801 case value_t::string:
19802 {
19803 AllocatorType<string_t> alloc;
19804 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19805 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19806 break;
19807 }
19808
19809 case value_t::binary:
19810 {
19811 AllocatorType<binary_t> alloc;
19812 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19813 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19814 break;
19815 }
19816
19817 case value_t::null:
19818 case value_t::boolean:
19819 case value_t::number_integer:
19820 case value_t::number_unsigned:
19821 case value_t::number_float:
19822 case value_t::discarded:
19823 default:
19824 {
19825 break;
19826 }
19827 }
19828 }
19829 };
19830
19831 private:
19850 void assert_invariant(bool check_parents = true) const noexcept
19851 {
19852 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
19853 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
19854 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
19855 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
19856
19857#if JSON_DIAGNOSTICS
19858 JSON_TRY
19859 {
19860 // cppcheck-suppress assertWithSideEffect
19861 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
19862 {
19863 return j.m_parent == this;
19864 }));
19865 }
19866 JSON_CATCH(...) {} // LCOV_EXCL_LINE
19867#endif
19868 static_cast<void>(check_parents);
19869 }
19870
19871 void set_parents()
19872 {
19873#if JSON_DIAGNOSTICS
19874 switch (m_type)
19875 {
19876 case value_t::array:
19877 {
19878 for (auto& element : *m_value.array)
19879 {
19880 element.m_parent = this;
19881 }
19882 break;
19883 }
19884
19885 case value_t::object:
19886 {
19887 for (auto& element : *m_value.object)
19888 {
19889 element.second.m_parent = this;
19890 }
19891 break;
19892 }
19893
19894 case value_t::null:
19895 case value_t::string:
19896 case value_t::boolean:
19897 case value_t::number_integer:
19898 case value_t::number_unsigned:
19899 case value_t::number_float:
19900 case value_t::binary:
19901 case value_t::discarded:
19902 default:
19903 break;
19904 }
19905#endif
19906 }
19907
19908 iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
19909 {
19910#if JSON_DIAGNOSTICS
19911 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
19912 {
19913 (it + i)->m_parent = this;
19914 }
19915#else
19916 static_cast<void>(count_set_parents);
19917#endif
19918 return it;
19919 }
19920
19921 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
19922 {
19923#if JSON_DIAGNOSTICS
19924 if (old_capacity != static_cast<std::size_t>(-1))
19925 {
19926 // see https://github.com/nlohmann/json/issues/2838
19927 JSON_ASSERT(type() == value_t::array);
19928 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
19929 {
19930 // capacity has changed: update all parents
19931 set_parents();
19932 return j;
19933 }
19934 }
19935
19936 // ordered_json uses a vector internally, so pointers could have
19937 // been invalidated; see https://github.com/nlohmann/json/issues/2962
19938#ifdef JSON_HEDLEY_MSVC_VERSION
19939#pragma warning(push )
19940#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
19941#endif
19943 {
19944 set_parents();
19945 return j;
19946 }
19947#ifdef JSON_HEDLEY_MSVC_VERSION
19948#pragma warning( pop )
19949#endif
19950
19951 j.m_parent = this;
19952#else
19953 static_cast<void>(j);
19954 static_cast<void>(old_capacity);
19955#endif
19956 return j;
19957 }
19958
19959 public:
19961 // JSON parser callback //
19963
19967
19971
19973 // constructors //
19975
19980
19984 : m_type(v), m_value(v)
19985 {
19986 assert_invariant();
19987 }
19988
19991 basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
19992 : basic_json(value_t::null)
19993 {
19994 assert_invariant();
19995 }
19996
19999 template < typename CompatibleType,
20003 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20004 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20005 std::forward<CompatibleType>(val))))
20006 {
20007 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20008 set_parents();
20009 assert_invariant();
20010 }
20011
20014 template < typename BasicJsonType,
20016 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
20017 basic_json(const BasicJsonType& val)
20018 {
20019 using other_boolean_t = typename BasicJsonType::boolean_t;
20020 using other_number_float_t = typename BasicJsonType::number_float_t;
20021 using other_number_integer_t = typename BasicJsonType::number_integer_t;
20022 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20023 using other_string_t = typename BasicJsonType::string_t;
20024 using other_object_t = typename BasicJsonType::object_t;
20025 using other_array_t = typename BasicJsonType::array_t;
20026 using other_binary_t = typename BasicJsonType::binary_t;
20027
20028 switch (val.type())
20029 {
20030 case value_t::boolean:
20031 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20032 break;
20033 case value_t::number_float:
20034 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20035 break;
20036 case value_t::number_integer:
20037 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20038 break;
20039 case value_t::number_unsigned:
20040 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20041 break;
20042 case value_t::string:
20043 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20044 break;
20045 case value_t::object:
20046 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20047 break;
20048 case value_t::array:
20049 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20050 break;
20051 case value_t::binary:
20052 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20053 break;
20054 case value_t::null:
20055 *this = nullptr;
20056 break;
20057 case value_t::discarded:
20058 m_type = value_t::discarded;
20059 break;
20060 default: // LCOV_EXCL_LINE
20061 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
20062 }
20063 JSON_ASSERT(m_type == val.type());
20064 set_parents();
20065 assert_invariant();
20066 }
20067
20071 bool type_deduction = true,
20072 value_t manual_type = value_t::array)
20073 {
20074 // check if each element is an array with two elements whose first
20075 // element is a string
20076 bool is_an_object = std::all_of(init.begin(), init.end(),
20077 [](const detail::json_ref<basic_json>& element_ref)
20078 {
20079 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
20080 });
20081
20082 // adjust type if type deduction is not wanted
20083 if (!type_deduction)
20084 {
20085 // if array is wanted, do not create an object though possible
20086 if (manual_type == value_t::array)
20087 {
20088 is_an_object = false;
20089 }
20090
20091 // if object is wanted but impossible, throw an exception
20092 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
20093 {
20094 JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
20095 }
20096 }
20097
20098 if (is_an_object)
20099 {
20100 // the initializer list is a list of pairs -> create object
20101 m_type = value_t::object;
20102 m_value = value_t::object;
20103
20104 for (auto& element_ref : init)
20105 {
20106 auto element = element_ref.moved_or_copied();
20107 m_value.object->emplace(
20108 std::move(*((*element.m_value.array)[0].m_value.string)),
20109 std::move((*element.m_value.array)[1]));
20110 }
20111 }
20112 else
20113 {
20114 // the initializer list describes an array -> create array
20115 m_type = value_t::array;
20116 m_value.array = create<array_t>(init.begin(), init.end());
20117 }
20118
20119 set_parents();
20120 assert_invariant();
20121 }
20122
20126 static basic_json binary(const typename binary_t::container_type& init)
20127 {
20128 auto res = basic_json();
20129 res.m_type = value_t::binary;
20130 res.m_value = init;
20131 return res;
20132 }
20133
20137 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
20138 {
20139 auto res = basic_json();
20140 res.m_type = value_t::binary;
20141 res.m_value = binary_t(init, subtype);
20142 return res;
20143 }
20144
20148 static basic_json binary(typename binary_t::container_type&& init)
20149 {
20150 auto res = basic_json();
20151 res.m_type = value_t::binary;
20152 res.m_value = std::move(init);
20153 return res;
20154 }
20155
20159 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
20160 {
20161 auto res = basic_json();
20162 res.m_type = value_t::binary;
20163 res.m_value = binary_t(std::move(init), subtype);
20164 return res;
20165 }
20166
20171 {
20172 return basic_json(init, false, value_t::array);
20173 }
20174
20179 {
20180 return basic_json(init, false, value_t::object);
20181 }
20182
20186 : m_type(value_t::array)
20187 {
20188 m_value.array = create<array_t>(cnt, val);
20189 set_parents();
20190 assert_invariant();
20191 }
20192
20195 template < class InputIT, typename std::enable_if <
20196 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
20197 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
20198 basic_json(InputIT first, InputIT last)
20199 {
20200 JSON_ASSERT(first.m_object != nullptr);
20201 JSON_ASSERT(last.m_object != nullptr);
20202
20203 // make sure iterator fits the current value
20204 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20205 {
20206 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
20207 }
20208
20209 // copy type from first iterator
20210 m_type = first.m_object->m_type;
20211
20212 // check if iterator range is complete for primitive values
20213 switch (m_type)
20214 {
20215 case value_t::boolean:
20216 case value_t::number_float:
20217 case value_t::number_integer:
20218 case value_t::number_unsigned:
20219 case value_t::string:
20220 {
20221 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
20222 || !last.m_it.primitive_iterator.is_end()))
20223 {
20224 JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
20225 }
20226 break;
20227 }
20228
20229 case value_t::null:
20230 case value_t::object:
20231 case value_t::array:
20232 case value_t::binary:
20233 case value_t::discarded:
20234 default:
20235 break;
20236 }
20237
20238 switch (m_type)
20239 {
20240 case value_t::number_integer:
20241 {
20242 m_value.number_integer = first.m_object->m_value.number_integer;
20243 break;
20244 }
20245
20246 case value_t::number_unsigned:
20247 {
20248 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
20249 break;
20250 }
20251
20252 case value_t::number_float:
20253 {
20254 m_value.number_float = first.m_object->m_value.number_float;
20255 break;
20256 }
20257
20258 case value_t::boolean:
20259 {
20260 m_value.boolean = first.m_object->m_value.boolean;
20261 break;
20262 }
20263
20264 case value_t::string:
20265 {
20266 m_value = *first.m_object->m_value.string;
20267 break;
20268 }
20269
20270 case value_t::object:
20271 {
20272 m_value.object = create<object_t>(first.m_it.object_iterator,
20273 last.m_it.object_iterator);
20274 break;
20275 }
20276
20277 case value_t::array:
20278 {
20279 m_value.array = create<array_t>(first.m_it.array_iterator,
20280 last.m_it.array_iterator);
20281 break;
20282 }
20283
20284 case value_t::binary:
20285 {
20286 m_value = *first.m_object->m_value.binary;
20287 break;
20288 }
20289
20290 case value_t::null:
20291 case value_t::discarded:
20292 default:
20293 JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
20294 }
20295
20296 set_parents();
20297 assert_invariant();
20298 }
20299
20300
20302 // other constructors and destructor //
20304
20305 template<typename JsonRef,
20307 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
20308 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
20309
20313 : m_type(other.m_type)
20314 {
20315 // check of passed value is valid
20316 other.assert_invariant();
20317
20318 switch (m_type)
20319 {
20320 case value_t::object:
20321 {
20322 m_value = *other.m_value.object;
20323 break;
20324 }
20325
20326 case value_t::array:
20327 {
20328 m_value = *other.m_value.array;
20329 break;
20330 }
20331
20332 case value_t::string:
20333 {
20334 m_value = *other.m_value.string;
20335 break;
20336 }
20337
20338 case value_t::boolean:
20339 {
20340 m_value = other.m_value.boolean;
20341 break;
20342 }
20343
20344 case value_t::number_integer:
20345 {
20346 m_value = other.m_value.number_integer;
20347 break;
20348 }
20349
20350 case value_t::number_unsigned:
20351 {
20352 m_value = other.m_value.number_unsigned;
20353 break;
20354 }
20355
20356 case value_t::number_float:
20357 {
20358 m_value = other.m_value.number_float;
20359 break;
20360 }
20361
20362 case value_t::binary:
20363 {
20364 m_value = *other.m_value.binary;
20365 break;
20366 }
20367
20368 case value_t::null:
20369 case value_t::discarded:
20370 default:
20371 break;
20372 }
20373
20374 set_parents();
20375 assert_invariant();
20376 }
20377
20380 basic_json(basic_json&& other) noexcept
20381 : m_type(std::move(other.m_type)),
20382 m_value(std::move(other.m_value))
20383 {
20384 // check that passed value is valid
20385 other.assert_invariant(false);
20386
20387 // invalidate payload
20388 other.m_type = value_t::null;
20389 other.m_value = {};
20390
20391 set_parents();
20392 assert_invariant();
20393 }
20394
20398 std::is_nothrow_move_constructible<value_t>::value&&
20399 std::is_nothrow_move_assignable<value_t>::value&&
20400 std::is_nothrow_move_constructible<json_value>::value&&
20401 std::is_nothrow_move_assignable<json_value>::value
20402 )
20403 {
20404 // check that passed value is valid
20405 other.assert_invariant();
20406
20407 using std::swap;
20408 swap(m_type, other.m_type);
20409 swap(m_value, other.m_value);
20410
20411 set_parents();
20412 assert_invariant();
20413 return *this;
20414 }
20415
20418 ~basic_json() noexcept
20419 {
20420 assert_invariant(false);
20421 m_value.destroy(m_type);
20422 }
20423
20425
20426 public:
20428 // object inspection //
20430
20434
20437 string_t dump(const int indent = -1,
20438 const char indent_char = ' ',
20439 const bool ensure_ascii = false,
20440 const error_handler_t error_handler = error_handler_t::strict) const
20441 {
20442 string_t result;
20443 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20444
20445 if (indent >= 0)
20446 {
20447 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20448 }
20449 else
20450 {
20451 s.dump(*this, false, ensure_ascii, 0);
20452 }
20453
20454 return result;
20455 }
20456
20459 constexpr value_t type() const noexcept
20460 {
20461 return m_type;
20462 }
20463
20466 constexpr bool is_primitive() const noexcept
20467 {
20468 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20469 }
20470
20473 constexpr bool is_structured() const noexcept
20474 {
20475 return is_array() || is_object();
20476 }
20477
20480 constexpr bool is_null() const noexcept
20481 {
20482 return m_type == value_t::null;
20483 }
20484
20487 constexpr bool is_boolean() const noexcept
20488 {
20489 return m_type == value_t::boolean;
20490 }
20491
20494 constexpr bool is_number() const noexcept
20495 {
20496 return is_number_integer() || is_number_float();
20497 }
20498
20501 constexpr bool is_number_integer() const noexcept
20502 {
20503 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20504 }
20505
20508 constexpr bool is_number_unsigned() const noexcept
20509 {
20510 return m_type == value_t::number_unsigned;
20511 }
20512
20515 constexpr bool is_number_float() const noexcept
20516 {
20517 return m_type == value_t::number_float;
20518 }
20519
20522 constexpr bool is_object() const noexcept
20523 {
20524 return m_type == value_t::object;
20525 }
20526
20529 constexpr bool is_array() const noexcept
20530 {
20531 return m_type == value_t::array;
20532 }
20533
20536 constexpr bool is_string() const noexcept
20537 {
20538 return m_type == value_t::string;
20539 }
20540
20543 constexpr bool is_binary() const noexcept
20544 {
20545 return m_type == value_t::binary;
20546 }
20547
20550 constexpr bool is_discarded() const noexcept
20551 {
20552 return m_type == value_t::discarded;
20553 }
20554
20557 constexpr operator value_t() const noexcept
20558 {
20559 return m_type;
20560 }
20561
20563
20564 private:
20566 // value access //
20568
20570 boolean_t get_impl(boolean_t* /*unused*/) const
20571 {
20573 {
20574 return m_value.boolean;
20575 }
20576
20577 JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
20578 }
20579
20581 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20582 {
20583 return is_object() ? m_value.object : nullptr;
20584 }
20585
20587 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20588 {
20589 return is_object() ? m_value.object : nullptr;
20590 }
20591
20593 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20594 {
20595 return is_array() ? m_value.array : nullptr;
20596 }
20597
20599 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20600 {
20601 return is_array() ? m_value.array : nullptr;
20602 }
20603
20605 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20606 {
20607 return is_string() ? m_value.string : nullptr;
20608 }
20609
20611 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20612 {
20613 return is_string() ? m_value.string : nullptr;
20614 }
20615
20617 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20618 {
20619 return is_boolean() ? &m_value.boolean : nullptr;
20620 }
20621
20623 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20624 {
20625 return is_boolean() ? &m_value.boolean : nullptr;
20626 }
20627
20629 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20630 {
20631 return is_number_integer() ? &m_value.number_integer : nullptr;
20632 }
20633
20635 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20636 {
20637 return is_number_integer() ? &m_value.number_integer : nullptr;
20638 }
20639
20641 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20642 {
20643 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20644 }
20645
20647 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20648 {
20649 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20650 }
20651
20653 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20654 {
20655 return is_number_float() ? &m_value.number_float : nullptr;
20656 }
20657
20659 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20660 {
20661 return is_number_float() ? &m_value.number_float : nullptr;
20662 }
20663
20665 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20666 {
20667 return is_binary() ? m_value.binary : nullptr;
20668 }
20669
20671 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20672 {
20673 return is_binary() ? m_value.binary : nullptr;
20674 }
20675
20687 template<typename ReferenceType, typename ThisType>
20688 static ReferenceType get_ref_impl(ThisType& obj)
20689 {
20690 // delegate the call to get_ptr<>()
20691 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20692
20693 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20694 {
20695 return *ptr;
20696 }
20697
20698 JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20699 }
20700
20701 public:
20705
20708 template<typename PointerType, typename std::enable_if<
20709 std::is_pointer<PointerType>::value, int>::type = 0>
20710 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20711 {
20712 // delegate the call to get_impl_ptr<>()
20713 return get_impl_ptr(static_cast<PointerType>(nullptr));
20714 }
20715
20718 template < typename PointerType, typename std::enable_if <
20719 std::is_pointer<PointerType>::value&&
20720 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20721 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20722 {
20723 // delegate the call to get_impl_ptr<>() const
20724 return get_impl_ptr(static_cast<PointerType>(nullptr));
20725 }
20726
20727 private:
20766 template < typename ValueType,
20770 int > = 0 >
20771 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20772 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20773 {
20774 auto ret = ValueType();
20775 JSONSerializer<ValueType>::from_json(*this, ret);
20776 return ret;
20777 }
20778
20809 template < typename ValueType,
20812 int > = 0 >
20813 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20814 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20815 {
20816 return JSONSerializer<ValueType>::from_json(*this);
20817 }
20818
20834 template < typename BasicJsonType,
20837 int > = 0 >
20838 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20839 {
20840 return *this;
20841 }
20842
20857 template<typename BasicJsonType,
20859 std::is_same<BasicJsonType, basic_json_t>::value,
20860 int> = 0>
20861 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20862 {
20863 return *this;
20864 }
20865
20870 template<typename PointerType,
20872 std::is_pointer<PointerType>::value,
20873 int> = 0>
20874 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20875 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20876 {
20877 // delegate the call to get_ptr
20878 return get_ptr<PointerType>();
20879 }
20880
20881 public:
20905 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20906#if defined(JSON_HAS_CPP_14)
20907 constexpr
20908#endif
20909 auto get() const noexcept(
20910 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20911 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20912 {
20913 // we cannot static_assert on ValueTypeCV being non-const, because
20914 // there is support for get<const basic_json_t>(), which is why we
20915 // still need the uncvref
20916 static_assert(!std::is_reference<ValueTypeCV>::value,
20917 "get() cannot be used with reference types, you might want to use get_ref()");
20918 return get_impl<ValueType>(detail::priority_tag<4> {});
20919 }
20920
20948 template<typename PointerType, typename std::enable_if<
20949 std::is_pointer<PointerType>::value, int>::type = 0>
20950 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20951 {
20952 // delegate the call to get_ptr
20953 return get_ptr<PointerType>();
20954 }
20955
20958 template < typename ValueType,
20962 int > = 0 >
20963 ValueType & get_to(ValueType& v) const noexcept(noexcept(
20964 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20965 {
20966 JSONSerializer<ValueType>::from_json(*this, v);
20967 return v;
20968 }
20969
20970 // specialization to allow calling get_to with a basic_json value
20971 // see https://github.com/nlohmann/json/issues/2175
20972 template<typename ValueType,
20975 int> = 0>
20976 ValueType & get_to(ValueType& v) const
20977 {
20978 v = *this;
20979 return v;
20980 }
20981
20982 template <
20983 typename T, std::size_t N,
20984 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20987 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20988 noexcept(noexcept(JSONSerializer<Array>::from_json(
20989 std::declval<const basic_json_t&>(), v)))
20990 {
20991 JSONSerializer<Array>::from_json(*this, v);
20992 return v;
20993 }
20994
20997 template<typename ReferenceType, typename std::enable_if<
20998 std::is_reference<ReferenceType>::value, int>::type = 0>
20999 ReferenceType get_ref()
21000 {
21001 // delegate call to get_ref_impl
21002 return get_ref_impl<ReferenceType>(*this);
21003 }
21004
21007 template < typename ReferenceType, typename std::enable_if <
21008 std::is_reference<ReferenceType>::value&&
21009 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
21010 ReferenceType get_ref() const
21011 {
21012 // delegate call to get_ref_impl
21013 return get_ref_impl<ReferenceType>(*this);
21014 }
21015
21045 template < typename ValueType, typename std::enable_if <
21053#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21055#endif
21056#if defined(JSON_HAS_CPP_17)
21058#endif
21060 >::value, int >::type = 0 >
21061 JSON_EXPLICIT operator ValueType() const
21062 {
21063 // delegate the call to get<>() const
21064 return get<ValueType>();
21065 }
21066
21070 {
21071 if (!is_binary())
21072 {
21073 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21074 }
21075
21076 return *get_ptr<binary_t*>();
21077 }
21078
21081 const binary_t& get_binary() const
21082 {
21083 if (!is_binary())
21084 {
21085 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21086 }
21087
21088 return *get_ptr<const binary_t*>();
21089 }
21090
21092
21093
21095 // element access //
21097
21101
21105 {
21106 // at only works for arrays
21108 {
21109 JSON_TRY
21110 {
21111 return set_parent(m_value.array->at(idx));
21112 }
21113 JSON_CATCH (std::out_of_range&)
21114 {
21115 // create better exception explanation
21116 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21117 }
21118 }
21119 else
21120 {
21121 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21122 }
21123 }
21124
21128 {
21129 // at only works for arrays
21131 {
21132 JSON_TRY
21133 {
21134 return m_value.array->at(idx);
21135 }
21136 JSON_CATCH (std::out_of_range&)
21137 {
21138 // create better exception explanation
21139 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21140 }
21141 }
21142 else
21143 {
21144 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21145 }
21146 }
21147
21150 reference at(const typename object_t::key_type& key)
21151 {
21152 // at only works for objects
21154 {
21155 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21156 }
21157
21158 auto it = m_value.object->find(key);
21159 if (it == m_value.object->end())
21160 {
21161 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21162 }
21163 return set_parent(it->second);
21164 }
21165
21168 template<class KeyType, detail::enable_if_t<
21170 reference at(KeyType && key)
21171 {
21172 // at only works for objects
21174 {
21175 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21176 }
21177
21178 auto it = m_value.object->find(std::forward<KeyType>(key));
21179 if (it == m_value.object->end())
21180 {
21181 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21182 }
21183 return set_parent(it->second);
21184 }
21185
21188 const_reference at(const typename object_t::key_type& key) const
21189 {
21190 // at only works for objects
21192 {
21193 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21194 }
21195
21196 auto it = m_value.object->find(key);
21197 if (it == m_value.object->end())
21198 {
21199 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21200 }
21201 return it->second;
21202 }
21203
21206 template<class KeyType, detail::enable_if_t<
21208 const_reference at(KeyType && key) const
21209 {
21210 // at only works for objects
21212 {
21213 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21214 }
21215
21216 auto it = m_value.object->find(std::forward<KeyType>(key));
21217 if (it == m_value.object->end())
21218 {
21219 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21220 }
21221 return it->second;
21222 }
21223
21227 {
21228 // implicitly convert null value to an empty array
21229 if (is_null())
21230 {
21231 m_type = value_t::array;
21232 m_value.array = create<array_t>();
21233 assert_invariant();
21234 }
21235
21236 // operator[] only works for arrays
21238 {
21239 // fill up array with null values if given idx is outside range
21240 if (idx >= m_value.array->size())
21241 {
21242#if JSON_DIAGNOSTICS
21243 // remember array size & capacity before resizing
21244 const auto old_size = m_value.array->size();
21245 const auto old_capacity = m_value.array->capacity();
21246#endif
21247 m_value.array->resize(idx + 1);
21248
21249#if JSON_DIAGNOSTICS
21250 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
21251 {
21252 // capacity has changed: update all parents
21253 set_parents();
21254 }
21255 else
21256 {
21257 // set parent for values added above
21258 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21259 }
21260#endif
21261 assert_invariant();
21262 }
21263
21264 return m_value.array->operator[](idx);
21265 }
21266
21267 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21268 }
21269
21273 {
21274 // const operator[] only works for arrays
21276 {
21277 return m_value.array->operator[](idx);
21278 }
21279
21280 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21281 }
21282
21285 reference operator[](typename object_t::key_type key)
21286 {
21287 // implicitly convert null value to an empty object
21288 if (is_null())
21289 {
21290 m_type = value_t::object;
21291 m_value.object = create<object_t>();
21292 assert_invariant();
21293 }
21294
21295 // operator[] only works for objects
21297 {
21298 auto result = m_value.object->emplace(std::move(key), nullptr);
21299 return set_parent(result.first->second);
21300 }
21301
21302 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21303 }
21304
21307 const_reference operator[](const typename object_t::key_type& key) const
21308 {
21309 // const operator[] only works for objects
21311 {
21312 auto it = m_value.object->find(key);
21313 JSON_ASSERT(it != m_value.object->end());
21314 return it->second;
21315 }
21316
21317 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21318 }
21319
21320 // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
21321 // (they seemingly cannot be constrained to resolve the ambiguity)
21322 template<typename T>
21324 {
21325 return operator[](typename object_t::key_type(key));
21326 }
21327
21328 template<typename T>
21330 {
21331 return operator[](typename object_t::key_type(key));
21332 }
21333
21336 template<class KeyType, detail::enable_if_t<
21338 reference operator[](KeyType && key)
21339 {
21340 // implicitly convert null value to an empty object
21341 if (is_null())
21342 {
21343 m_type = value_t::object;
21344 m_value.object = create<object_t>();
21345 assert_invariant();
21346 }
21347
21348 // operator[] only works for objects
21350 {
21351 auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr);
21352 return set_parent(result.first->second);
21353 }
21354
21355 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21356 }
21357
21360 template<class KeyType, detail::enable_if_t<
21362 const_reference operator[](KeyType && key) const
21363 {
21364 // const operator[] only works for objects
21366 {
21367 auto it = m_value.object->find(std::forward<KeyType>(key));
21368 JSON_ASSERT(it != m_value.object->end());
21369 return it->second;
21370 }
21371
21372 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21373 }
21374
21375 private:
21376 template<typename KeyType>
21377 using is_comparable_with_object_key = detail::is_comparable <
21378 object_comparator_t, const typename object_t::key_type&, KeyType >;
21379
21380 template<typename ValueType>
21381 using value_return_type = std::conditional <
21383 string_t, typename std::decay<ValueType>::type >;
21384
21385 public:
21388 template < class ValueType, detail::enable_if_t <
21391 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21392 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21393 {
21394 // value only works for objects
21396 {
21397 // if key is found, return value and given default value otherwise
21398 const auto it = find(key);
21399 if (it != end())
21400 {
21401 return it->template get<ValueType>();
21402 }
21403
21404 return default_value;
21405 }
21406
21407 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21408 }
21409
21412 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21416 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21417 ReturnType value(const typename object_t::key_type& key, ValueType && default_value) const
21418 {
21419 // value only works for objects
21421 {
21422 // if key is found, return value and given default value otherwise
21423 const auto it = find(key);
21424 if (it != end())
21425 {
21426 return it->template get<ReturnType>();
21427 }
21428
21429 return std::forward<ValueType>(default_value);
21430 }
21431
21432 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21433 }
21434
21437 template < class ValueType, class KeyType, detail::enable_if_t <
21440 && is_comparable_with_object_key<KeyType>::value
21442 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21443 ValueType value(KeyType && key, const ValueType& default_value) const
21444 {
21445 // value only works for objects
21447 {
21448 // if key is found, return value and given default value otherwise
21449 const auto it = find(std::forward<KeyType>(key));
21450 if (it != end())
21451 {
21452 return it->template get<ValueType>();
21453 }
21454
21455 return default_value;
21456 }
21457
21458 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21459 }
21460
21463 template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
21467 && is_comparable_with_object_key<KeyType>::value
21469 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21470 ReturnType value(KeyType && key, ValueType && default_value) const
21471 {
21472 // value only works for objects
21474 {
21475 // if key is found, return value and given default value otherwise
21476 const auto it = find(std::forward<KeyType>(key));
21477 if (it != end())
21478 {
21479 return it->template get<ReturnType>();
21480 }
21481
21482 return std::forward<ValueType>(default_value);
21483 }
21484
21485 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21486 }
21487
21490 template < class ValueType, detail::enable_if_t <
21492 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21493 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21494 {
21495 // value only works for objects
21497 {
21498 // if pointer resolves a value, return it or use default value
21499 JSON_TRY
21500 {
21501 return ptr.get_checked(this).template get<ValueType>();
21502 }
21504 {
21505 return default_value;
21506 }
21507 }
21508
21509 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21510 }
21511
21514 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21517 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21518 ReturnType value(const json_pointer& ptr, ValueType && default_value) const
21519 {
21520 // value only works for objects
21522 {
21523 // if pointer resolves a value, return it or use default value
21524 JSON_TRY
21525 {
21526 return ptr.get_checked(this).template get<ReturnType>();
21527 }
21529 {
21530 return std::forward<ValueType>(default_value);
21531 }
21532 }
21533
21534 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21535 }
21536
21537 template < class ValueType, class BasicJsonType, detail::enable_if_t <
21540 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21541 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21542 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
21543 {
21544 return value(ptr.convert(), default_value);
21545 }
21546
21547 template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
21551 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21552 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21553 ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType && default_value) const
21554 {
21555 return value(ptr.convert(), std::forward<ValueType>(default_value));
21556 }
21557
21561 {
21562 return *begin();
21563 }
21564
21568 {
21569 return *cbegin();
21570 }
21571
21575 {
21576 auto tmp = end();
21577 --tmp;
21578 return *tmp;
21579 }
21580
21584 {
21585 auto tmp = cend();
21586 --tmp;
21587 return *tmp;
21588 }
21589
21592 template < class IteratorType, detail::enable_if_t <
21593 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21594 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21595 IteratorType erase(IteratorType pos)
21596 {
21597 // make sure iterator fits the current value
21598 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21599 {
21600 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21601 }
21602
21603 IteratorType result = end();
21604
21605 switch (m_type)
21606 {
21607 case value_t::boolean:
21608 case value_t::number_float:
21609 case value_t::number_integer:
21610 case value_t::number_unsigned:
21611 case value_t::string:
21612 case value_t::binary:
21613 {
21614 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21615 {
21616 JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
21617 }
21618
21619 if (is_string())
21620 {
21621 AllocatorType<string_t> alloc;
21622 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21623 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21624 m_value.string = nullptr;
21625 }
21626 else if (is_binary())
21627 {
21628 AllocatorType<binary_t> alloc;
21629 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21630 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21631 m_value.binary = nullptr;
21632 }
21633
21634 m_type = value_t::null;
21635 assert_invariant();
21636 break;
21637 }
21638
21639 case value_t::object:
21640 {
21641 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21642 break;
21643 }
21644
21645 case value_t::array:
21646 {
21647 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21648 break;
21649 }
21650
21651 case value_t::null:
21652 case value_t::discarded:
21653 default:
21654 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21655 }
21656
21657 return result;
21658 }
21659
21662 template < class IteratorType, detail::enable_if_t <
21663 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21664 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21665 IteratorType erase(IteratorType first, IteratorType last)
21666 {
21667 // make sure iterator fits the current value
21668 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21669 {
21670 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
21671 }
21672
21673 IteratorType result = end();
21674
21675 switch (m_type)
21676 {
21677 case value_t::boolean:
21678 case value_t::number_float:
21679 case value_t::number_integer:
21680 case value_t::number_unsigned:
21681 case value_t::string:
21682 case value_t::binary:
21683 {
21684 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21685 || !last.m_it.primitive_iterator.is_end()))
21686 {
21687 JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21688 }
21689
21690 if (is_string())
21691 {
21692 AllocatorType<string_t> alloc;
21693 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21694 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21695 m_value.string = nullptr;
21696 }
21697 else if (is_binary())
21698 {
21699 AllocatorType<binary_t> alloc;
21700 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21701 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21702 m_value.binary = nullptr;
21703 }
21704
21705 m_type = value_t::null;
21706 assert_invariant();
21707 break;
21708 }
21709
21710 case value_t::object:
21711 {
21712 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21713 last.m_it.object_iterator);
21714 break;
21715 }
21716
21717 case value_t::array:
21718 {
21719 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21720 last.m_it.array_iterator);
21721 break;
21722 }
21723
21724 case value_t::null:
21725 case value_t::discarded:
21726 default:
21727 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21728 }
21729
21730 return result;
21731 }
21732
21733 private:
21734 template < typename KeyType, detail::enable_if_t <
21736 size_type erase_internal(KeyType && key)
21737 {
21738 // this erase only works for objects
21740 {
21741 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21742 }
21743
21744 return m_value.object->erase(std::forward<KeyType>(key));
21745 }
21746
21747 template < typename KeyType, detail::enable_if_t <
21749 size_type erase_internal(KeyType && key)
21750 {
21751 // this erase only works for objects
21753 {
21754 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21755 }
21756
21757 const auto it = m_value.object->find(std::forward<KeyType>(key));
21758 if (it != m_value.object->end())
21759 {
21760 m_value.object->erase(it);
21761 return 1;
21762 }
21763 return 0;
21764 }
21765
21766 public:
21767
21770 size_type erase(const typename object_t::key_type& key)
21771 {
21772 // the indirection via erase_internal() is added to avoid making this
21773 // function a template and thus de-rank it during overload resolution
21774 return erase_internal(key);
21775 }
21776
21779 template<class KeyType, detail::enable_if_t<
21781 size_type erase(KeyType && key)
21782 {
21783 return erase_internal(std::forward<KeyType>(key));
21784 }
21785
21788 void erase(const size_type idx)
21789 {
21790 // this erase only works for arrays
21792 {
21793 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21794 {
21795 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21796 }
21797
21798 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21799 }
21800 else
21801 {
21802 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21803 }
21804 }
21805
21807
21808
21810 // lookup //
21812
21815
21818 iterator find(const typename object_t::key_type& key)
21819 {
21820 auto result = end();
21821
21822 if (is_object())
21823 {
21824 result.m_it.object_iterator = m_value.object->find(key);
21825 }
21826
21827 return result;
21828 }
21829
21832 const_iterator find(const typename object_t::key_type& key) const
21833 {
21834 auto result = cend();
21835
21836 if (is_object())
21837 {
21838 result.m_it.object_iterator = m_value.object->find(key);
21839 }
21840
21841 return result;
21842 }
21843
21846 template<class KeyType, detail::enable_if_t<
21848 iterator find(KeyType && key)
21849 {
21850 auto result = end();
21851
21852 if (is_object())
21853 {
21854 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
21855 }
21856
21857 return result;
21858 }
21859
21862 template<class KeyType, detail::enable_if_t<
21864 const_iterator find(KeyType && key) const
21865 {
21866 auto result = cend();
21867
21868 if (is_object())
21869 {
21870 result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
21871 }
21872
21873 return result;
21874 }
21875
21878 size_type count(const typename object_t::key_type& key) const
21879 {
21880 // return 0 for all nonobject types
21881 return is_object() ? m_value.object->count(key) : 0;
21882 }
21883
21886 template<class KeyType, detail::enable_if_t<
21888 size_type count(KeyType && key) const
21889 {
21890 // return 0 for all nonobject types
21891 return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0;
21892 }
21893
21896 bool contains(const typename object_t::key_type& key) const
21897 {
21898 return is_object() && m_value.object->find(key) != m_value.object->end();
21899 }
21900
21903 template<class KeyType, detail::enable_if_t<
21905 bool contains(KeyType && key) const
21906 {
21907 return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end();
21908 }
21909
21912 bool contains(const json_pointer& ptr) const
21913 {
21914 return ptr.contains(this);
21915 }
21916
21917 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
21918 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21919 bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
21920 {
21921 return ptr.contains(this);
21922 }
21923
21925
21926
21928 // iterators //
21930
21933
21936 iterator begin() noexcept
21937 {
21938 iterator result(this);
21939 result.set_begin();
21940 return result;
21941 }
21942
21945 const_iterator begin() const noexcept
21946 {
21947 return cbegin();
21948 }
21949
21952 const_iterator cbegin() const noexcept
21953 {
21954 const_iterator result(this);
21955 result.set_begin();
21956 return result;
21957 }
21958
21961 iterator end() noexcept
21962 {
21963 iterator result(this);
21964 result.set_end();
21965 return result;
21966 }
21967
21970 const_iterator end() const noexcept
21971 {
21972 return cend();
21973 }
21974
21977 const_iterator cend() const noexcept
21978 {
21979 const_iterator result(this);
21980 result.set_end();
21981 return result;
21982 }
21983
21987 {
21988 return reverse_iterator(end());
21989 }
21990
21994 {
21995 return crbegin();
21996 }
21997
22001 {
22002 return reverse_iterator(begin());
22003 }
22004
22008 {
22009 return crend();
22010 }
22011
22015 {
22016 return const_reverse_iterator(cend());
22017 }
22018
22022 {
22024 }
22025
22026 public:
22033 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22034 {
22035 return ref.items();
22036 }
22037
22044 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22045 {
22046 return ref.items();
22047 }
22048
22051 iteration_proxy<iterator> items() noexcept
22052 {
22053 return iteration_proxy<iterator>(*this);
22054 }
22055
22058 iteration_proxy<const_iterator> items() const noexcept
22059 {
22060 return iteration_proxy<const_iterator>(*this);
22061 }
22062
22064
22065
22067 // capacity //
22069
22072
22075 bool empty() const noexcept
22076 {
22077 switch (m_type)
22078 {
22079 case value_t::null:
22080 {
22081 // null values are empty
22082 return true;
22083 }
22084
22085 case value_t::array:
22086 {
22087 // delegate call to array_t::empty()
22088 return m_value.array->empty();
22089 }
22090
22091 case value_t::object:
22092 {
22093 // delegate call to object_t::empty()
22094 return m_value.object->empty();
22095 }
22096
22097 case value_t::string:
22098 case value_t::boolean:
22099 case value_t::number_integer:
22100 case value_t::number_unsigned:
22101 case value_t::number_float:
22102 case value_t::binary:
22103 case value_t::discarded:
22104 default:
22105 {
22106 // all other types are nonempty
22107 return false;
22108 }
22109 }
22110 }
22111
22114 size_type size() const noexcept
22115 {
22116 switch (m_type)
22117 {
22118 case value_t::null:
22119 {
22120 // null values are empty
22121 return 0;
22122 }
22123
22124 case value_t::array:
22125 {
22126 // delegate call to array_t::size()
22127 return m_value.array->size();
22128 }
22129
22130 case value_t::object:
22131 {
22132 // delegate call to object_t::size()
22133 return m_value.object->size();
22134 }
22135
22136 case value_t::string:
22137 case value_t::boolean:
22138 case value_t::number_integer:
22139 case value_t::number_unsigned:
22140 case value_t::number_float:
22141 case value_t::binary:
22142 case value_t::discarded:
22143 default:
22144 {
22145 // all other types have size 1
22146 return 1;
22147 }
22148 }
22149 }
22150
22153 size_type max_size() const noexcept
22154 {
22155 switch (m_type)
22156 {
22157 case value_t::array:
22158 {
22159 // delegate call to array_t::max_size()
22160 return m_value.array->max_size();
22161 }
22162
22163 case value_t::object:
22164 {
22165 // delegate call to object_t::max_size()
22166 return m_value.object->max_size();
22167 }
22168
22169 case value_t::null:
22170 case value_t::string:
22171 case value_t::boolean:
22172 case value_t::number_integer:
22173 case value_t::number_unsigned:
22174 case value_t::number_float:
22175 case value_t::binary:
22176 case value_t::discarded:
22177 default:
22178 {
22179 // all other types have max_size() == size()
22180 return size();
22181 }
22182 }
22183 }
22184
22186
22187
22189 // modifiers //
22191
22194
22197 void clear() noexcept
22198 {
22199 switch (m_type)
22200 {
22201 case value_t::number_integer:
22202 {
22203 m_value.number_integer = 0;
22204 break;
22205 }
22206
22207 case value_t::number_unsigned:
22208 {
22209 m_value.number_unsigned = 0;
22210 break;
22211 }
22212
22213 case value_t::number_float:
22214 {
22215 m_value.number_float = 0.0;
22216 break;
22217 }
22218
22219 case value_t::boolean:
22220 {
22221 m_value.boolean = false;
22222 break;
22223 }
22224
22225 case value_t::string:
22226 {
22227 m_value.string->clear();
22228 break;
22229 }
22230
22231 case value_t::binary:
22232 {
22233 m_value.binary->clear();
22234 break;
22235 }
22236
22237 case value_t::array:
22238 {
22239 m_value.array->clear();
22240 break;
22241 }
22242
22243 case value_t::object:
22244 {
22245 m_value.object->clear();
22246 break;
22247 }
22248
22249 case value_t::null:
22250 case value_t::discarded:
22251 default:
22252 break;
22253 }
22254 }
22255
22259 {
22260 // push_back only works for null objects or arrays
22261 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22262 {
22263 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22264 }
22265
22266 // transform null object into an array
22267 if (is_null())
22268 {
22269 m_type = value_t::array;
22270 m_value = value_t::array;
22271 assert_invariant();
22272 }
22273
22274 // add element to array (move semantics)
22275 const auto old_capacity = m_value.array->capacity();
22276 m_value.array->push_back(std::move(val));
22277 set_parent(m_value.array->back(), old_capacity);
22278 // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
22279 }
22280
22284 {
22285 push_back(std::move(val));
22286 return *this;
22287 }
22288
22291 void push_back(const basic_json& val)
22292 {
22293 // push_back only works for null objects or arrays
22294 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22295 {
22296 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22297 }
22298
22299 // transform null object into an array
22300 if (is_null())
22301 {
22302 m_type = value_t::array;
22303 m_value = value_t::array;
22304 assert_invariant();
22305 }
22306
22307 // add element to array
22308 const auto old_capacity = m_value.array->capacity();
22309 m_value.array->push_back(val);
22310 set_parent(m_value.array->back(), old_capacity);
22311 }
22312
22316 {
22317 push_back(val);
22318 return *this;
22319 }
22320
22323 void push_back(const typename object_t::value_type& val)
22324 {
22325 // push_back only works for null objects or objects
22326 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22327 {
22328 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22329 }
22330
22331 // transform null object into an object
22332 if (is_null())
22333 {
22334 m_type = value_t::object;
22335 m_value = value_t::object;
22336 assert_invariant();
22337 }
22338
22339 // add element to object
22340 auto res = m_value.object->insert(val);
22341 set_parent(res.first->second);
22342 }
22343
22346 reference operator+=(const typename object_t::value_type& val)
22347 {
22348 push_back(val);
22349 return *this;
22350 }
22351
22355 {
22356 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22357 {
22358 basic_json&& key = init.begin()->moved_or_copied();
22359 push_back(typename object_t::value_type(
22360 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22361 }
22362 else
22363 {
22364 push_back(basic_json(init));
22365 }
22366 }
22367
22371 {
22372 push_back(init);
22373 return *this;
22374 }
22375
22378 template<class... Args>
22379 reference emplace_back(Args&& ... args)
22380 {
22381 // emplace_back only works for null objects or arrays
22382 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22383 {
22384 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
22385 }
22386
22387 // transform null object into an array
22388 if (is_null())
22389 {
22390 m_type = value_t::array;
22391 m_value = value_t::array;
22392 assert_invariant();
22393 }
22394
22395 // add element to array (perfect forwarding)
22396 const auto old_capacity = m_value.array->capacity();
22397 m_value.array->emplace_back(std::forward<Args>(args)...);
22398 return set_parent(m_value.array->back(), old_capacity);
22399 }
22400
22403 template<class... Args>
22404 std::pair<iterator, bool> emplace(Args&& ... args)
22405 {
22406 // emplace only works for null objects or arrays
22407 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22408 {
22409 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
22410 }
22411
22412 // transform null object into an object
22413 if (is_null())
22414 {
22415 m_type = value_t::object;
22416 m_value = value_t::object;
22417 assert_invariant();
22418 }
22419
22420 // add element to array (perfect forwarding)
22421 auto res = m_value.object->emplace(std::forward<Args>(args)...);
22422 set_parent(res.first->second);
22423
22424 // create result iterator and set iterator to the result of emplace
22425 auto it = begin();
22426 it.m_it.object_iterator = res.first;
22427
22428 // return pair of iterator and boolean
22429 return {it, res.second};
22430 }
22431
22435 template<typename... Args>
22437 {
22438 iterator result(this);
22439 JSON_ASSERT(m_value.array != nullptr);
22440
22441 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22442 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22443 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22444
22445 // This could have been written as:
22446 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22447 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22448
22449 set_parents();
22450 return result;
22451 }
22452
22456 {
22457 // insert only works for arrays
22459 {
22460 // check if iterator pos fits to this JSON value
22461 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22462 {
22463 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22464 }
22465
22466 // insert to array and return iterator
22467 return insert_iterator(pos, val);
22468 }
22469
22470 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22471 }
22472
22476 {
22477 return insert(pos, val);
22478 }
22479
22483 {
22484 // insert only works for arrays
22486 {
22487 // check if iterator pos fits to this JSON value
22488 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22489 {
22490 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22491 }
22492
22493 // insert to array and return iterator
22494 return insert_iterator(pos, cnt, val);
22495 }
22496
22497 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22498 }
22499
22503 {
22504 // insert only works for arrays
22506 {
22507 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22508 }
22509
22510 // check if iterator pos fits to this JSON value
22511 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22512 {
22513 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22514 }
22515
22516 // check if range iterators belong to the same JSON object
22517 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22518 {
22519 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22520 }
22521
22522 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22523 {
22524 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
22525 }
22526
22527 // insert to array and return iterator
22528 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22529 }
22530
22534 {
22535 // insert only works for arrays
22537 {
22538 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22539 }
22540
22541 // check if iterator pos fits to this JSON value
22542 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22543 {
22544 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22545 }
22546
22547 // insert to array and return iterator
22548 return insert_iterator(pos, ilist.begin(), ilist.end());
22549 }
22550
22554 {
22555 // insert only works for objects
22557 {
22558 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22559 }
22560
22561 // check if range iterators belong to the same JSON object
22562 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22563 {
22564 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22565 }
22566
22567 // passed iterators must belong to objects
22568 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22569 {
22570 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
22571 }
22572
22573 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22574 }
22575
22578 void update(const_reference j, bool merge_objects = false)
22579 {
22580 update(j.begin(), j.end(), merge_objects);
22581 }
22582
22585 void update(const_iterator first, const_iterator last, bool merge_objects = false)
22586 {
22587 // implicitly convert null value to an empty object
22588 if (is_null())
22589 {
22590 m_type = value_t::object;
22591 m_value.object = create<object_t>();
22592 assert_invariant();
22593 }
22594
22596 {
22597 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
22598 }
22599
22600 // check if range iterators belong to the same JSON object
22601 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22602 {
22603 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22604 }
22605
22606 // passed iterators must belong to objects
22607 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22608 {
22609 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
22610 }
22611
22612 for (auto it = first; it != last; ++it)
22613 {
22614 if (merge_objects && it.value().is_object())
22615 {
22616 auto it2 = m_value.object->find(it.key());
22617 if (it2 != m_value.object->end())
22618 {
22619 it2->second.update(it.value(), true);
22620 continue;
22621 }
22622 }
22623 m_value.object->operator[](it.key()) = it.value();
22624#if JSON_DIAGNOSTICS
22625 m_value.object->operator[](it.key()).m_parent = this;
22626#endif
22627 }
22628 }
22629
22632 void swap(reference other) noexcept (
22633 std::is_nothrow_move_constructible<value_t>::value&&
22634 std::is_nothrow_move_assignable<value_t>::value&&
22635 std::is_nothrow_move_constructible<json_value>::value&&
22636 std::is_nothrow_move_assignable<json_value>::value
22637 )
22638 {
22639 std::swap(m_type, other.m_type);
22640 std::swap(m_value, other.m_value);
22641
22642 set_parents();
22643 other.set_parents();
22644 assert_invariant();
22645 }
22646
22649 friend void swap(reference left, reference right) noexcept (
22650 std::is_nothrow_move_constructible<value_t>::value&&
22651 std::is_nothrow_move_assignable<value_t>::value&&
22652 std::is_nothrow_move_constructible<json_value>::value&&
22653 std::is_nothrow_move_assignable<json_value>::value
22654 )
22655 {
22656 left.swap(right);
22657 }
22658
22661 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
22662 {
22663 // swap only works for arrays
22665 {
22666 using std::swap;
22667 swap(*(m_value.array), other);
22668 }
22669 else
22670 {
22671 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
22672 }
22673 }
22674
22677 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
22678 {
22679 // swap only works for objects
22681 {
22682 using std::swap;
22683 swap(*(m_value.object), other);
22684 }
22685 else
22686 {
22687 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
22688 }
22689 }
22690
22693 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
22694 {
22695 // swap only works for strings
22697 {
22698 using std::swap;
22699 swap(*(m_value.string), other);
22700 }
22701 else
22702 {
22703 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
22704 }
22705 }
22706
22709 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
22710 {
22711 // swap only works for strings
22713 {
22714 using std::swap;
22715 swap(*(m_value.binary), other);
22716 }
22717 else
22718 {
22719 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
22720 }
22721 }
22722
22725 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22726 {
22727 // swap only works for strings
22729 {
22730 using std::swap;
22731 swap(*(m_value.binary), other);
22732 }
22733 else
22734 {
22735 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
22736 }
22737 }
22738
22740
22742 // lexicographical comparison operators //
22744
22747
22748 // note parentheses around operands are necessary; see
22749 // https://github.com/nlohmann/json/issues/1530
22750#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22751 const auto lhs_type = lhs.type(); \
22752 const auto rhs_type = rhs.type(); \
22753 \
22754 if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22755 { \
22756 switch (lhs_type) \
22757 { \
22758 case value_t::array: \
22759 return (*lhs.m_value.array) op (*rhs.m_value.array); \
22760 \
22761 case value_t::object: \
22762 return (*lhs.m_value.object) op (*rhs.m_value.object); \
22763 \
22764 case value_t::null: \
22765 return (null_result); \
22766 \
22767 case value_t::string: \
22768 return (*lhs.m_value.string) op (*rhs.m_value.string); \
22769 \
22770 case value_t::boolean: \
22771 return (lhs.m_value.boolean) op (rhs.m_value.boolean); \
22772 \
22773 case value_t::number_integer: \
22774 return (lhs.m_value.number_integer) op (rhs.m_value.number_integer); \
22775 \
22776 case value_t::number_unsigned: \
22777 return (lhs.m_value.number_unsigned) op (rhs.m_value.number_unsigned); \
22778 \
22779 case value_t::number_float: \
22780 return (lhs.m_value.number_float) op (rhs.m_value.number_float); \
22781 \
22782 case value_t::binary: \
22783 return (*lhs.m_value.binary) op (*rhs.m_value.binary); \
22784 \
22785 case value_t::discarded: \
22786 default: \
22787 return (unordered_result); \
22788 } \
22789 } \
22790 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22791 { \
22792 return static_cast<number_float_t>(lhs.m_value.number_integer) op rhs.m_value.number_float; \
22793 } \
22794 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22795 { \
22796 return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_integer); \
22797 } \
22798 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22799 { \
22800 return static_cast<number_float_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_float; \
22801 } \
22802 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22803 { \
22804 return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_unsigned); \
22805 } \
22806 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22807 { \
22808 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_integer; \
22809 } \
22810 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22811 { \
22812 return lhs.m_value.number_integer op static_cast<number_integer_t>(rhs.m_value.number_unsigned); \
22813 } \
22814 else if(compares_unordered(lhs, rhs))\
22815 {\
22816 return (unordered_result);\
22817 }\
22818 \
22819 return (default_result);
22820
22822 // returns true if:
22823 // - any operand is NaN and the other operand is of number type
22824 // - any operand is discarded
22825 // in legacy mode, discarded values are considered ordered if
22826 // an operation is computed as an odd number of inverses of others
22827 static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22828 {
22829 if ((lhs.is_number_float() && std::isnan(lhs.m_value.number_float) && rhs.is_number())
22830 || (rhs.is_number_float() && std::isnan(rhs.m_value.number_float) && lhs.is_number()))
22831 {
22832 return true;
22833 }
22834#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22835 return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22836#else
22837 static_cast<void>(inverse);
22838 return lhs.is_discarded() || rhs.is_discarded();
22839#endif
22840 }
22841
22842 private:
22843 bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22844 {
22845 return compares_unordered(*this, rhs, inverse);
22846 }
22847
22848 public:
22849#if JSON_HAS_THREE_WAY_COMPARISON
22852 bool operator==(const_reference rhs) const noexcept
22853 {
22854#ifdef __GNUC__
22855#pragma GCC diagnostic push
22856#pragma GCC diagnostic ignored "-Wfloat-equal"
22857#endif
22858 const_reference lhs = *this;
22859 JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22860#ifdef __GNUC__
22861#pragma GCC diagnostic pop
22862#endif
22863 }
22864
22867 template<typename ScalarType>
22868 requires std::is_scalar_v<ScalarType>
22869 bool operator==(ScalarType rhs) const noexcept
22870 {
22871 return *this == basic_json(rhs);
22872 }
22873
22876 bool operator!=(const_reference rhs) const noexcept
22877 {
22878 if (compares_unordered(rhs, true))
22879 {
22880 return false;
22881 }
22882 return !operator==(rhs);
22883 }
22884
22887 std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
22888 {
22889 const_reference lhs = *this;
22890 // default_result is used if we cannot compare values. In that case,
22891 // we compare types.
22892 JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
22893 std::partial_ordering::equivalent,
22894 std::partial_ordering::unordered,
22895 lhs_type <=> rhs_type) // *NOPAD*
22896 }
22897
22900 template<typename ScalarType>
22901 requires std::is_scalar_v<ScalarType>
22902 std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
22903 {
22904 return *this <=> basic_json(rhs); // *NOPAD*
22905 }
22906
22907#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22908 // all operators that are computed as an odd number of inverses of others
22909 // need to be overloaded to emulate the legacy comparison behavior
22910
22914 bool operator<=(const_reference rhs) const noexcept
22915 {
22916 if (compares_unordered(rhs, true))
22917 {
22918 return false;
22919 }
22920 return !(rhs < *this);
22921 }
22922
22925 template<typename ScalarType>
22926 requires std::is_scalar_v<ScalarType>
22927 bool operator<=(ScalarType rhs) const noexcept
22928 {
22929 return *this <= basic_json(rhs);
22930 }
22931
22935 bool operator>=(const_reference rhs) const noexcept
22936 {
22937 if (compares_unordered(rhs, true))
22938 {
22939 return false;
22940 }
22941 return !(*this < rhs);
22942 }
22943
22946 template<typename ScalarType>
22947 requires std::is_scalar_v<ScalarType>
22948 bool operator>=(ScalarType rhs) const noexcept
22949 {
22950 return *this >= basic_json(rhs);
22951 }
22952#endif
22953#else
22956 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22957 {
22958#ifdef __GNUC__
22959#pragma GCC diagnostic push
22960#pragma GCC diagnostic ignored "-Wfloat-equal"
22961#endif
22962 JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22963#ifdef __GNUC__
22964#pragma GCC diagnostic pop
22965#endif
22966 }
22967
22970 template<typename ScalarType, typename std::enable_if<
22971 std::is_scalar<ScalarType>::value, int>::type = 0>
22972 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
22973 {
22974 return lhs == basic_json(rhs);
22975 }
22976
22979 template<typename ScalarType, typename std::enable_if<
22980 std::is_scalar<ScalarType>::value, int>::type = 0>
22981 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
22982 {
22983 return basic_json(lhs) == rhs;
22984 }
22985
22988 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22989 {
22990 if (compares_unordered(lhs, rhs, true))
22991 {
22992 return false;
22993 }
22994 return !(lhs == rhs);
22995 }
22996
22999 template<typename ScalarType, typename std::enable_if<
23000 std::is_scalar<ScalarType>::value, int>::type = 0>
23001 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23002 {
23003 return lhs != basic_json(rhs);
23004 }
23005
23008 template<typename ScalarType, typename std::enable_if<
23009 std::is_scalar<ScalarType>::value, int>::type = 0>
23010 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23011 {
23012 return basic_json(lhs) != rhs;
23013 }
23014
23017 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23018 {
23019 // default_result is used if we cannot compare values. In that case,
23020 // we compare types. Note we have to call the operator explicitly,
23021 // because MSVC has problems otherwise.
23022 JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
23023 }
23024
23027 template<typename ScalarType, typename std::enable_if<
23028 std::is_scalar<ScalarType>::value, int>::type = 0>
23029 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23030 {
23031 return lhs < basic_json(rhs);
23032 }
23033
23036 template<typename ScalarType, typename std::enable_if<
23037 std::is_scalar<ScalarType>::value, int>::type = 0>
23038 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23039 {
23040 return basic_json(lhs) < rhs;
23041 }
23042
23045 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23046 {
23047 if (compares_unordered(lhs, rhs, true))
23048 {
23049 return false;
23050 }
23051 return !(rhs < lhs);
23052 }
23053
23056 template<typename ScalarType, typename std::enable_if<
23057 std::is_scalar<ScalarType>::value, int>::type = 0>
23058 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23059 {
23060 return lhs <= basic_json(rhs);
23061 }
23062
23065 template<typename ScalarType, typename std::enable_if<
23066 std::is_scalar<ScalarType>::value, int>::type = 0>
23067 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23068 {
23069 return basic_json(lhs) <= rhs;
23070 }
23071
23074 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23075 {
23076 // double inverse
23077 if (compares_unordered(lhs, rhs))
23078 {
23079 return false;
23080 }
23081 return !(lhs <= rhs);
23082 }
23083
23086 template<typename ScalarType, typename std::enable_if<
23087 std::is_scalar<ScalarType>::value, int>::type = 0>
23088 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23089 {
23090 return lhs > basic_json(rhs);
23091 }
23092
23095 template<typename ScalarType, typename std::enable_if<
23096 std::is_scalar<ScalarType>::value, int>::type = 0>
23097 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23098 {
23099 return basic_json(lhs) > rhs;
23100 }
23101
23104 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23105 {
23106 if (compares_unordered(lhs, rhs, true))
23107 {
23108 return false;
23109 }
23110 return !(lhs < rhs);
23111 }
23112
23115 template<typename ScalarType, typename std::enable_if<
23116 std::is_scalar<ScalarType>::value, int>::type = 0>
23117 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23118 {
23119 return lhs >= basic_json(rhs);
23120 }
23121
23124 template<typename ScalarType, typename std::enable_if<
23125 std::is_scalar<ScalarType>::value, int>::type = 0>
23126 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23127 {
23128 return basic_json(lhs) >= rhs;
23129 }
23130#endif
23131
23132#undef JSON_IMPLEMENT_OPERATOR
23133
23135
23137 // serialization //
23139
23142#ifndef JSON_NO_IO
23145 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23146 {
23147 // read width member and use it as indentation parameter if nonzero
23148 const bool pretty_print = o.width() > 0;
23149 const auto indentation = pretty_print ? o.width() : 0;
23150
23151 // reset width to 0 for subsequent calls to this stream
23152 o.width(0);
23153
23154 // do the actual serialization
23155 serializer s(detail::output_adapter<char>(o), o.fill());
23156 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23157 return o;
23158 }
23159
23166 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23167 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23168 {
23169 return o << j;
23170 }
23171#endif // JSON_NO_IO
23173
23174
23176 // deserialization //
23178
23181
23184 template<typename InputType>
23186 static basic_json parse(InputType&& i,
23187 const parser_callback_t cb = nullptr,
23188 const bool allow_exceptions = true,
23189 const bool ignore_comments = false)
23190 {
23191 basic_json result;
23192 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23193 return result;
23194 }
23195
23198 template<typename IteratorType>
23200 static basic_json parse(IteratorType first,
23201 IteratorType last,
23202 const parser_callback_t cb = nullptr,
23203 const bool allow_exceptions = true,
23204 const bool ignore_comments = false)
23205 {
23206 basic_json result;
23207 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23208 return result;
23209 }
23210
23212 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23213 static basic_json parse(detail::span_input_adapter&& i,
23214 const parser_callback_t cb = nullptr,
23215 const bool allow_exceptions = true,
23216 const bool ignore_comments = false)
23217 {
23218 basic_json result;
23219 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23220 return result;
23221 }
23222
23225 template<typename InputType>
23226 static bool accept(InputType&& i,
23227 const bool ignore_comments = false)
23228 {
23229 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23230 }
23231
23234 template<typename IteratorType>
23235 static bool accept(IteratorType first, IteratorType last,
23236 const bool ignore_comments = false)
23237 {
23238 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23239 }
23240
23242 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23243 static bool accept(detail::span_input_adapter&& i,
23244 const bool ignore_comments = false)
23245 {
23246 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23247 }
23248
23251 template <typename InputType, typename SAX>
23253 static bool sax_parse(InputType&& i, SAX* sax,
23255 const bool strict = true,
23256 const bool ignore_comments = false)
23257 {
23258 auto ia = detail::input_adapter(std::forward<InputType>(i));
23259 return format == input_format_t::json
23260 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23261 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23262 }
23263
23266 template<class IteratorType, class SAX>
23268 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23270 const bool strict = true,
23271 const bool ignore_comments = false)
23272 {
23273 auto ia = detail::input_adapter(std::move(first), std::move(last));
23274 return format == input_format_t::json
23275 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23276 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23277 }
23278
23284 template <typename SAX>
23285 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23287 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23289 const bool strict = true,
23290 const bool ignore_comments = false)
23291 {
23292 auto ia = i.get();
23293 return format == input_format_t::json
23294 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23295 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23296 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23297 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23298 }
23299#ifndef JSON_NO_IO
23306 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23307 friend std::istream& operator<<(basic_json& j, std::istream& i)
23308 {
23309 return operator>>(i, j);
23310 }
23311
23314 friend std::istream& operator>>(std::istream& i, basic_json& j)
23315 {
23316 parser(detail::input_adapter(i)).parse(false, j);
23317 return i;
23318 }
23319#endif // JSON_NO_IO
23321
23323 // convenience functions //
23325
23329 const char* type_name() const noexcept
23330 {
23331 switch (m_type)
23332 {
23333 case value_t::null:
23334 return "null";
23335 case value_t::object:
23336 return "object";
23337 case value_t::array:
23338 return "array";
23339 case value_t::string:
23340 return "string";
23341 case value_t::boolean:
23342 return "boolean";
23343 case value_t::binary:
23344 return "binary";
23345 case value_t::discarded:
23346 return "discarded";
23347 case value_t::number_integer:
23348 case value_t::number_unsigned:
23349 case value_t::number_float:
23350 default:
23351 return "number";
23352 }
23353 }
23354
23355
23358 // member variables //
23360
23362 value_t m_type = value_t::null;
23363
23365 json_value m_value = {};
23366
23367#if JSON_DIAGNOSTICS
23369 basic_json* m_parent = nullptr;
23370#endif
23371
23373 // binary serialization/deserialization //
23375
23378
23379 public:
23382 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
23383 {
23384 std::vector<std::uint8_t> result;
23385 to_cbor(j, result);
23386 return result;
23387 }
23388
23392 {
23393 binary_writer<std::uint8_t>(o).write_cbor(j);
23394 }
23395
23399 {
23400 binary_writer<char>(o).write_cbor(j);
23401 }
23402
23405 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
23406 {
23407 std::vector<std::uint8_t> result;
23408 to_msgpack(j, result);
23409 return result;
23410 }
23411
23415 {
23416 binary_writer<std::uint8_t>(o).write_msgpack(j);
23417 }
23418
23422 {
23423 binary_writer<char>(o).write_msgpack(j);
23424 }
23425
23428 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
23429 const bool use_size = false,
23430 const bool use_type = false)
23431 {
23432 std::vector<std::uint8_t> result;
23433 to_ubjson(j, result, use_size, use_type);
23434 return result;
23435 }
23436
23440 const bool use_size = false, const bool use_type = false)
23441 {
23442 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
23443 }
23444
23448 const bool use_size = false, const bool use_type = false)
23449 {
23450 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23451 }
23452
23455 static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
23456 const bool use_size = false,
23457 const bool use_type = false)
23458 {
23459 std::vector<std::uint8_t> result;
23460 to_bjdata(j, result, use_size, use_type);
23461 return result;
23462 }
23463
23467 const bool use_size = false, const bool use_type = false)
23468 {
23469 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
23470 }
23471
23475 const bool use_size = false, const bool use_type = false)
23476 {
23477 binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
23478 }
23479
23482 static std::vector<std::uint8_t> to_bson(const basic_json& j)
23483 {
23484 std::vector<std::uint8_t> result;
23485 to_bson(j, result);
23486 return result;
23487 }
23488
23492 {
23493 binary_writer<std::uint8_t>(o).write_bson(j);
23494 }
23495
23499 {
23500 binary_writer<char>(o).write_bson(j);
23501 }
23502
23505 template<typename InputType>
23507 static basic_json from_cbor(InputType&& i,
23508 const bool strict = true,
23509 const bool allow_exceptions = true,
23510 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23511 {
23512 basic_json result;
23513 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23514 auto ia = detail::input_adapter(std::forward<InputType>(i));
23515 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23516 return res ? result : basic_json(value_t::discarded);
23517 }
23518
23521 template<typename IteratorType>
23523 static basic_json from_cbor(IteratorType first, IteratorType last,
23524 const bool strict = true,
23525 const bool allow_exceptions = true,
23526 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23527 {
23528 basic_json result;
23529 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23530 auto ia = detail::input_adapter(std::move(first), std::move(last));
23531 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23532 return res ? result : basic_json(value_t::discarded);
23533 }
23534
23535 template<typename T>
23537 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23538 static basic_json from_cbor(const T* ptr, std::size_t len,
23539 const bool strict = true,
23540 const bool allow_exceptions = true,
23541 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23542 {
23543 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23544 }
23545
23546
23548 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23549 static basic_json from_cbor(detail::span_input_adapter&& i,
23550 const bool strict = true,
23551 const bool allow_exceptions = true,
23552 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23553 {
23554 basic_json result;
23555 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23556 auto ia = i.get();
23557 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23558 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23559 return res ? result : basic_json(value_t::discarded);
23560 }
23561
23564 template<typename InputType>
23566 static basic_json from_msgpack(InputType&& i,
23567 const bool strict = true,
23568 const bool allow_exceptions = true)
23569 {
23570 basic_json result;
23571 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23572 auto ia = detail::input_adapter(std::forward<InputType>(i));
23573 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23574 return res ? result : basic_json(value_t::discarded);
23575 }
23576
23579 template<typename IteratorType>
23581 static basic_json from_msgpack(IteratorType first, IteratorType last,
23582 const bool strict = true,
23583 const bool allow_exceptions = true)
23584 {
23585 basic_json result;
23586 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23587 auto ia = detail::input_adapter(std::move(first), std::move(last));
23588 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23589 return res ? result : basic_json(value_t::discarded);
23590 }
23591
23592 template<typename T>
23594 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23595 static basic_json from_msgpack(const T* ptr, std::size_t len,
23596 const bool strict = true,
23597 const bool allow_exceptions = true)
23598 {
23599 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23600 }
23601
23603 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23604 static basic_json from_msgpack(detail::span_input_adapter&& i,
23605 const bool strict = true,
23606 const bool allow_exceptions = true)
23607 {
23608 basic_json result;
23609 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23610 auto ia = i.get();
23611 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23612 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23613 return res ? result : basic_json(value_t::discarded);
23614 }
23615
23618 template<typename InputType>
23620 static basic_json from_ubjson(InputType&& i,
23621 const bool strict = true,
23622 const bool allow_exceptions = true)
23623 {
23624 basic_json result;
23625 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23626 auto ia = detail::input_adapter(std::forward<InputType>(i));
23627 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23628 return res ? result : basic_json(value_t::discarded);
23629 }
23630
23633 template<typename IteratorType>
23635 static basic_json from_ubjson(IteratorType first, IteratorType last,
23636 const bool strict = true,
23637 const bool allow_exceptions = true)
23638 {
23639 basic_json result;
23640 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23641 auto ia = detail::input_adapter(std::move(first), std::move(last));
23642 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23643 return res ? result : basic_json(value_t::discarded);
23644 }
23645
23646 template<typename T>
23648 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23649 static basic_json from_ubjson(const T* ptr, std::size_t len,
23650 const bool strict = true,
23651 const bool allow_exceptions = true)
23652 {
23653 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23654 }
23655
23657 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23658 static basic_json from_ubjson(detail::span_input_adapter&& i,
23659 const bool strict = true,
23660 const bool allow_exceptions = true)
23661 {
23662 basic_json result;
23663 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23664 auto ia = i.get();
23665 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23666 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23667 return res ? result : basic_json(value_t::discarded);
23668 }
23669
23670
23673 template<typename InputType>
23675 static basic_json from_bjdata(InputType&& i,
23676 const bool strict = true,
23677 const bool allow_exceptions = true)
23678 {
23679 basic_json result;
23680 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23681 auto ia = detail::input_adapter(std::forward<InputType>(i));
23682 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23683 return res ? result : basic_json(value_t::discarded);
23684 }
23685
23688 template<typename IteratorType>
23690 static basic_json from_bjdata(IteratorType first, IteratorType last,
23691 const bool strict = true,
23692 const bool allow_exceptions = true)
23693 {
23694 basic_json result;
23695 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23696 auto ia = detail::input_adapter(std::move(first), std::move(last));
23697 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23698 return res ? result : basic_json(value_t::discarded);
23699 }
23700
23703 template<typename InputType>
23705 static basic_json from_bson(InputType&& i,
23706 const bool strict = true,
23707 const bool allow_exceptions = true)
23708 {
23709 basic_json result;
23710 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23711 auto ia = detail::input_adapter(std::forward<InputType>(i));
23712 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23713 return res ? result : basic_json(value_t::discarded);
23714 }
23715
23718 template<typename IteratorType>
23720 static basic_json from_bson(IteratorType first, IteratorType last,
23721 const bool strict = true,
23722 const bool allow_exceptions = true)
23723 {
23724 basic_json result;
23725 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23726 auto ia = detail::input_adapter(std::move(first), std::move(last));
23727 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23728 return res ? result : basic_json(value_t::discarded);
23729 }
23730
23731 template<typename T>
23733 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23734 static basic_json from_bson(const T* ptr, std::size_t len,
23735 const bool strict = true,
23736 const bool allow_exceptions = true)
23737 {
23738 return from_bson(ptr, ptr + len, strict, allow_exceptions);
23739 }
23740
23742 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23743 static basic_json from_bson(detail::span_input_adapter&& i,
23744 const bool strict = true,
23745 const bool allow_exceptions = true)
23746 {
23747 basic_json result;
23748 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23749 auto ia = i.get();
23750 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23751 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23752 return res ? result : basic_json(value_t::discarded);
23753 }
23755
23757 // JSON Pointer support //
23759
23762
23766 {
23767 return ptr.get_unchecked(this);
23768 }
23769
23770 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23771 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23772 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23773 {
23774 return ptr.get_unchecked(this);
23775 }
23776
23780 {
23781 return ptr.get_unchecked(this);
23782 }
23783
23784 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23785 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23786 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23787 {
23788 return ptr.get_unchecked(this);
23789 }
23790
23794 {
23795 return ptr.get_checked(this);
23796 }
23797
23798 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23799 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23800 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23801 {
23802 return ptr.get_checked(this);
23803 }
23804
23808 {
23809 return ptr.get_checked(this);
23810 }
23811
23812 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23813 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23814 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23815 {
23816 return ptr.get_checked(this);
23817 }
23818
23822 {
23823 basic_json result(value_t::object);
23824 json_pointer::flatten("", *this, result);
23825 return result;
23826 }
23827
23831 {
23832 return json_pointer::unflatten(*this);
23833 }
23834
23836
23838 // JSON Patch functions //
23840
23843
23846 void patch_inplace(const basic_json& json_patch)
23847 {
23848 basic_json& result = *this;
23849 // the valid JSON Patch operations
23850 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23851
23852 const auto get_op = [](const std::string & op)
23853 {
23854 if (op == "add")
23855 {
23856 return patch_operations::add;
23857 }
23858 if (op == "remove")
23859 {
23860 return patch_operations::remove;
23861 }
23862 if (op == "replace")
23863 {
23864 return patch_operations::replace;
23865 }
23866 if (op == "move")
23867 {
23868 return patch_operations::move;
23869 }
23870 if (op == "copy")
23871 {
23872 return patch_operations::copy;
23873 }
23874 if (op == "test")
23875 {
23876 return patch_operations::test;
23877 }
23878
23879 return patch_operations::invalid;
23880 };
23881
23882 // wrapper for "add" operation; add value at ptr
23883 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
23884 {
23885 // adding to the root of the target document means replacing it
23886 if (ptr.empty())
23887 {
23888 result = val;
23889 return;
23890 }
23891
23892 // make sure the top element of the pointer exists
23893 json_pointer top_pointer = ptr.top();
23894 if (top_pointer != ptr)
23895 {
23896 result.at(top_pointer);
23897 }
23898
23899 // get reference to parent of JSON pointer ptr
23900 const auto last_path = ptr.back();
23901 ptr.pop_back();
23902 // parent must exist when performing patch add per RFC6902 specs
23903 basic_json& parent = result.at(ptr);
23904
23905 switch (parent.m_type)
23906 {
23907 case value_t::null:
23908 case value_t::object:
23909 {
23910 // use operator[] to add value
23911 parent[last_path] = val;
23912 break;
23913 }
23914
23915 case value_t::array:
23916 {
23917 if (last_path == "-")
23918 {
23919 // special case: append to back
23920 parent.push_back(val);
23921 }
23922 else
23923 {
23924 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
23925 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
23926 {
23927 // avoid undefined behavior
23928 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
23929 }
23930
23931 // default case: insert add offset
23932 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
23933 }
23934 break;
23935 }
23936
23937 // if there exists a parent it cannot be primitive
23938 case value_t::string: // LCOV_EXCL_LINE
23939 case value_t::boolean: // LCOV_EXCL_LINE
23940 case value_t::number_integer: // LCOV_EXCL_LINE
23941 case value_t::number_unsigned: // LCOV_EXCL_LINE
23942 case value_t::number_float: // LCOV_EXCL_LINE
23943 case value_t::binary: // LCOV_EXCL_LINE
23944 case value_t::discarded: // LCOV_EXCL_LINE
23945 default: // LCOV_EXCL_LINE
23946 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
23947 }
23948 };
23949
23950 // wrapper for "remove" operation; remove value at ptr
23951 const auto operation_remove = [this, &result](json_pointer & ptr)
23952 {
23953 // get reference to parent of JSON pointer ptr
23954 const auto last_path = ptr.back();
23955 ptr.pop_back();
23956 basic_json& parent = result.at(ptr);
23957
23958 // remove child
23959 if (parent.is_object())
23960 {
23961 // perform range check
23962 auto it = parent.find(last_path);
23963 if (JSON_HEDLEY_LIKELY(it != parent.end()))
23964 {
23965 parent.erase(it);
23966 }
23967 else
23968 {
23969 JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
23970 }
23971 }
23972 else if (parent.is_array())
23973 {
23974 // note erase performs range check
23975 parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
23976 }
23977 };
23978
23979 // type check: top level value must be an array
23980 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
23981 {
23982 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
23983 }
23984
23985 // iterate and apply the operations
23986 for (const auto& val : json_patch)
23987 {
23988 // wrapper to get a value for an operation
23989 const auto get_value = [&val](const std::string & op,
23990 const std::string & member,
23991 bool string_type) -> basic_json &
23992 {
23993 // find value
23994 auto it = val.m_value.object->find(member);
23995
23996 // context-sensitive error message
23997 const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
23998
23999 // check if desired value is present
24000 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24001 {
24002 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24003 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
24004 }
24005
24006 // check if result is of type string
24007 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24008 {
24009 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24010 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
24011 }
24012
24013 // no error: return value
24014 return it->second;
24015 };
24016
24017 // type check: every element of the array must be an object
24018 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24019 {
24020 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
24021 }
24022
24023 // collect mandatory members
24024 const auto op = get_value("op", "op", true).template get<std::string>();
24025 const auto path = get_value(op, "path", true).template get<std::string>();
24026 json_pointer ptr(path);
24027
24028 switch (get_op(op))
24029 {
24030 case patch_operations::add:
24031 {
24032 operation_add(ptr, get_value("add", "value", false));
24033 break;
24034 }
24035
24036 case patch_operations::remove:
24037 {
24038 operation_remove(ptr);
24039 break;
24040 }
24041
24042 case patch_operations::replace:
24043 {
24044 // the "path" location must exist - use at()
24045 result.at(ptr) = get_value("replace", "value", false);
24046 break;
24047 }
24048
24049 case patch_operations::move:
24050 {
24051 const auto from_path = get_value("move", "from", true).template get<std::string>();
24052 json_pointer from_ptr(from_path);
24053
24054 // the "from" location must exist - use at()
24055 basic_json v = result.at(from_ptr);
24056
24057 // The move operation is functionally identical to a
24058 // "remove" operation on the "from" location, followed
24059 // immediately by an "add" operation at the target
24060 // location with the value that was just removed.
24061 operation_remove(from_ptr);
24062 operation_add(ptr, v);
24063 break;
24064 }
24065
24066 case patch_operations::copy:
24067 {
24068 const auto from_path = get_value("copy", "from", true).template get<std::string>();
24069 const json_pointer from_ptr(from_path);
24070
24071 // the "from" location must exist - use at()
24072 basic_json v = result.at(from_ptr);
24073
24074 // The copy is functionally identical to an "add"
24075 // operation at the target location using the value
24076 // specified in the "from" member.
24077 operation_add(ptr, v);
24078 break;
24079 }
24080
24081 case patch_operations::test:
24082 {
24083 bool success = false;
24084 JSON_TRY
24085 {
24086 // check if "value" matches the one at "path"
24087 // the "path" location must exist - use at()
24088 success = (result.at(ptr) == get_value("test", "value", false));
24089 }
24091 {
24092 // ignore out of range errors: success remains false
24093 }
24094
24095 // throw an exception if test fails
24096 if (JSON_HEDLEY_UNLIKELY(!success))
24097 {
24098 JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
24099 }
24100
24101 break;
24102 }
24103
24104 case patch_operations::invalid:
24105 default:
24106 {
24107 // op must be "add", "remove", "replace", "move", "copy", or
24108 // "test"
24109 JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
24110 }
24111 }
24112 }
24113 }
24114
24117 basic_json patch(const basic_json& json_patch) const
24118 {
24119 basic_json result = *this;
24120 result.patch_inplace(json_patch);
24121 return result;
24122 }
24123
24127 static basic_json diff(const basic_json& source, const basic_json& target,
24128 const std::string& path = "")
24129 {
24130 // the patch
24131 basic_json result(value_t::array);
24132
24133 // if the values are the same, return empty patch
24134 if (source == target)
24135 {
24136 return result;
24137 }
24138
24139 if (source.type() != target.type())
24140 {
24141 // different types: replace value
24142 result.push_back(
24143 {
24144 {"op", "replace"}, {"path", path}, {"value", target}
24145 });
24146 return result;
24147 }
24148
24149 switch (source.type())
24150 {
24151 case value_t::array:
24152 {
24153 // first pass: traverse common elements
24154 std::size_t i = 0;
24155 while (i < source.size() && i < target.size())
24156 {
24157 // recursive call to compare array values at index i
24158 auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
24159 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24160 ++i;
24161 }
24162
24163 // We now reached the end of at least one array
24164 // in a second pass, traverse the remaining elements
24165
24166 // remove my remaining elements
24167 const auto end_index = static_cast<difference_type>(result.size());
24168 while (i < source.size())
24169 {
24170 // add operations in reverse order to avoid invalid
24171 // indices
24172 result.insert(result.begin() + end_index, object(
24173 {
24174 {"op", "remove"},
24175 {"path", detail::concat(path, '/', std::to_string(i))}
24176 }));
24177 ++i;
24178 }
24179
24180 // add other remaining elements
24181 while (i < target.size())
24182 {
24183 result.push_back(
24184 {
24185 {"op", "add"},
24186 {"path", detail::concat(path, "/-")},
24187 {"value", target[i]}
24188 });
24189 ++i;
24190 }
24191
24192 break;
24193 }
24194
24195 case value_t::object:
24196 {
24197 // first pass: traverse this object's elements
24198 for (auto it = source.cbegin(); it != source.cend(); ++it)
24199 {
24200 // escape the key name to be used in a JSON patch
24201 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24202
24203 if (target.find(it.key()) != target.end())
24204 {
24205 // recursive call to compare object values at key it
24206 auto temp_diff = diff(it.value(), target[it.key()], path_key);
24207 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24208 }
24209 else
24210 {
24211 // found a key that is not in o -> remove it
24212 result.push_back(object(
24213 {
24214 {"op", "remove"}, {"path", path_key}
24215 }));
24216 }
24217 }
24218
24219 // second pass: traverse other object's elements
24220 for (auto it = target.cbegin(); it != target.cend(); ++it)
24221 {
24222 if (source.find(it.key()) == source.end())
24223 {
24224 // found a key that is not in this -> add it
24225 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24226 result.push_back(
24227 {
24228 {"op", "add"}, {"path", path_key},
24229 {"value", it.value()}
24230 });
24231 }
24232 }
24233
24234 break;
24235 }
24236
24237 case value_t::null:
24238 case value_t::string:
24239 case value_t::boolean:
24240 case value_t::number_integer:
24241 case value_t::number_unsigned:
24242 case value_t::number_float:
24243 case value_t::binary:
24244 case value_t::discarded:
24245 default:
24246 {
24247 // both primitive type: replace value
24248 result.push_back(
24249 {
24250 {"op", "replace"}, {"path", path}, {"value", target}
24251 });
24252 break;
24253 }
24254 }
24255
24256 return result;
24257 }
24259
24261 // JSON Merge Patch functions //
24263
24266
24269 void merge_patch(const basic_json& apply_patch)
24270 {
24271 if (apply_patch.is_object())
24272 {
24273 if (!is_object())
24274 {
24275 *this = object();
24276 }
24277 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24278 {
24279 if (it.value().is_null())
24280 {
24281 erase(it.key());
24282 }
24283 else
24284 {
24285 operator[](it.key()).merge_patch(it.value());
24286 }
24287 }
24288 }
24289 else
24290 {
24291 *this = apply_patch;
24292 }
24293 }
24294
24296};
24297
24302{
24303 return j.dump();
24304}
24305
24306inline namespace literals
24307{
24308inline namespace json_literals
24309{
24310
24314inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24315{
24316 return nlohmann::json::parse(s, s + n);
24317}
24318
24322inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24323{
24324 return nlohmann::json::json_pointer(std::string(s, n));
24325}
24326
24327} // namespace json_literals
24328} // namespace literals
24330
24332// nonmember support //
24334
24335namespace std // NOLINT(cert-dcl58-cpp)
24336{
24337
24341struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>
24342{
24343 std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
24344 {
24345 return nlohmann::detail::hash(j);
24346 }
24347};
24348
24349// specialization for std::less<value_t>
24350template<>
24351struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
24352{
24357 bool operator()(::nlohmann::detail::value_t lhs,
24358 ::nlohmann::detail::value_t rhs) const noexcept
24359 {
24360#if JSON_HAS_THREE_WAY_COMPARISON
24361 return std::is_lt(lhs <=> rhs); // *NOPAD*
24362#else
24363 return ::nlohmann::detail::operator<(lhs, rhs);
24364#endif
24365 }
24366};
24367
24368// C++20 prohibit function specialization in the std namespace.
24369#ifndef JSON_HAS_CPP_20
24370
24374inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
24375 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
24376 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
24377{
24378 j1.swap(j2);
24379}
24380
24381#endif
24382
24383} // namespace std
24384
24385#if JSON_USE_GLOBAL_UDLS
24386 using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24387 using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24388#endif
24389
24390// #include <nlohmann/detail/macro_unscope.hpp>
24391// __ _____ _____ _____
24392// __| | __| | | | JSON for Modern C++
24393// | | |__ | | | | | | version 3.11.2
24394// |_____|_____|_____|_|___| https://github.com/nlohmann/json
24395//
24396// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24397// SPDX-License-Identifier: MIT
24398
24399
24400
24401// restore clang diagnostic settings
24402#if defined(__clang__)
24403 #pragma clang diagnostic pop
24404#endif
24405
24406// clean up
24407#undef JSON_ASSERT
24408#undef JSON_INTERNAL_CATCH
24409#undef JSON_THROW
24410#undef JSON_PRIVATE_UNLESS_TESTED
24411#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24412#undef NLOHMANN_BASIC_JSON_TPL
24413#undef JSON_EXPLICIT
24414#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
24415#undef JSON_INLINE_VARIABLE
24416#undef JSON_NO_UNIQUE_ADDRESS
24417#undef JSON_DISABLE_ENUM_SERIALIZATION
24418#undef JSON_USE_GLOBAL_UDLS
24419
24420#ifndef JSON_TEST_KEEP_MACROS
24421 #undef JSON_CATCH
24422 #undef JSON_TRY
24423 #undef JSON_HAS_CPP_11
24424 #undef JSON_HAS_CPP_14
24425 #undef JSON_HAS_CPP_17
24426 #undef JSON_HAS_CPP_20
24427 #undef JSON_HAS_FILESYSTEM
24428 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
24429 #undef JSON_HAS_THREE_WAY_COMPARISON
24430 #undef JSON_HAS_RANGES
24431 #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
24432#endif
24433
24434// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24435// __ _____ _____ _____
24436// __| | __| | | | JSON for Modern C++
24437// | | |__ | | | | | | version 3.11.2
24438// |_____|_____|_____|_|___| https://github.com/nlohmann/json
24439//
24440// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
24441// SPDX-License-Identifier: MIT
24442
24443
24444
24445#undef JSON_HEDLEY_ALWAYS_INLINE
24446#undef JSON_HEDLEY_ARM_VERSION
24447#undef JSON_HEDLEY_ARM_VERSION_CHECK
24448#undef JSON_HEDLEY_ARRAY_PARAM
24449#undef JSON_HEDLEY_ASSUME
24450#undef JSON_HEDLEY_BEGIN_C_DECLS
24451#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24452#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24453#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24454#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24455#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24456#undef JSON_HEDLEY_CLANG_HAS_FEATURE
24457#undef JSON_HEDLEY_CLANG_HAS_WARNING
24458#undef JSON_HEDLEY_COMPCERT_VERSION
24459#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24460#undef JSON_HEDLEY_CONCAT
24461#undef JSON_HEDLEY_CONCAT3
24462#undef JSON_HEDLEY_CONCAT3_EX
24463#undef JSON_HEDLEY_CONCAT_EX
24464#undef JSON_HEDLEY_CONST
24465#undef JSON_HEDLEY_CONSTEXPR
24466#undef JSON_HEDLEY_CONST_CAST
24467#undef JSON_HEDLEY_CPP_CAST
24468#undef JSON_HEDLEY_CRAY_VERSION
24469#undef JSON_HEDLEY_CRAY_VERSION_CHECK
24470#undef JSON_HEDLEY_C_DECL
24471#undef JSON_HEDLEY_DEPRECATED
24472#undef JSON_HEDLEY_DEPRECATED_FOR
24473#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24474#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24475#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24476#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24477#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24478#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
24479#undef JSON_HEDLEY_DIAGNOSTIC_POP
24480#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24481#undef JSON_HEDLEY_DMC_VERSION
24482#undef JSON_HEDLEY_DMC_VERSION_CHECK
24483#undef JSON_HEDLEY_EMPTY_BASES
24484#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24485#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24486#undef JSON_HEDLEY_END_C_DECLS
24487#undef JSON_HEDLEY_FLAGS
24488#undef JSON_HEDLEY_FLAGS_CAST
24489#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24490#undef JSON_HEDLEY_GCC_HAS_BUILTIN
24491#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24492#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24493#undef JSON_HEDLEY_GCC_HAS_EXTENSION
24494#undef JSON_HEDLEY_GCC_HAS_FEATURE
24495#undef JSON_HEDLEY_GCC_HAS_WARNING
24496#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24497#undef JSON_HEDLEY_GCC_VERSION
24498#undef JSON_HEDLEY_GCC_VERSION_CHECK
24499#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24500#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24501#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24502#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24503#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24504#undef JSON_HEDLEY_GNUC_HAS_FEATURE
24505#undef JSON_HEDLEY_GNUC_HAS_WARNING
24506#undef JSON_HEDLEY_GNUC_VERSION
24507#undef JSON_HEDLEY_GNUC_VERSION_CHECK
24508#undef JSON_HEDLEY_HAS_ATTRIBUTE
24509#undef JSON_HEDLEY_HAS_BUILTIN
24510#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24511#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24512#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24513#undef JSON_HEDLEY_HAS_EXTENSION
24514#undef JSON_HEDLEY_HAS_FEATURE
24515#undef JSON_HEDLEY_HAS_WARNING
24516#undef JSON_HEDLEY_IAR_VERSION
24517#undef JSON_HEDLEY_IAR_VERSION_CHECK
24518#undef JSON_HEDLEY_IBM_VERSION
24519#undef JSON_HEDLEY_IBM_VERSION_CHECK
24520#undef JSON_HEDLEY_IMPORT
24521#undef JSON_HEDLEY_INLINE
24522#undef JSON_HEDLEY_INTEL_CL_VERSION
24523#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
24524#undef JSON_HEDLEY_INTEL_VERSION
24525#undef JSON_HEDLEY_INTEL_VERSION_CHECK
24526#undef JSON_HEDLEY_IS_CONSTANT
24527#undef JSON_HEDLEY_IS_CONSTEXPR_
24528#undef JSON_HEDLEY_LIKELY
24529#undef JSON_HEDLEY_MALLOC
24530#undef JSON_HEDLEY_MCST_LCC_VERSION
24531#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
24532#undef JSON_HEDLEY_MESSAGE
24533#undef JSON_HEDLEY_MSVC_VERSION
24534#undef JSON_HEDLEY_MSVC_VERSION_CHECK
24535#undef JSON_HEDLEY_NEVER_INLINE
24536#undef JSON_HEDLEY_NON_NULL
24537#undef JSON_HEDLEY_NO_ESCAPE
24538#undef JSON_HEDLEY_NO_RETURN
24539#undef JSON_HEDLEY_NO_THROW
24540#undef JSON_HEDLEY_NULL
24541#undef JSON_HEDLEY_PELLES_VERSION
24542#undef JSON_HEDLEY_PELLES_VERSION_CHECK
24543#undef JSON_HEDLEY_PGI_VERSION
24544#undef JSON_HEDLEY_PGI_VERSION_CHECK
24545#undef JSON_HEDLEY_PREDICT
24546#undef JSON_HEDLEY_PRINTF_FORMAT
24547#undef JSON_HEDLEY_PRIVATE
24548#undef JSON_HEDLEY_PUBLIC
24549#undef JSON_HEDLEY_PURE
24550#undef JSON_HEDLEY_REINTERPRET_CAST
24551#undef JSON_HEDLEY_REQUIRE
24552#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24553#undef JSON_HEDLEY_REQUIRE_MSG
24554#undef JSON_HEDLEY_RESTRICT
24555#undef JSON_HEDLEY_RETURNS_NON_NULL
24556#undef JSON_HEDLEY_SENTINEL
24557#undef JSON_HEDLEY_STATIC_ASSERT
24558#undef JSON_HEDLEY_STATIC_CAST
24559#undef JSON_HEDLEY_STRINGIFY
24560#undef JSON_HEDLEY_STRINGIFY_EX
24561#undef JSON_HEDLEY_SUNPRO_VERSION
24562#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24563#undef JSON_HEDLEY_TINYC_VERSION
24564#undef JSON_HEDLEY_TINYC_VERSION_CHECK
24565#undef JSON_HEDLEY_TI_ARMCL_VERSION
24566#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24567#undef JSON_HEDLEY_TI_CL2000_VERSION
24568#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24569#undef JSON_HEDLEY_TI_CL430_VERSION
24570#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24571#undef JSON_HEDLEY_TI_CL6X_VERSION
24572#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24573#undef JSON_HEDLEY_TI_CL7X_VERSION
24574#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24575#undef JSON_HEDLEY_TI_CLPRU_VERSION
24576#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24577#undef JSON_HEDLEY_TI_VERSION
24578#undef JSON_HEDLEY_TI_VERSION_CHECK
24579#undef JSON_HEDLEY_UNAVAILABLE
24580#undef JSON_HEDLEY_UNLIKELY
24581#undef JSON_HEDLEY_UNPREDICTABLE
24582#undef JSON_HEDLEY_UNREACHABLE
24583#undef JSON_HEDLEY_UNREACHABLE_RETURN
24584#undef JSON_HEDLEY_VERSION
24585#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24586#undef JSON_HEDLEY_VERSION_DECODE_MINOR
24587#undef JSON_HEDLEY_VERSION_DECODE_REVISION
24588#undef JSON_HEDLEY_VERSION_ENCODE
24589#undef JSON_HEDLEY_WARNING
24590#undef JSON_HEDLEY_WARN_UNUSED_RESULT
24591#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
24592#undef JSON_HEDLEY_FALL_THROUGH
24593
24594
24595
24596#endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::json json
Definition: WeArtMessageSerializer.cpp:4
namespace for Niels Lohmann
Definition: json.hpp:19274
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22346
const_iterator end() const noexcept
returns an iterator to one past the last element
Definition: json.hpp:21970
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22283
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:23720
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:21961
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21888
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.hpp:20148
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:19424
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:20170
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:22033
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23793
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:21912
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21788
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22291
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:20178
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23382
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:20198
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:20459
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:19970
ReturnType value(const typename object_t::key_type &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.hpp:21417
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21665
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22051
const_reference operator[](T *key) const
Definition: json.hpp:21329
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:19416
const_reference back() const
access the last element
Definition: json.hpp:21583
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24269
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.hpp:22482
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:19539
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20721
void swap(object_t &other)
exchanges the values
Definition: json.hpp:22677
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:19348
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20710
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:22709
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:20963
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.hpp:21285
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:19400
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:19403
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:19409
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22058
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23455
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22585
JSON_PRIVATE_UNLESS_TESTED const_reference bool static SAX bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
Definition: json.hpp:23253
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:23765
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:19390
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.hpp:21781
basic_json(const JsonRef &ref)
Definition: json.hpp:20308
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:21952
json_value m_value
the value of the current element
Definition: json.hpp:23365
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20950
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.hpp:21896
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.hpp:22533
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20536
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:22404
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21392
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.hpp:21864
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21010
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.hpp:22455
const binary_t & get_binary() const
get a binary value
Definition: json.hpp:21081
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:22021
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:19395
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23398
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23405
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:22323
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:21905
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22632
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21443
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition: json.hpp:24117
reference operator[](KeyType &&key)
access specified object element
Definition: json.hpp:21338
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition: json.hpp:23705
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.hpp:22475
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:19342
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:21104
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21272
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:23498
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:22725
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23620
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22436
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:20159
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:22153
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20480
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23428
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:23329
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22114
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:19515
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.hpp:19547
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.hpp:22553
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21595
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:22379
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20999
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:19340
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:19519
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23421
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23581
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20466
StringType string_t
a type for a string
Definition: json.hpp:19523
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20487
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23447
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.hpp:21848
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23507
const_reference front() const
access the first element
Definition: json.hpp:21567
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.hpp:23482
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:19392
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20529
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:19531
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:20397
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:20126
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:21770
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.hpp:21832
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21493
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.hpp:21818
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:19405
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23391
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:23830
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:23821
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23523
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:20017
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:23690
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:23566
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:21127
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:20137
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition: json.hpp:20003
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23466
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23779
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.hpp:23474
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20976
const_reverse_iterator rbegin() const noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:21993
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22578
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20543
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:20380
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21226
binary_t & get_binary()
get a binary value
Definition: json.hpp:21069
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20508
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20515
void swap(string_t &other)
exchanges the values
Definition: json.hpp:22693
value_type & reference
the type of an element reference
Definition: json.hpp:19385
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:19543
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:22000
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:20909
const_iterator cend() const noexcept
returns an iterator to one past the last element
Definition: json.hpp:21977
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20494
reference operator[](T *key)
Definition: json.hpp:21323
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20550
JSON_PRIVATE_UNLESS_TESTED const_reference bool inverse
Definition: json.hpp:22827
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:19398
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:21878
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:20437
void clear() noexcept
clears the contents
Definition: json.hpp:22197
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:20312
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:19407
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:20987
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:19991
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21470
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:23807
JSON_PRIVATE_UNLESS_TESTED const_reference rhs
Definition: json.hpp:22827
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:21986
friend class ::nlohmann::detail::parser
Definition: json.hpp:19284
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:19387
~basic_json() noexcept
destructor
Definition: json.hpp:20418
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20501
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:23635
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:20185
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition: json.hpp:23491
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23439
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23414
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:22354
reference back()
access the last element
Definition: json.hpp:21574
void patch_inplace(const basic_json &json_patch)
applies a JSON patch in-place without copying the object
Definition: json.hpp:23846
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20473
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:22370
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:22258
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:23314
detail::value_t value_t
Definition: json.hpp:19338
reference front()
access the first element
Definition: json.hpp:21560
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:19535
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:22075
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:20070
const_iterator begin() const noexcept
returns an iterator to the first element
Definition: json.hpp:21945
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:22014
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:21150
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22649
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:19983
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.hpp:21208
const_reverse_iterator rend() const noexcept
returns an iterator to the reverse-end
Definition: json.hpp:22007
void swap(array_t &other)
exchanges the values
Definition: json.hpp:22661
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition: json.hpp:19506
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.hpp:22502
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:19527
ReturnType value(const json_pointer &ptr, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21518
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.hpp:21307
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20522
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:21936
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.hpp:23307
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.hpp:21362
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:22315
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:21188
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.hpp:21170
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:24127
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.hpp:23675
an internal type for a backed binary type
Definition: json.hpp:5820
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5860
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5826
std::uint64_t subtype_type
Definition: json.hpp:5823
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5854
BinaryType container_type
Definition: json.hpp:5822
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5848
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5836
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5875
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5841
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5882
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5831
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5867
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5889
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:9142
binary_reader(const binary_reader &)=delete
binary_reader(binary_reader &&)=default
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.hpp:9158
binary_reader & operator=(const binary_reader &)=delete
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:9179
binary_reader & operator=(binary_reader &&)=default
serialization to CBOR and MessagePack values
Definition: json.hpp:14955
void write_bson(const BasicJsonType &j)
Definition: json.hpp:14975
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16710
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:16717
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:14966
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:16739
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false)
Definition: json.hpp:15654
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:15328
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:15004
general exception of the basic_json class
Definition: json.hpp:4301
const int id
the id of the exception
Definition: json.hpp:4310
static std::string diagnostics(std::nullptr_t)
Definition: json.hpp:4321
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:4316
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:4304
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.hpp:4327
Definition: json.hpp:6115
char char_type
Definition: json.hpp:6117
file_input_adapter(const file_input_adapter &)=delete
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6133
file_input_adapter(file_input_adapter &&) noexcept=default
Definition: json.hpp:6154
input_stream_adapter & operator=(input_stream_adapter &&)=delete
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:6177
~input_stream_adapter()
Definition: json.hpp:6158
std::char_traits< char >::int_type get_character()
Definition: json.hpp:6187
char char_type
Definition: json.hpp:6156
input_stream_adapter(const input_stream_adapter &)=delete
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(std::istream &i)
Definition: json.hpp:6168
exception indicating errors with iterators
Definition: json.hpp:4452
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4455
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:12834
~iter_impl()=default
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:13408
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:12971
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:13353
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:12961
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:13300
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:13335
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:13399
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:13214
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:13508
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:13255
iter_impl operator++(int) &
post-increment (it++)
Definition: json.hpp:13152
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13362
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13470
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:12864
pointer operator->() const
dereference the iterator
Definition: json.hpp:13110
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:13533
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:13441
iter_impl(iter_impl &&) noexcept=default
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:12859
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:13419
reference value() const
return the value of an iterator
Definition: json.hpp:13524
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:13344
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:12868
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:13163
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:12862
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:13066
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13430
iter_impl()=default
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:12946
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:13291
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.hpp:13203
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:12873
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:12936
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:13027
Definition: json.hpp:5115
iteration_proxy_value operator++(int) &
Definition: json.hpp:5171
iteration_proxy_value(iteration_proxy_value const &)=default
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:5180
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:5186
std::ptrdiff_t difference_type
Definition: json.hpp:5117
iteration_proxy_value(IteratorType it, std::size_t array_index_=0) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_default_constructible< string_type >::value)
Definition: json.hpp:5138
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:5163
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:5228
const string_type & key() const
return key of the iterator
Definition: json.hpp:5192
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
std::input_iterator_tag iterator_category
Definition: json.hpp:5121
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:5122
proxy class for the items() function
Definition: json.hpp:5236
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:5261
iteration_proxy(iteration_proxy const &)=default
iteration_proxy(iteration_proxy &&) noexcept=default
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:5255
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:5245
iteration_proxy & operator=(iteration_proxy const &)=default
Definition: json.hpp:6209
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:6217
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6213
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:6211
Definition: json.hpp:14696
json_ref(json_ref &&) noexcept=default
json_ref(const value_type &value)
Definition: json.hpp:14704
json_ref(value_type &&value)
Definition: json.hpp:14700
value_type const & operator*() const
Definition: json.hpp:14735
value_type const * operator->() const
Definition: json.hpp:14740
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:14708
json_ref(Args &&... args)
Definition: json.hpp:14715
value_type moved_or_copied() const
Definition: json.hpp:14726
BasicJsonType value_type
Definition: json.hpp:14698
a template for a reverse iterator class
Definition: json.hpp:13587
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.hpp:13603
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.hpp:13615
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:13609
std::ptrdiff_t difference_type
Definition: json.hpp:13589
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:13627
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:13651
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:13657
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:13645
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:13593
reference value() const
return the value of an iterator
Definition: json.hpp:13664
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:13600
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:13621
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:13591
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:13639
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:13596
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:13633
Definition: json.hpp:7221
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:7224
bool end_object()
Definition: json.hpp:7274
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7264
bool binary(binary_t &)
Definition: json.hpp:7259
bool number_integer(number_integer_t)
Definition: json.hpp:7239
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.hpp:7279
bool boolean(bool)
Definition: json.hpp:7234
bool null()
Definition: json.hpp:7229
bool end_array()
Definition: json.hpp:7284
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:7244
bool string(string_t &)
Definition: json.hpp:7254
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:7227
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:7249
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:7289
bool key(string_t &)
Definition: json.hpp:7269
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:7223
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:7225
typename BasicJsonType::string_t string_t
Definition: json.hpp:7226
Definition: json.hpp:6914
bool boolean(bool val)
Definition: json.hpp:6945
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:7102
typename BasicJsonType::string_t string_t
Definition: json.hpp:6919
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6963
constexpr bool is_errored() const
Definition: json.hpp:7114
bool string(string_t &val)
Definition: json.hpp:6969
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6917
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6920
bool start_object(std::size_t len)
Definition: json.hpp:6981
bool start_array(std::size_t len)
Definition: json.hpp:7052
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6916
bool end_array()
Definition: json.hpp:7069
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool key(string_t &val)
Definition: json.hpp:6999
bool end_object()
Definition: json.hpp:7016
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6922
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6921
bool null()
Definition: json.hpp:6939
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6957
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6924
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6918
bool number_integer(number_integer_t val)
Definition: json.hpp:6951
bool binary(binary_t &val)
Definition: json.hpp:6975
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6731
json_sax_dom_parser(const json_sax_dom_parser &)=delete
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool string(string_t &val)
Definition: json.hpp:6785
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6744
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6852
bool null()
Definition: json.hpp:6755
typename BasicJsonType::string_t string_t
Definition: json.hpp:6736
bool start_object(std::size_t len)
Definition: json.hpp:6797
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6734
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6773
bool number_integer(number_integer_t val)
Definition: json.hpp:6767
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6733
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool binary(binary_t &val)
Definition: json.hpp:6791
json_sax_dom_parser(json_sax_dom_parser &&)=default
bool boolean(bool val)
Definition: json.hpp:6761
bool end_array()
Definition: json.hpp:6841
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6779
bool end_object()
Definition: json.hpp:6819
constexpr bool is_errored() const
Definition: json.hpp:6864
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6737
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6735
bool start_array(std::size_t len)
Definition: json.hpp:6829
bool key(string_t &val)
Definition: json.hpp:6809
Definition: json.hpp:7336
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:7363
token_type
token types for the parser
Definition: json.hpp:7340
lexical analysis
Definition: json.hpp:7413
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8787
void skip_whitespace()
Definition: json.hpp:8801
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:7424
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8774
std::string get_token_string() const
Definition: json.hpp:8749
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8713
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8741
token_type scan()
Definition: json.hpp:8810
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8719
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:7422
lexer(lexer &&)=default
~lexer()=default
lexer & operator=(lexer &&)=default
lexer(const lexer &)=delete
lexer & operator=(lexer &)=delete
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8731
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8725
exception indicating other library errors
Definition: json.hpp:4504
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4507
exception indicating access out of the defined range
Definition: json.hpp:4487
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4490
Definition: json.hpp:14913
output_adapter(StringType &s)
Definition: json.hpp:14924
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:14920
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:14916
output adapter for output streams
Definition: json.hpp:14865
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:14867
void write_character(CharType c) override
Definition: json.hpp:14871
output adapter for basic_string
Definition: json.hpp:14890
void write_character(CharType c) override
Definition: json.hpp:14896
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:14892
output adapter for byte vectors
Definition: json.hpp:14840
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:14842
void write_character(CharType c) override
Definition: json.hpp:14846
exception indicating a parse error
Definition: json.hpp:4399
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition: json.hpp:4411
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4419
const std::size_t byte
byte index of the parse error
Definition: json.hpp:4436
syntax analysis
Definition: json.hpp:12159
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:12169
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:12191
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:12251
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:12259
Definition: json.hpp:12651
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:12713
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:12745
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:12680
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:12726
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:12674
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12696
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:12686
primitive_iterator_t operator++(int) &noexcept
Definition: json.hpp:12719
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:12739
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12691
constexpr difference_type get_value() const noexcept
Definition: json.hpp:12662
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:12708
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:12701
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:12668
primitive_iterator_t operator--(int) &noexcept
Definition: json.hpp:12732
Definition: json.hpp:17936
std::array< char, 512 > string_buffer
string buffer
Definition: json.hpp:18860
std::uint8_t state
Definition: json.hpp:18278
std::size_t bytes_after_last_accept
Definition: json.hpp:18282
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:17951
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.hpp:18276
std::size_t undumped_chars
Definition: json.hpp:18283
const char thousands_sep
the locale's thousand separator character
Definition: json.hpp:18855
const char decimal_point
the locale's decimal point character
Definition: json.hpp:18857
serializer & operator=(const serializer &)=delete
~serializer()=default
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:18868
string_t indent_string
the indentation string
Definition: json.hpp:18865
const std::lconv * loc
the locale
Definition: json.hpp:18853
serializer & operator=(serializer &&)=delete
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:18850
const char indent_char
the indentation character
Definition: json.hpp:18863
std::size_t bytes
Definition: json.hpp:18279
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:17991
serializer(const serializer &)=delete
serializer(serializer &&)=delete
Definition: json.hpp:6535
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:6543
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6550
contiguous_bytes_input_adapter && get()
Definition: json.hpp:6553
exception indicating executing a member function with a wrong type
Definition: json.hpp:4470
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.hpp:4473
Definition: json.hpp:6369
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:6376
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:6373
char char_type
Definition: json.hpp:6371
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.hpp:13717
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:13812
typename string_t_helper< RefStringType >::type string_t
Definition: json.hpp:13739
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:13819
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.hpp:13743
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:13878
friend bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:14612
void pop_back()
remove last reference token
Definition: json.hpp:13840
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:13749
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:13797
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13871
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:13779
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:13804
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:13826
friend bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:14637
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:13789
friend class json_pointer
Definition: json.hpp:13723
const string_t & back() const
return last reference token
Definition: json.hpp:13852
friend std::ostream & operator<<(std::ostream &o, const json_pointer &ptr)
write string representation of the JSON pointer to stream
Definition: json.hpp:13770
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:13864
friend bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
compares two JSON pointer for less-than
Definition: json.hpp:14662
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:5309
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2586
#define JSON_HEDLEY_CONST
Definition: json.hpp:1816
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:1100
#define JSON_INLINE_VARIABLE
Definition: json.hpp:2489
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1446
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2549
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:71
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1711
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1604
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2516
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:24301
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:2045
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14612
#define JSON_CATCH(exception)
Definition: json.hpp:2515
#define JSON_ASSERT(x)
Definition: json.hpp:2542
#define JSON_THROW(exception)
Definition: json.hpp:2513
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.hpp:78
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:69
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2595
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1712
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition: json.hpp:12049
#define JSON_TRY
Definition: json.hpp:2514
#define NLOHMANN_JSON_NAMESPACE_END
Definition: json.hpp:145
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.hpp:2495
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14637
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:70
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2770
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition: json.hpp:135
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition: json.hpp:12046
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:1101
#define JSON_EXPLICIT
Definition: json.hpp:2807
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1394
#define JSON_HEDLEY_PURE
Definition: json.hpp:1785
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:14662
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.hpp:22750
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:17275
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:17111
Target reinterpret_bits(const Source source)
Definition: json.hpp:16831
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:16972
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:17329
constexpr int kAlpha
Definition: json.hpp:17094
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:17611
constexpr int kGamma
Definition: json.hpp:17095
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:17370
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:17711
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:17763
constexpr bool is_transparent()
Definition: json.hpp:4122
constexpr bool is_c_string()
Definition: json.hpp:4094
detail namespace with internal helper functions
Definition: json.hpp:247
input_format_t
the supported input formats
Definition: json.hpp:6103
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:5709
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:307
typename make_void< Ts... >::type void_t
Definition: json.hpp:253
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:9003
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:14835
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.hpp:4203
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:9011
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:12150
OutStringType concat(Args &&... args)
Definition: json.hpp:4277
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.hpp:4212
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3499
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition: json.hpp:3206
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3505
typename std::conditional< is_usable_as_key_type< typename BasicJsonType::object_comparator_t, typename BasicJsonType::object_t::key_type, KeyTypeCVRef, RequireTransparentComparator, ExcludeObjectKeyType >::value &&!is_json_iterator_of< BasicJsonType, KeyType >::value, std::true_type, std::false_type >::type is_usable_as_basic_json_key_type
Definition: json.hpp:3943
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:17848
typename T::pointer pointer_t
Definition: json.hpp:3490
parse_event_t
Definition: json.hpp:12133
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.hpp:4206
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition: json.hpp:4939
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4750
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3167
typename T::value_type value_type_t
Definition: json.hpp:3484
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:311
T conditional_static_cast(U value)
Definition: json.hpp:3977
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.hpp:4218
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3079
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8972
typename T::mapped_type mapped_type_t
Definition: json.hpp:3478
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2955
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:8980
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3671
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5271
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:9114
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:304
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3502
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:6508
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3175
std::integral_constant< bool, Value > bool_constant
Definition: json.hpp:4084
void concat_into(OutStringType &)
Definition: json.hpp:4193
typename T::key_type key_type_t
Definition: json.hpp:3481
constexpr bool value_in_range_of(T val)
Definition: json.hpp:4078
value_t
the JSON type enumeration
Definition: json.hpp:2857
@ null
null value
@ number_integer
number value (signed integer)
@ boolean
boolean value
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ string
string value
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition: json.hpp:4000
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8988
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)> >, index_sequence< Idx... >)
Definition: json.hpp:4833
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:298
typename std::conditional< is_comparable< Comparator, ObjectKeyType, KeyTypeCVRef >::value &&!(ExcludeObjectKeyType &&std::is_same< KeyType, ObjectKeyType >::value) &&(!RequireTransparentComparator||is_detected< detect_is_transparent, Comparator >::value) &&!is_json_pointer< KeyType >::value, std::true_type, std::false_type >::type is_usable_as_key_type
Definition: json.hpp:3927
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5951
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.hpp:4209
typename T::iterator_category iterator_category_t
Definition: json.hpp:3496
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5933
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:2886
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:6451
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:9006
typename std::conditional< is_detected< detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType >::value, std::true_type, std::false_type >::type has_erase_with_key_type
Definition: json.hpp:3955
error_handler_t
how to treat decoding errors
Definition: json.hpp:17928
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
std::size_t concat_length()
Definition: json.hpp:4162
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition: json.hpp:3674
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4593
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.hpp:3578
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.hpp:4197
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5571
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:4607
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8964
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3183
typename T::difference_type difference_type_t
Definition: json.hpp:3487
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3065
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4933
typename T::is_transparent detect_is_transparent
Definition: json.hpp:3913
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8984
typename T::reference reference_t
Definition: json.hpp:3493
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8968
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:8999
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.hpp:3946
typename T::key_compare detect_key_compare
Definition: json.hpp:3562
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8992
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.hpp:4215
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8976
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:292
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2974
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:5108
std::integral_constant< bool,(std::is_signed< OfType >::value &&(sizeof(T)< sizeof(OfType)))||(same_sign< OfType, T >::value &&sizeof(OfType)==sizeof(T)) > never_out_of_range
Definition: json.hpp:4005
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.hpp:4200
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:8996
Definition: json.hpp:24307
Definition: json.hpp:5292
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24374
namespace for Niels Lohmann
Definition: json.hpp:5762
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:5786
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:5776
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:5766
Definition: json.hpp:3570
typename BasicJsonType::object_t object_t
Definition: json.hpp:3571
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.hpp:3572
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.hpp:3574
Definition: json.hpp:3585
decltype(input_adapter(begin(std::declval< ContainerType >()), end(std::declval< ContainerType >()))) adapter_type
Definition: json.hpp:6474
Definition: json.hpp:279
std::false_type value_t
Definition: json.hpp:280
Default type
Definition: json.hpp:281
Definition: json.hpp:16959
diyfp w
Definition: json.hpp:16960
diyfp minus
Definition: json.hpp:16961
diyfp plus
Definition: json.hpp:16962
Definition: json.hpp:17098
std::uint64_t f
Definition: json.hpp:17099
int e
Definition: json.hpp:17100
int k
Definition: json.hpp:17101
Definition: json.hpp:16841
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:16865
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:16947
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:16930
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:16853
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:16847
static constexpr int kPrecision
Definition: json.hpp:16842
std::uint64_t f
Definition: json.hpp:16844
int e
Definition: json.hpp:16845
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:5496
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:5471
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:5461
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:5483
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:5512
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:5400
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:5409
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:5354
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:5422
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:5448
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:5435
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:5531
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:5552
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:5541
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:5376
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:5387
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:5367
Definition: json.hpp:5348
Definition: json.hpp:5028
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:5030
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3524
Definition: json.hpp:3509
Definition: json.hpp:3565
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3539
Definition: json.hpp:3534
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3554
Definition: json.hpp:3549
Definition: json.hpp:4544
Definition: json.hpp:3107
T value_type
Definition: json.hpp:3108
static constexpr std::size_t size() noexcept
Definition: json.hpp:3109
an iterator value
Definition: json.hpp:12767
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:12771
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:12773
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:12769
Definition: json.hpp:3458
Definition: json.hpp:3445
Definition: json.hpp:4109
Definition: json.hpp:3904
Definition: json.hpp:3768
Definition: json.hpp:3787
Definition: json.hpp:3858
Definition: json.hpp:3708
Definition: json.hpp:3745
static constexpr auto value
Definition: json.hpp:3746
Definition: json.hpp:3861
Definition: json.hpp:3874
Definition: json.hpp:3681
Definition: json.hpp:3831
Definition: json.hpp:3741
Definition: json.hpp:3752
ConstructibleStringType laundered_type
Definition: json.hpp:3757
static constexpr auto value
Definition: json.hpp:3760
Definition: json.hpp:3877
Definition: json.hpp:3618
Definition: json.hpp:3598
Definition: json.hpp:295
Definition: json.hpp:3517
static constexpr bool value
Definition: json.hpp:3518
Definition: json.hpp:6427
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:6428
Definition: json.hpp:3634
Definition: json.hpp:3883
Definition: json.hpp:3468
Definition: json.hpp:3965
char x[2]
Definition: json.hpp:3966
Definition: json.hpp:3961
static one test(decltype(&C::capacity))
char one
Definition: json.hpp:3962
static two test(...)
@ value
Definition: json.hpp:3972
Definition: json.hpp:3653
static constexpr bool value
Definition: json.hpp:3667
Definition: json.hpp:9046
Definition: json.hpp:9015
static constexpr bool value
Definition: json.hpp:9028
Definition: json.hpp:3894
Definition: json.hpp:4131
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6439
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6443
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:6417
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:6416
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:6419
IteratorType iterator_type
Definition: json.hpp:6415
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3286
Definition: json.hpp:3274
Definition: json.hpp:3255
Definition: json.hpp:250
void type
Definition: json.hpp:251
Definition: json.hpp:3592
Definition: json.hpp:265
nonesuch(nonesuch const &&)=delete
~nonesuch()=delete
void operator=(nonesuch &&)=delete
void operator=(nonesuch const &)=delete
nonesuch(nonesuch const &)=delete
abstract output adapter interface
Definition: json.hpp:14821
output_adapter_protocol(const output_adapter_protocol &)=default
virtual ~output_adapter_protocol()=default
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
virtual void write_characters(const CharType *s, std::size_t length)=0
struct to capture the start position of the current token
Definition: json.hpp:3020
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:3024
std::size_t lines_read
the number of lines read
Definition: json.hpp:3026
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:3022
Definition: json.hpp:3190
Definition: json.hpp:3196
static JSON_INLINE_VARIABLE constexpr T value
Definition: json.hpp:3197
Definition: json.hpp:5729
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:5731
Definition: json.hpp:3127
Definition: json.hpp:3146
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3148
static constexpr bool test(T val)
Definition: json.hpp:4062
static constexpr bool test(T)
Definition: json.hpp:4071
Definition: json.hpp:4057
static constexpr bool test(T val)
Definition: json.hpp:4015
static constexpr bool test(T val)
Definition: json.hpp:4035
static constexpr bool test(T val)
Definition: json.hpp:4025
static constexpr bool test(T val)
Definition: json.hpp:4046
Definition: json.hpp:4010
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:6308
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:6250
Definition: json.hpp:6244
SAX interface.
Definition: json.hpp:6600
virtual bool binary(binary_t &val)=0
a binary value was read
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
virtual bool key(string_t &val)=0
an object key was read
json_sax()=default
virtual bool string(string_t &val)=0
a string value was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6601
typename BasicJsonType::string_t string_t
Definition: json.hpp:6604
virtual bool end_array()=0
the end of an array was read
json_sax(const json_sax &)=default
virtual bool boolean(bool val)=0
a boolean value was read
virtual bool end_object()=0
the end of an object was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6603
virtual bool null()=0
a null value was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6602
json_sax(json_sax &&) noexcept=default
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6605
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
a minimal map-like container that preserves insertion order
Definition: json.hpp:18910
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:18913
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:19204
typename Container::value_type value_type
Definition: json.hpp:18917
std::equal_to< Key > key_compare
Definition: json.hpp:18921
iterator erase(iterator pos)
Definition: json.hpp:19082
T mapped_type
Definition: json.hpp:18912
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.hpp:18927
T & operator[](KeyType &&key)
Definition: json.hpp:18969
typename Container::iterator iterator
Definition: json.hpp:18914
const T & at(KeyType &&key) const
Definition: json.hpp:19029
T & at(KeyType &&key)
Definition: json.hpp:19001
const T & operator[](KeyType &&key) const
Definition: json.hpp:18981
iterator find(const key_type &key)
Definition: json.hpp:19166
iterator erase(iterator first, iterator last)
Definition: json.hpp:19087
const T & at(const key_type &key) const
Definition: json.hpp:19014
const_iterator find(const key_type &key) const
Definition: json.hpp:19192
T & operator[](const key_type &key)
Definition: json.hpp:18962
size_type erase(KeyType &&key)
Definition: json.hpp:19063
typename Container::size_type size_type
Definition: json.hpp:18916
ordered_map() noexcept(noexcept(Container()))
Definition: json.hpp:18926
void insert(InputIt first, InputIt last)
Definition: json.hpp:19227
size_type count(const key_type &key) const
Definition: json.hpp:19140
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.hpp:18949
size_type erase(const key_type &key)
Definition: json.hpp:19042
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.hpp:18931
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:19209
size_type count(KeyType &&key) const
Definition: json.hpp:19154
Key key_type
Definition: json.hpp:18911
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:18929
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:19224
const T & operator[](const key_type &key) const
Definition: json.hpp:18974
iterator find(KeyType &&key)
Definition: json.hpp:19180
T & at(const key_type &key)
Definition: json.hpp:18986
typename Container::const_iterator const_iterator
Definition: json.hpp:18915
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:18934
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.hpp:24343
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:24357