PeriDyno 1.2.1
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1// __ _____ _____ _____
2// __| | __| | | | JSON for Modern C++
3// | | |__ | | | | | | version 3.11.3
4// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2023 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 <string> // string, stoi, to_string
31#include <utility> // declval, forward, move, pair, swap
32#include <vector> // vector
33
34// #include <nlohmann/adl_serializer.hpp>
35// __ _____ _____ _____
36// __| | __| | | | JSON for Modern C++
37// | | |__ | | | | | | version 3.11.3
38// |_____|_____|_____|_|___| https://github.com/nlohmann/json
39//
40// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
41// SPDX-License-Identifier: MIT
42
43
44
45#include <utility>
46
47// #include <nlohmann/detail/abi_macros.hpp>
48// __ _____ _____ _____
49// __| | __| | | | JSON for Modern C++
50// | | |__ | | | | | | version 3.11.3
51// |_____|_____|_____|_|___| https://github.com/nlohmann/json
52//
53// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
54// SPDX-License-Identifier: MIT
55
56
57
58// This file contains all macro definitions affecting or depending on the ABI
59
60#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
61#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
62#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 3
63#warning "Already included a different version of the library!"
64#endif
65#endif
66#endif
67
68#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
69#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum)
70#define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum)
71
72#ifndef JSON_DIAGNOSTICS
73#define JSON_DIAGNOSTICS 0
74#endif
75
76#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
77#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
78#endif
79
80#if JSON_DIAGNOSTICS
81#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag
82#else
83#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS
84#endif
85
86#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
87#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp
88#else
89#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON
90#endif
91
92#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION
93#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0
94#endif
95
96// Construct the namespace ABI tags component
97#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b
98#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \
99 NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b)
100
101#define NLOHMANN_JSON_ABI_TAGS \
102 NLOHMANN_JSON_ABI_TAGS_CONCAT( \
103 NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \
104 NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON)
105
106// Construct the namespace version component
107#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \
108 _v ## major ## _ ## minor ## _ ## patch
109#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \
110 NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch)
111
112#if NLOHMANN_JSON_NAMESPACE_NO_VERSION
113#define NLOHMANN_JSON_NAMESPACE_VERSION
114#else
115#define NLOHMANN_JSON_NAMESPACE_VERSION \
116 NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \
117 NLOHMANN_JSON_VERSION_MINOR, \
118 NLOHMANN_JSON_VERSION_PATCH)
119#endif
120
121// Combine namespace components
122#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b
123#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \
124 NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b)
125
126#ifndef NLOHMANN_JSON_NAMESPACE
127#define NLOHMANN_JSON_NAMESPACE \
128 nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \
129 NLOHMANN_JSON_ABI_TAGS, \
130 NLOHMANN_JSON_NAMESPACE_VERSION)
131#endif
132
133#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN
134#define NLOHMANN_JSON_NAMESPACE_BEGIN \
135 namespace nlohmann \
136 { \
137 inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \
138 NLOHMANN_JSON_ABI_TAGS, \
139 NLOHMANN_JSON_NAMESPACE_VERSION) \
140 {
141#endif
142
143#ifndef NLOHMANN_JSON_NAMESPACE_END
144#define NLOHMANN_JSON_NAMESPACE_END \
145 } /* namespace (inline namespace) NOLINT(readability/namespace) */ \
146 } // namespace nlohmann
147#endif
148
149// #include <nlohmann/detail/conversions/from_json.hpp>
150// __ _____ _____ _____
151// __| | __| | | | JSON for Modern C++
152// | | |__ | | | | | | version 3.11.3
153// |_____|_____|_____|_|___| https://github.com/nlohmann/json
154//
155// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
156// SPDX-License-Identifier: MIT
157
158
159
160#include <algorithm> // transform
161#include <array> // array
162#include <forward_list> // forward_list
163#include <iterator> // inserter, front_inserter, end
164#include <map> // map
165#include <string> // string
166#include <tuple> // tuple, make_tuple
167#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
168#include <unordered_map> // unordered_map
169#include <utility> // pair, declval
170#include <valarray> // valarray
171
172// #include <nlohmann/detail/exceptions.hpp>
173// __ _____ _____ _____
174// __| | __| | | | JSON for Modern C++
175// | | |__ | | | | | | version 3.11.3
176// |_____|_____|_____|_|___| https://github.com/nlohmann/json
177//
178// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
179// SPDX-License-Identifier: MIT
180
181
182
183#include <cstddef> // nullptr_t
184#include <exception> // exception
185#if JSON_DIAGNOSTICS
186#include <numeric> // accumulate
187#endif
188#include <stdexcept> // runtime_error
189#include <string> // to_string
190#include <vector> // vector
191
192// #include <nlohmann/detail/value_t.hpp>
193// __ _____ _____ _____
194// __| | __| | | | JSON for Modern C++
195// | | |__ | | | | | | version 3.11.3
196// |_____|_____|_____|_|___| https://github.com/nlohmann/json
197//
198// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
199// SPDX-License-Identifier: MIT
200
201
202
203#include <array> // array
204#include <cstddef> // size_t
205#include <cstdint> // uint8_t
206#include <string> // string
207
208// #include <nlohmann/detail/macro_scope.hpp>
209// __ _____ _____ _____
210// __| | __| | | | JSON for Modern C++
211// | | |__ | | | | | | version 3.11.3
212// |_____|_____|_____|_|___| https://github.com/nlohmann/json
213//
214// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
215// SPDX-License-Identifier: MIT
216
217
218
219#include <utility> // declval, pair
220// #include <nlohmann/detail/meta/detected.hpp>
221// __ _____ _____ _____
222// __| | __| | | | JSON for Modern C++
223// | | |__ | | | | | | version 3.11.3
224// |_____|_____|_____|_|___| https://github.com/nlohmann/json
225//
226// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
227// SPDX-License-Identifier: MIT
228
229
230
231#include <type_traits>
232
233// #include <nlohmann/detail/meta/void_t.hpp>
234// __ _____ _____ _____
235// __| | __| | | | JSON for Modern C++
236// | | |__ | | | | | | version 3.11.3
237// |_____|_____|_____|_|___| https://github.com/nlohmann/json
238//
239// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
240// SPDX-License-Identifier: MIT
241
242
243
244// #include <nlohmann/detail/abi_macros.hpp>
245
246
248namespace detail
249{
250
251 template<typename ...Ts> struct make_void
252 {
253 using type = void;
254 };
255 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
256
257} // namespace detail
259
260
262namespace detail
263{
264
265 // https://en.cppreference.com/w/cpp/experimental/is_detected
266 struct nonesuch
267 {
268 nonesuch() = delete;
269 ~nonesuch() = delete;
270 nonesuch(nonesuch const&) = delete;
271 nonesuch(nonesuch const&&) = delete;
272 void operator=(nonesuch const&) = delete;
273 void operator=(nonesuch&&) = delete;
274 };
275
276 template<class Default,
277 class AlwaysVoid,
278 template<class...> class Op,
279 class... Args>
280 struct detector
281 {
282 using value_t = std::false_type;
283 using type = Default;
284 };
285
286 template<class Default, template<class...> class Op, class... Args>
287 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
288 {
289 using value_t = std::true_type;
290 using type = Op<Args...>;
291 };
292
293 template<template<class...> class Op, class... Args>
294 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
295
296 template<template<class...> class Op, class... Args>
297 struct is_detected_lazy : is_detected<Op, Args...> { };
298
299 template<template<class...> class Op, class... Args>
300 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
301
302 template<class Default, template<class...> class Op, class... Args>
303 using detected_or = detector<Default, void, Op, Args...>;
304
305 template<class Default, template<class...> class Op, class... Args>
306 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
307
308 template<class Expected, template<class...> class Op, class... Args>
309 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
310
311 template<class To, template<class...> class Op, class... Args>
313 std::is_convertible<detected_t<Op, Args...>, To>;
314
315} // namespace detail
317
318// #include <nlohmann/thirdparty/hedley/hedley.hpp>
319
320
321// __ _____ _____ _____
322// __| | __| | | | JSON for Modern C++
323// | | |__ | | | | | | version 3.11.3
324// |_____|_____|_____|_|___| https://github.com/nlohmann/json
325//
326// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
327// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson <evan@nemerson.com>
328// SPDX-License-Identifier: MIT
329
330/* Hedley - https://nemequ.github.io/hedley
331 * Created by Evan Nemerson <evan@nemerson.com>
332 */
333
334#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
335#if defined(JSON_HEDLEY_VERSION)
336#undef JSON_HEDLEY_VERSION
337#endif
338#define JSON_HEDLEY_VERSION 15
339
340#if defined(JSON_HEDLEY_STRINGIFY_EX)
341#undef JSON_HEDLEY_STRINGIFY_EX
342#endif
343#define JSON_HEDLEY_STRINGIFY_EX(x) #x
344
345#if defined(JSON_HEDLEY_STRINGIFY)
346#undef JSON_HEDLEY_STRINGIFY
347#endif
348#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
349
350#if defined(JSON_HEDLEY_CONCAT_EX)
351#undef JSON_HEDLEY_CONCAT_EX
352#endif
353#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
354
355#if defined(JSON_HEDLEY_CONCAT)
356#undef JSON_HEDLEY_CONCAT
357#endif
358#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
359
360#if defined(JSON_HEDLEY_CONCAT3_EX)
361#undef JSON_HEDLEY_CONCAT3_EX
362#endif
363#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
364
365#if defined(JSON_HEDLEY_CONCAT3)
366#undef JSON_HEDLEY_CONCAT3
367#endif
368#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
369
370#if defined(JSON_HEDLEY_VERSION_ENCODE)
371#undef JSON_HEDLEY_VERSION_ENCODE
372#endif
373#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
374
375#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
376#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
377#endif
378#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
379
380#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
381#undef JSON_HEDLEY_VERSION_DECODE_MINOR
382#endif
383#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
384
385#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
386#undef JSON_HEDLEY_VERSION_DECODE_REVISION
387#endif
388#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
389
390#if defined(JSON_HEDLEY_GNUC_VERSION)
391#undef JSON_HEDLEY_GNUC_VERSION
392#endif
393#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
394#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
395#elif defined(__GNUC__)
396#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
397#endif
398
399#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
400#undef JSON_HEDLEY_GNUC_VERSION_CHECK
401#endif
402#if defined(JSON_HEDLEY_GNUC_VERSION)
403#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
404#else
405#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
406#endif
407
408#if defined(JSON_HEDLEY_MSVC_VERSION)
409#undef JSON_HEDLEY_MSVC_VERSION
410#endif
411#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
412#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
413#elif defined(_MSC_FULL_VER) && !defined(__ICL)
414#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
415#elif defined(_MSC_VER) && !defined(__ICL)
416#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
417#endif
418
419#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
420#undef JSON_HEDLEY_MSVC_VERSION_CHECK
421#endif
422#if !defined(JSON_HEDLEY_MSVC_VERSION)
423#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
424#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
425#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
426#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
427#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
428#else
429#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
430#endif
431
432#if defined(JSON_HEDLEY_INTEL_VERSION)
433#undef JSON_HEDLEY_INTEL_VERSION
434#endif
435#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
436#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
437#elif defined(__INTEL_COMPILER) && !defined(__ICL)
438#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
439#endif
440
441#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
442#undef JSON_HEDLEY_INTEL_VERSION_CHECK
443#endif
444#if defined(JSON_HEDLEY_INTEL_VERSION)
445#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446#else
447#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
448#endif
449
450#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
451#undef JSON_HEDLEY_INTEL_CL_VERSION
452#endif
453#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
454#define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
455#endif
456
457#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
458#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
459#endif
460#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
461#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462#else
463#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
464#endif
465
466#if defined(JSON_HEDLEY_PGI_VERSION)
467#undef JSON_HEDLEY_PGI_VERSION
468#endif
469#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
470#define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
471#endif
472
473#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
474#undef JSON_HEDLEY_PGI_VERSION_CHECK
475#endif
476#if defined(JSON_HEDLEY_PGI_VERSION)
477#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478#else
479#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
480#endif
481
482#if defined(JSON_HEDLEY_SUNPRO_VERSION)
483#undef JSON_HEDLEY_SUNPRO_VERSION
484#endif
485#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
486#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)
487#elif defined(__SUNPRO_C)
488#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
489#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
490#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)
491#elif defined(__SUNPRO_CC)
492#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
493#endif
494
495#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
496#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
497#endif
498#if defined(JSON_HEDLEY_SUNPRO_VERSION)
499#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
500#else
501#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
502#endif
503
504#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
505#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
506#endif
507#if defined(__EMSCRIPTEN__)
508#define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
509#endif
510
511#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
512#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
513#endif
514#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
515#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
516#else
517#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
518#endif
519
520#if defined(JSON_HEDLEY_ARM_VERSION)
521#undef JSON_HEDLEY_ARM_VERSION
522#endif
523#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
524#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
525#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
526#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
527#endif
528
529#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
530#undef JSON_HEDLEY_ARM_VERSION_CHECK
531#endif
532#if defined(JSON_HEDLEY_ARM_VERSION)
533#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534#else
535#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
536#endif
537
538#if defined(JSON_HEDLEY_IBM_VERSION)
539#undef JSON_HEDLEY_IBM_VERSION
540#endif
541#if defined(__ibmxl__)
542#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
543#elif defined(__xlC__) && defined(__xlC_ver__)
544#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
545#elif defined(__xlC__)
546#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
547#endif
548
549#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
550#undef JSON_HEDLEY_IBM_VERSION_CHECK
551#endif
552#if defined(JSON_HEDLEY_IBM_VERSION)
553#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
554#else
555#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
556#endif
557
558#if defined(JSON_HEDLEY_TI_VERSION)
559#undef JSON_HEDLEY_TI_VERSION
560#endif
561#if \
562 defined(__TI_COMPILER_VERSION__) && \
563 ( \
564 defined(__TMS470__) || defined(__TI_ARM__) || \
565 defined(__MSP430__) || \
566 defined(__TMS320C2000__) \
567 )
568#if (__TI_COMPILER_VERSION__ >= 16000000)
569#define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
570#endif
571#endif
572
573#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
574#undef JSON_HEDLEY_TI_VERSION_CHECK
575#endif
576#if defined(JSON_HEDLEY_TI_VERSION)
577#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
578#else
579#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
580#endif
581
582#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
583#undef JSON_HEDLEY_TI_CL2000_VERSION
584#endif
585#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
586#define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
587#endif
588
589#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
590#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
591#endif
592#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
593#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
594#else
595#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
596#endif
597
598#if defined(JSON_HEDLEY_TI_CL430_VERSION)
599#undef JSON_HEDLEY_TI_CL430_VERSION
600#endif
601#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
602#define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
603#endif
604
605#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
606#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
607#endif
608#if defined(JSON_HEDLEY_TI_CL430_VERSION)
609#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
610#else
611#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
612#endif
613
614#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
615#undef JSON_HEDLEY_TI_ARMCL_VERSION
616#endif
617#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
618#define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
619#endif
620
621#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
622#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
623#endif
624#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
625#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
626#else
627#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
628#endif
629
630#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
631#undef JSON_HEDLEY_TI_CL6X_VERSION
632#endif
633#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
634#define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
635#endif
636
637#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
638#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
639#endif
640#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
641#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
642#else
643#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
644#endif
645
646#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
647#undef JSON_HEDLEY_TI_CL7X_VERSION
648#endif
649#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
650#define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
651#endif
652
653#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
654#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
655#endif
656#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
657#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
658#else
659#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
660#endif
661
662#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
663#undef JSON_HEDLEY_TI_CLPRU_VERSION
664#endif
665#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
666#define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
667#endif
668
669#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
670#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
671#endif
672#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
673#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
674#else
675#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
676#endif
677
678#if defined(JSON_HEDLEY_CRAY_VERSION)
679#undef JSON_HEDLEY_CRAY_VERSION
680#endif
681#if defined(_CRAYC)
682#if defined(_RELEASE_PATCHLEVEL)
683#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
684#else
685#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
686#endif
687#endif
688
689#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
690#undef JSON_HEDLEY_CRAY_VERSION_CHECK
691#endif
692#if defined(JSON_HEDLEY_CRAY_VERSION)
693#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
694#else
695#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
696#endif
697
698#if defined(JSON_HEDLEY_IAR_VERSION)
699#undef JSON_HEDLEY_IAR_VERSION
700#endif
701#if defined(__IAR_SYSTEMS_ICC__)
702#if __VER__ > 1000
703#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
704#else
705#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
706#endif
707#endif
708
709#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
710#undef JSON_HEDLEY_IAR_VERSION_CHECK
711#endif
712#if defined(JSON_HEDLEY_IAR_VERSION)
713#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
714#else
715#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
716#endif
717
718#if defined(JSON_HEDLEY_TINYC_VERSION)
719#undef JSON_HEDLEY_TINYC_VERSION
720#endif
721#if defined(__TINYC__)
722#define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
723#endif
724
725#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
726#undef JSON_HEDLEY_TINYC_VERSION_CHECK
727#endif
728#if defined(JSON_HEDLEY_TINYC_VERSION)
729#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
730#else
731#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
732#endif
733
734#if defined(JSON_HEDLEY_DMC_VERSION)
735#undef JSON_HEDLEY_DMC_VERSION
736#endif
737#if defined(__DMC__)
738#define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
739#endif
740
741#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
742#undef JSON_HEDLEY_DMC_VERSION_CHECK
743#endif
744#if defined(JSON_HEDLEY_DMC_VERSION)
745#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
746#else
747#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
748#endif
749
750#if defined(JSON_HEDLEY_COMPCERT_VERSION)
751#undef JSON_HEDLEY_COMPCERT_VERSION
752#endif
753#if defined(__COMPCERT_VERSION__)
754#define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
755#endif
756
757#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
758#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
759#endif
760#if defined(JSON_HEDLEY_COMPCERT_VERSION)
761#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
762#else
763#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
764#endif
765
766#if defined(JSON_HEDLEY_PELLES_VERSION)
767#undef JSON_HEDLEY_PELLES_VERSION
768#endif
769#if defined(__POCC__)
770#define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
771#endif
772
773#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
774#undef JSON_HEDLEY_PELLES_VERSION_CHECK
775#endif
776#if defined(JSON_HEDLEY_PELLES_VERSION)
777#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
778#else
779#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
780#endif
781
782#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
783#undef JSON_HEDLEY_MCST_LCC_VERSION
784#endif
785#if defined(__LCC__) && defined(__LCC_MINOR__)
786#define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
787#endif
788
789#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
790#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
791#endif
792#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
793#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
794#else
795#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
796#endif
797
798#if defined(JSON_HEDLEY_GCC_VERSION)
799#undef JSON_HEDLEY_GCC_VERSION
800#endif
801#if \
802 defined(JSON_HEDLEY_GNUC_VERSION) && \
803 !defined(__clang__) && \
804 !defined(JSON_HEDLEY_INTEL_VERSION) && \
805 !defined(JSON_HEDLEY_PGI_VERSION) && \
806 !defined(JSON_HEDLEY_ARM_VERSION) && \
807 !defined(JSON_HEDLEY_CRAY_VERSION) && \
808 !defined(JSON_HEDLEY_TI_VERSION) && \
809 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
810 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
811 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
812 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
813 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
814 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
815 !defined(__COMPCERT__) && \
816 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
817#define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
818#endif
819
820#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
821#undef JSON_HEDLEY_GCC_VERSION_CHECK
822#endif
823#if defined(JSON_HEDLEY_GCC_VERSION)
824#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
825#else
826#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
827#endif
828
829#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
830#undef JSON_HEDLEY_HAS_ATTRIBUTE
831#endif
832#if \
833 defined(__has_attribute) && \
834 ( \
835 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
836 )
837# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
838#else
839# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
840#endif
841
842#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
843#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
844#endif
845#if defined(__has_attribute)
846#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
847#else
848#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
849#endif
850
851#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
852#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
853#endif
854#if defined(__has_attribute)
855#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
856#else
857#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
858#endif
859
860#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
861#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
862#endif
863#if \
864 defined(__has_cpp_attribute) && \
865 defined(__cplusplus) && \
866 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
867#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
868#else
869#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
870#endif
871
872#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
873#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
874#endif
875#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
876#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
877#elif \
878 !defined(JSON_HEDLEY_PGI_VERSION) && \
879 !defined(JSON_HEDLEY_IAR_VERSION) && \
880 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
881 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
882#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
883#else
884#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
885#endif
886
887#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
888#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
889#endif
890#if defined(__has_cpp_attribute) && defined(__cplusplus)
891#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
892#else
893#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
894#endif
895
896#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
897#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
898#endif
899#if defined(__has_cpp_attribute) && defined(__cplusplus)
900#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
901#else
902#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
903#endif
904
905#if defined(JSON_HEDLEY_HAS_BUILTIN)
906#undef JSON_HEDLEY_HAS_BUILTIN
907#endif
908#if defined(__has_builtin)
909#define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
910#else
911#define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
912#endif
913
914#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
915#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
916#endif
917#if defined(__has_builtin)
918#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
919#else
920#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
921#endif
922
923#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
924#undef JSON_HEDLEY_GCC_HAS_BUILTIN
925#endif
926#if defined(__has_builtin)
927#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
928#else
929#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
930#endif
931
932#if defined(JSON_HEDLEY_HAS_FEATURE)
933#undef JSON_HEDLEY_HAS_FEATURE
934#endif
935#if defined(__has_feature)
936#define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
937#else
938#define JSON_HEDLEY_HAS_FEATURE(feature) (0)
939#endif
940
941#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
942#undef JSON_HEDLEY_GNUC_HAS_FEATURE
943#endif
944#if defined(__has_feature)
945#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
946#else
947#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
948#endif
949
950#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
951#undef JSON_HEDLEY_GCC_HAS_FEATURE
952#endif
953#if defined(__has_feature)
954#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
955#else
956#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
957#endif
958
959#if defined(JSON_HEDLEY_HAS_EXTENSION)
960#undef JSON_HEDLEY_HAS_EXTENSION
961#endif
962#if defined(__has_extension)
963#define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
964#else
965#define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
966#endif
967
968#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
969#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
970#endif
971#if defined(__has_extension)
972#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
973#else
974#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
975#endif
976
977#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
978#undef JSON_HEDLEY_GCC_HAS_EXTENSION
979#endif
980#if defined(__has_extension)
981#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
982#else
983#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
984#endif
985
986#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
987#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
988#endif
989#if defined(__has_declspec_attribute)
990#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
991#else
992#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
993#endif
994
995#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
996#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
997#endif
998#if defined(__has_declspec_attribute)
999#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1000#else
1001#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1002#endif
1003
1004#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
1005#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
1006#endif
1007#if defined(__has_declspec_attribute)
1008#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
1009#else
1010#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1011#endif
1012
1013#if defined(JSON_HEDLEY_HAS_WARNING)
1014#undef JSON_HEDLEY_HAS_WARNING
1015#endif
1016#if defined(__has_warning)
1017#define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
1018#else
1019#define JSON_HEDLEY_HAS_WARNING(warning) (0)
1020#endif
1021
1022#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
1023#undef JSON_HEDLEY_GNUC_HAS_WARNING
1024#endif
1025#if defined(__has_warning)
1026#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1027#else
1028#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
1029#endif
1030
1031#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
1032#undef JSON_HEDLEY_GCC_HAS_WARNING
1033#endif
1034#if defined(__has_warning)
1035#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
1036#else
1037#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1038#endif
1039
1040#if \
1041 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1042 defined(__clang__) || \
1043 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1044 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1045 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1046 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1047 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1048 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1049 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1050 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1051 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1052 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
1053 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1054 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1055 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
1056 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
1057 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
1058 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
1059#define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
1060#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1061#define JSON_HEDLEY_PRAGMA(value) __pragma(value)
1062#else
1063#define JSON_HEDLEY_PRAGMA(value)
1064#endif
1065
1066#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
1067#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
1068#endif
1069#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
1070#undef JSON_HEDLEY_DIAGNOSTIC_POP
1071#endif
1072#if defined(__clang__)
1073#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1074#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1075#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1076#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1077#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1078#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1079#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1080#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1081#elif \
1082 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1083 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1084#define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
1085#define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
1086#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
1087#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
1088#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
1089#elif \
1090 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1091 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1092 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
1093 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1094 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1095 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1096#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
1097#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
1098#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1099#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
1100#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
1101#else
1102#define JSON_HEDLEY_DIAGNOSTIC_PUSH
1103#define JSON_HEDLEY_DIAGNOSTIC_POP
1104#endif
1105
1106 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
1107 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1108#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1109#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
1110#endif
1111#if defined(__cplusplus)
1112# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
1113# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
1114# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
1115# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1116 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1117 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1118 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1119 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
1120 xpr \
1121 JSON_HEDLEY_DIAGNOSTIC_POP
1122# else
1123# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1124 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1125 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1126 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
1127 xpr \
1128 JSON_HEDLEY_DIAGNOSTIC_POP
1129# endif
1130# else
1131# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
1132 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1133 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
1134 xpr \
1135 JSON_HEDLEY_DIAGNOSTIC_POP
1136# endif
1137# endif
1138#endif
1139#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1140#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1141#endif
1142
1143#if defined(JSON_HEDLEY_CONST_CAST)
1144#undef JSON_HEDLEY_CONST_CAST
1145#endif
1146#if defined(__cplusplus)
1147# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1148#elif \
1149 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1150 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1151 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1152# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1153 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1154 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1155 ((T) (expr)); \
1156 JSON_HEDLEY_DIAGNOSTIC_POP \
1157 }))
1158#else
1159# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1160#endif
1161
1162#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1163#undef JSON_HEDLEY_REINTERPRET_CAST
1164#endif
1165#if defined(__cplusplus)
1166#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1167#else
1168#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1169#endif
1170
1171#if defined(JSON_HEDLEY_STATIC_CAST)
1172#undef JSON_HEDLEY_STATIC_CAST
1173#endif
1174#if defined(__cplusplus)
1175#define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1176#else
1177#define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1178#endif
1179
1180#if defined(JSON_HEDLEY_CPP_CAST)
1181#undef JSON_HEDLEY_CPP_CAST
1182#endif
1183#if defined(__cplusplus)
1184# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1185# define JSON_HEDLEY_CPP_CAST(T, expr) \
1186 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1187 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1188 ((T) (expr)) \
1189 JSON_HEDLEY_DIAGNOSTIC_POP
1190# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1191# define JSON_HEDLEY_CPP_CAST(T, expr) \
1192 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1193 _Pragma("diag_suppress=Pe137") \
1194 JSON_HEDLEY_DIAGNOSTIC_POP
1195# else
1196# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1197# endif
1198#else
1199# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1200#endif
1201
1202#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1203#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1204#endif
1205#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1206#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1207#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1208#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1209#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1210#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1211#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1212#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1213#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1214#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1215#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1216#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1217#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1218#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1219#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1220#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1221#elif \
1222 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1233#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1234#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1235#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1236#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1237#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1238#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1239#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1240#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1241#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1242#else
1243#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1244#endif
1245
1246#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1247#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1248#endif
1249#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1250#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1251#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1252#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1253#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1254#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1255#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1256#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1257#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1258#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1259#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1260#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1261#elif \
1262 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1263 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1264 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1265 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1266#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1267#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1268#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1269#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1270#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1271#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1272#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1273#else
1274#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1275#endif
1276
1277#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1278#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1279#endif
1280#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1281#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1282#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1283#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1284#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1285#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1286#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1287#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1288#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1289#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1290#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1291#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1292#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1293#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1294#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1295#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1296#elif \
1297 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1298 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1299 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1300#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1301#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1302#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1303#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1304#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1305#else
1306#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1307#endif
1308
1309#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1310#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1311#endif
1312#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1313#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1314#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1315#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1316#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1317#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1318#else
1319#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1320#endif
1321
1322#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1323#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1324#endif
1325#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1326#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1327#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1328#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1329#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1330#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1331#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1332#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1333#else
1334#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1335#endif
1336
1337#if defined(JSON_HEDLEY_DEPRECATED)
1338#undef JSON_HEDLEY_DEPRECATED
1339#endif
1340#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1341#undef JSON_HEDLEY_DEPRECATED_FOR
1342#endif
1343#if \
1344 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1345 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1346#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1347#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1348#elif \
1349 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1350 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1351 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1352 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1353 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1354 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1355 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1356 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1357 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1358 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1359 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1360 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1361#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1362#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1363#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1364#define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1365#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1366#elif \
1367 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1368 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1369 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1370 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1371 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1372 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1373 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1374 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1375 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1376 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1377 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1378 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1379 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1380 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1381 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1382 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1383#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1384#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1385#elif \
1386 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1387 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1388 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1389#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1390#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1391#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1392#define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1393#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1394#else
1395#define JSON_HEDLEY_DEPRECATED(since)
1396#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1397#endif
1398
1399#if defined(JSON_HEDLEY_UNAVAILABLE)
1400#undef JSON_HEDLEY_UNAVAILABLE
1401#endif
1402#if \
1403 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1404 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1405 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1406 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1407#define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1408#else
1409#define JSON_HEDLEY_UNAVAILABLE(available_since)
1410#endif
1411
1412#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1413#undef JSON_HEDLEY_WARN_UNUSED_RESULT
1414#endif
1415#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1416#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1417#endif
1418#if \
1419 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1420 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1421 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1422 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1423 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1424 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1425 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1426 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1427 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1428 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1429 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1430 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1431 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1432 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1433 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1434 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1435 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1436#define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1437#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1438#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1439#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1440#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1441#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1442#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1443#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1444#elif defined(_Check_return_) /* SAL */
1445#define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1446#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1447#else
1448#define JSON_HEDLEY_WARN_UNUSED_RESULT
1449#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1450#endif
1451
1452#if defined(JSON_HEDLEY_SENTINEL)
1453#undef JSON_HEDLEY_SENTINEL
1454#endif
1455#if \
1456 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1457 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1458 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1459 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1460 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1461#define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1462#else
1463#define JSON_HEDLEY_SENTINEL(position)
1464#endif
1465
1466#if defined(JSON_HEDLEY_NO_RETURN)
1467#undef JSON_HEDLEY_NO_RETURN
1468#endif
1469#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1470#define JSON_HEDLEY_NO_RETURN __noreturn
1471#elif \
1472 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1474#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1475#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1476#define JSON_HEDLEY_NO_RETURN _Noreturn
1477#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1478#define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1479#elif \
1480 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1481 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1482 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1483 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1484 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1485 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1486 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1488 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1490 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1492 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1493 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1494 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1495 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1496 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1497#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1498#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1499#define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1500#elif \
1501 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1502 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1503#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1504#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1505#define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1506#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1507#define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1508#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1509#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1510#else
1511#define JSON_HEDLEY_NO_RETURN
1512#endif
1513
1514#if defined(JSON_HEDLEY_NO_ESCAPE)
1515#undef JSON_HEDLEY_NO_ESCAPE
1516#endif
1517#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1518#define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1519#else
1520#define JSON_HEDLEY_NO_ESCAPE
1521#endif
1522
1523#if defined(JSON_HEDLEY_UNREACHABLE)
1524#undef JSON_HEDLEY_UNREACHABLE
1525#endif
1526#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1527#undef JSON_HEDLEY_UNREACHABLE_RETURN
1528#endif
1529#if defined(JSON_HEDLEY_ASSUME)
1530#undef JSON_HEDLEY_ASSUME
1531#endif
1532#if \
1533 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1534 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1535 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1536#define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1537#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1538#define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1539#elif \
1540 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1541 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1542#if defined(__cplusplus)
1543#define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1544#else
1545#define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1546#endif
1547#endif
1548#if \
1549 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1550 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1551 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1552 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1553 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1554 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1555 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1556#define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1557#elif defined(JSON_HEDLEY_ASSUME)
1558#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1559#endif
1560#if !defined(JSON_HEDLEY_ASSUME)
1561#if defined(JSON_HEDLEY_UNREACHABLE)
1562#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1563#else
1564#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1565#endif
1566#endif
1567#if defined(JSON_HEDLEY_UNREACHABLE)
1568#if \
1569 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1570 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1571#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1572#else
1573#define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1574#endif
1575#else
1576#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1577#endif
1578#if !defined(JSON_HEDLEY_UNREACHABLE)
1579#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1580#endif
1581
1583#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1584#pragma clang diagnostic ignored "-Wpedantic"
1585#endif
1586#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1587#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1588#endif
1589#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1590#if defined(__clang__)
1591#pragma clang diagnostic ignored "-Wvariadic-macros"
1592#elif defined(JSON_HEDLEY_GCC_VERSION)
1593#pragma GCC diagnostic ignored "-Wvariadic-macros"
1594#endif
1595#endif
1596#if defined(JSON_HEDLEY_NON_NULL)
1597#undef JSON_HEDLEY_NON_NULL
1598#endif
1599#if \
1600 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1601 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1602 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1603 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1604#define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1605#else
1606#define JSON_HEDLEY_NON_NULL(...)
1607#endif
1609
1610#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1611#undef JSON_HEDLEY_PRINTF_FORMAT
1612#endif
1613#if 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__(ms_printf, string_idx, first_to_check)))
1615#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1616#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1617#elif \
1618 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1619 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1620 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1621 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1622 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1623 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1624 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1625 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1626 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1627 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1628 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1629 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1630 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1631 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1632 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1633 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1634 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1635#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1636#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1637#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1638#else
1639#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1640#endif
1641
1642#if defined(JSON_HEDLEY_CONSTEXPR)
1643#undef JSON_HEDLEY_CONSTEXPR
1644#endif
1645#if defined(__cplusplus)
1646#if __cplusplus >= 201103L
1647#define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1648#endif
1649#endif
1650#if !defined(JSON_HEDLEY_CONSTEXPR)
1651#define JSON_HEDLEY_CONSTEXPR
1652#endif
1653
1654#if defined(JSON_HEDLEY_PREDICT)
1655#undef JSON_HEDLEY_PREDICT
1656#endif
1657#if defined(JSON_HEDLEY_LIKELY)
1658#undef JSON_HEDLEY_LIKELY
1659#endif
1660#if defined(JSON_HEDLEY_UNLIKELY)
1661#undef JSON_HEDLEY_UNLIKELY
1662#endif
1663#if defined(JSON_HEDLEY_UNPREDICTABLE)
1664#undef JSON_HEDLEY_UNPREDICTABLE
1665#endif
1666#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1667#define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1668#endif
1669#if \
1670 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1671 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1672 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1673# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1674# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1675# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1676# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1677# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1678#elif \
1679 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1680 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1681 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1683 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1686 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1687 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1688 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1689 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1690 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1691 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1692 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1693 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1694 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1695# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1696 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1697# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1698 (__extension__ ({ \
1699 double hedley_probability_ = (probability); \
1700 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1701 }))
1702# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1703 (__extension__ ({ \
1704 double hedley_probability_ = (probability); \
1705 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1706 }))
1707# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1708# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1709#else
1710# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1711# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1712# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1713# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1714# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1715#endif
1716#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1717#define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1718#endif
1719
1720#if defined(JSON_HEDLEY_MALLOC)
1721#undef JSON_HEDLEY_MALLOC
1722#endif
1723#if \
1724 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1725 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1726 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1727 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1728 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1729 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1730 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1731 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1732 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1733 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1734 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1735 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1736 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1737 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1738 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1739 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1740 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1741 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1742#define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1743#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1744#define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1745#elif \
1746 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1747 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1748#define JSON_HEDLEY_MALLOC __declspec(restrict)
1749#else
1750#define JSON_HEDLEY_MALLOC
1751#endif
1752
1753#if defined(JSON_HEDLEY_PURE)
1754#undef JSON_HEDLEY_PURE
1755#endif
1756#if \
1757 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1758 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1759 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1760 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1761 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1762 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1763 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1764 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1765 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1766 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1767 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1768 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1769 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1770 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1771 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1772 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1773 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1774 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1775 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1776# define JSON_HEDLEY_PURE __attribute__((__pure__))
1777#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1778# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1779#elif defined(__cplusplus) && \
1780 ( \
1781 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1782 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1783 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1784 )
1785# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1786#else
1787# define JSON_HEDLEY_PURE
1788#endif
1789
1790#if defined(JSON_HEDLEY_CONST)
1791#undef JSON_HEDLEY_CONST
1792#endif
1793#if \
1794 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1795 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1796 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1797 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1798 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1799 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1800 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1801 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1802 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1803 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1804 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1805 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1806 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1807 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1808 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1809 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1810 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1811 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1812 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1813#define JSON_HEDLEY_CONST __attribute__((__const__))
1814#elif \
1815 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1816#define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1817#else
1818#define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1819#endif
1820
1821#if defined(JSON_HEDLEY_RESTRICT)
1822#undef JSON_HEDLEY_RESTRICT
1823#endif
1824#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1825#define JSON_HEDLEY_RESTRICT restrict
1826#elif \
1827 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1828 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1829 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1830 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1831 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1832 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1833 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1834 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1835 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1836 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1837 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1838 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1839 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1840 defined(__clang__) || \
1841 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1842#define JSON_HEDLEY_RESTRICT __restrict
1843#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1844#define JSON_HEDLEY_RESTRICT _Restrict
1845#else
1846#define JSON_HEDLEY_RESTRICT
1847#endif
1848
1849#if defined(JSON_HEDLEY_INLINE)
1850#undef JSON_HEDLEY_INLINE
1851#endif
1852#if \
1853 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1854 (defined(__cplusplus) && (__cplusplus >= 199711L))
1855#define JSON_HEDLEY_INLINE inline
1856#elif \
1857 defined(JSON_HEDLEY_GCC_VERSION) || \
1858 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1859#define JSON_HEDLEY_INLINE __inline__
1860#elif \
1861 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1862 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1863 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1864 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1865 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1866 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1867 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1868 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1869 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1870 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1871#define JSON_HEDLEY_INLINE __inline
1872#else
1873#define JSON_HEDLEY_INLINE
1874#endif
1875
1876#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1877#undef JSON_HEDLEY_ALWAYS_INLINE
1878#endif
1879#if \
1880 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1881 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1882 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1883 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1884 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1885 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1886 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1887 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1888 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1889 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1890 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1891 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1892 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1893 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1894 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1895 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1896 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1897 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1898 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1899# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1900#elif \
1901 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1902 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1903# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1904#elif defined(__cplusplus) && \
1905 ( \
1906 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1907 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1908 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1909 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1910 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1911 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1912 )
1913# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1914#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1915# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1916#else
1917# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1918#endif
1919
1920#if defined(JSON_HEDLEY_NEVER_INLINE)
1921#undef JSON_HEDLEY_NEVER_INLINE
1922#endif
1923#if \
1924 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1925 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1926 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1927 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1928 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1929 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1930 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1931 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1932 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1933 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1934 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1935 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1936 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1937 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1938 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1939 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1940 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1941 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1942 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1943#define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1944#elif \
1945 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1946 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1947#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1948#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1949#define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1950#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1951#define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1952#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1953#define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1954#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1955#define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1956#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1957#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1958#else
1959#define JSON_HEDLEY_NEVER_INLINE
1960#endif
1961
1962#if defined(JSON_HEDLEY_PRIVATE)
1963#undef JSON_HEDLEY_PRIVATE
1964#endif
1965#if defined(JSON_HEDLEY_PUBLIC)
1966#undef JSON_HEDLEY_PUBLIC
1967#endif
1968#if defined(JSON_HEDLEY_IMPORT)
1969#undef JSON_HEDLEY_IMPORT
1970#endif
1971#if defined(_WIN32) || defined(__CYGWIN__)
1972# define JSON_HEDLEY_PRIVATE
1973# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1974# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1975#else
1976# if \
1977 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1978 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1979 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1980 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1981 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1982 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1983 ( \
1984 defined(__TI_EABI__) && \
1985 ( \
1986 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1987 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1988 ) \
1989 ) || \
1990 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1991# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1992# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1993# else
1994# define JSON_HEDLEY_PRIVATE
1995# define JSON_HEDLEY_PUBLIC
1996# endif
1997# define JSON_HEDLEY_IMPORT extern
1998#endif
1999
2000#if defined(JSON_HEDLEY_NO_THROW)
2001#undef JSON_HEDLEY_NO_THROW
2002#endif
2003#if \
2004 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
2005 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
2006 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2007 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2008#define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
2009#elif \
2010 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
2011 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
2012 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
2013#define JSON_HEDLEY_NO_THROW __declspec(nothrow)
2014#else
2015#define JSON_HEDLEY_NO_THROW
2016#endif
2017
2018#if defined(JSON_HEDLEY_FALL_THROUGH)
2019#undef JSON_HEDLEY_FALL_THROUGH
2020#endif
2021#if \
2022 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
2023 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
2024 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2025#define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
2026#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
2027#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
2028#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
2029#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
2030#elif defined(__fallthrough) /* SAL */
2031#define JSON_HEDLEY_FALL_THROUGH __fallthrough
2032#else
2033#define JSON_HEDLEY_FALL_THROUGH
2034#endif
2035
2036#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
2037#undef JSON_HEDLEY_RETURNS_NON_NULL
2038#endif
2039#if \
2040 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
2041 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2042 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2043#define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
2044#elif defined(_Ret_notnull_) /* SAL */
2045#define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
2046#else
2047#define JSON_HEDLEY_RETURNS_NON_NULL
2048#endif
2049
2050#if defined(JSON_HEDLEY_ARRAY_PARAM)
2051#undef JSON_HEDLEY_ARRAY_PARAM
2052#endif
2053#if \
2054 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
2055 !defined(__STDC_NO_VLA__) && \
2056 !defined(__cplusplus) && \
2057 !defined(JSON_HEDLEY_PGI_VERSION) && \
2058 !defined(JSON_HEDLEY_TINYC_VERSION)
2059#define JSON_HEDLEY_ARRAY_PARAM(name) (name)
2060#else
2061#define JSON_HEDLEY_ARRAY_PARAM(name)
2062#endif
2063
2064#if defined(JSON_HEDLEY_IS_CONSTANT)
2065#undef JSON_HEDLEY_IS_CONSTANT
2066#endif
2067#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
2068#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
2069#endif
2070 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
2071 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
2072#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2073#undef JSON_HEDLEY_IS_CONSTEXPR_
2074#endif
2075#if \
2076 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
2077 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2078 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2079 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
2080 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
2081 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2082 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
2083 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
2084 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2085 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
2086#define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
2087#endif
2088#if !defined(__cplusplus)
2089# if \
2090 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
2091 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
2092 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2093 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
2094 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
2095 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
2096 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
2097#if defined(__INTPTR_TYPE__)
2098#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
2099#else
2100#include <stdint.h>
2101#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
2102#endif
2103# elif \
2104 ( \
2105 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
2106 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
2107 !defined(JSON_HEDLEY_PGI_VERSION) && \
2108 !defined(JSON_HEDLEY_IAR_VERSION)) || \
2109 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
2110 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
2111 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
2112 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
2113 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
2114#if defined(__INTPTR_TYPE__)
2115#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
2116#else
2117#include <stdint.h>
2118#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
2119#endif
2120# elif \
2121 defined(JSON_HEDLEY_GCC_VERSION) || \
2122 defined(JSON_HEDLEY_INTEL_VERSION) || \
2123 defined(JSON_HEDLEY_TINYC_VERSION) || \
2124 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
2125 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
2126 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
2127 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
2128 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
2129 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
2130 defined(__clang__)
2131# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
2132 sizeof(void) != \
2133 sizeof(*( \
2134 1 ? \
2135 ((void*) ((expr) * 0L) ) : \
2136((struct { char v[sizeof(void) * 2]; } *) 1) \
2137 ) \
2138 ) \
2139 )
2140# endif
2141#endif
2142#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2143#if !defined(JSON_HEDLEY_IS_CONSTANT)
2144#define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2145#endif
2146#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2147#else
2148#if !defined(JSON_HEDLEY_IS_CONSTANT)
2149#define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2150#endif
2151#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2152#endif
2153
2154#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2155#undef JSON_HEDLEY_BEGIN_C_DECLS
2156#endif
2157#if defined(JSON_HEDLEY_END_C_DECLS)
2158#undef JSON_HEDLEY_END_C_DECLS
2159#endif
2160#if defined(JSON_HEDLEY_C_DECL)
2161#undef JSON_HEDLEY_C_DECL
2162#endif
2163#if defined(__cplusplus)
2164#define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2165#define JSON_HEDLEY_END_C_DECLS }
2166#define JSON_HEDLEY_C_DECL extern "C"
2167#else
2168#define JSON_HEDLEY_BEGIN_C_DECLS
2169#define JSON_HEDLEY_END_C_DECLS
2170#define JSON_HEDLEY_C_DECL
2171#endif
2172
2173#if defined(JSON_HEDLEY_STATIC_ASSERT)
2174#undef JSON_HEDLEY_STATIC_ASSERT
2175#endif
2176#if \
2177 !defined(__cplusplus) && ( \
2178 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2179 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2180 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2181 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2182 defined(_Static_assert) \
2183 )
2184# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2185#elif \
2186 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2187 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2188 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2189# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2190#else
2191# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2192#endif
2193
2194#if defined(JSON_HEDLEY_NULL)
2195#undef JSON_HEDLEY_NULL
2196#endif
2197#if defined(__cplusplus)
2198#if __cplusplus >= 201103L
2199#define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2200#elif defined(NULL)
2201#define JSON_HEDLEY_NULL NULL
2202#else
2203#define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2204#endif
2205#elif defined(NULL)
2206#define JSON_HEDLEY_NULL NULL
2207#else
2208#define JSON_HEDLEY_NULL ((void*) 0)
2209#endif
2210
2211#if defined(JSON_HEDLEY_MESSAGE)
2212#undef JSON_HEDLEY_MESSAGE
2213#endif
2214#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2215# define JSON_HEDLEY_MESSAGE(msg) \
2216 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2217 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2218 JSON_HEDLEY_PRAGMA(message msg) \
2219 JSON_HEDLEY_DIAGNOSTIC_POP
2220#elif \
2221 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2222 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2223# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2224#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2225# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2226#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2227# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2228#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2229# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2230#else
2231# define JSON_HEDLEY_MESSAGE(msg)
2232#endif
2233
2234#if defined(JSON_HEDLEY_WARNING)
2235#undef JSON_HEDLEY_WARNING
2236#endif
2237#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2238# define JSON_HEDLEY_WARNING(msg) \
2239 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2240 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2241 JSON_HEDLEY_PRAGMA(clang warning msg) \
2242 JSON_HEDLEY_DIAGNOSTIC_POP
2243#elif \
2244 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2245 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2246 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2247# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2248#elif \
2249 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2250 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2251# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2252#else
2253# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2254#endif
2255
2256#if defined(JSON_HEDLEY_REQUIRE)
2257#undef JSON_HEDLEY_REQUIRE
2258#endif
2259#if defined(JSON_HEDLEY_REQUIRE_MSG)
2260#undef JSON_HEDLEY_REQUIRE_MSG
2261#endif
2262#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2263# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2264# define JSON_HEDLEY_REQUIRE(expr) \
2265 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2266 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2267 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2268 JSON_HEDLEY_DIAGNOSTIC_POP
2269# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2270 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2271 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2272 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2273 JSON_HEDLEY_DIAGNOSTIC_POP
2274# else
2275# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2276# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2277# endif
2278#else
2279# define JSON_HEDLEY_REQUIRE(expr)
2280# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2281#endif
2282
2283#if defined(JSON_HEDLEY_FLAGS)
2284#undef JSON_HEDLEY_FLAGS
2285#endif
2286#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2287#define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2288#else
2289#define JSON_HEDLEY_FLAGS
2290#endif
2291
2292#if defined(JSON_HEDLEY_FLAGS_CAST)
2293#undef JSON_HEDLEY_FLAGS_CAST
2294#endif
2295#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2296# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2297 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2298 _Pragma("warning(disable:188)") \
2299 ((T) (expr)); \
2300 JSON_HEDLEY_DIAGNOSTIC_POP \
2301 }))
2302#else
2303# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2304#endif
2305
2306#if defined(JSON_HEDLEY_EMPTY_BASES)
2307#undef JSON_HEDLEY_EMPTY_BASES
2308#endif
2309#if \
2310 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2311 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2312#define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2313#else
2314#define JSON_HEDLEY_EMPTY_BASES
2315#endif
2316
2317 /* Remaining macros are deprecated. */
2318
2319#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2320#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2321#endif
2322#if defined(__clang__)
2323#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2324#else
2325#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2326#endif
2327
2328#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2329#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2330#endif
2331#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2332
2333#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2334#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2335#endif
2336#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2337
2338#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2339#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2340#endif
2341#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2342
2343#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2344#undef JSON_HEDLEY_CLANG_HAS_FEATURE
2345#endif
2346#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2347
2348#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2349#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2350#endif
2351#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2352
2353#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2354#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2355#endif
2356#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2357
2358#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2359#undef JSON_HEDLEY_CLANG_HAS_WARNING
2360#endif
2361#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2362
2363#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2364
2365
2366// This file contains all internal macro definitions (except those affecting ABI)
2367// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2368
2369// #include <nlohmann/detail/abi_macros.hpp>
2370
2371
2372// exclude unsupported compilers
2373#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2374#if defined(__clang__)
2375#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2376#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2377#endif
2378#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2379#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2380#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2381#endif
2382#endif
2383#endif
2384
2385// C++ language standard detection
2386// if the user manually specified the used c++ version this is skipped
2387#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2388#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2389#define JSON_HAS_CPP_20
2390#define JSON_HAS_CPP_17
2391#define JSON_HAS_CPP_14
2392#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2393#define JSON_HAS_CPP_17
2394#define JSON_HAS_CPP_14
2395#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2396#define JSON_HAS_CPP_14
2397#endif
2398// the cpp 11 flag is always specified because it is the minimal required version
2399#define JSON_HAS_CPP_11
2400#endif
2401
2402#ifdef __has_include
2403#if __has_include(<version>)
2404#include <version>
2405#endif
2406#endif
2407
2408#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2409#ifdef JSON_HAS_CPP_17
2410#if defined(__cpp_lib_filesystem)
2411#define JSON_HAS_FILESYSTEM 1
2412#elif defined(__cpp_lib_experimental_filesystem)
2413#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2414#elif !defined(__has_include)
2415#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2416#elif __has_include(<filesystem>)
2417#define JSON_HAS_FILESYSTEM 1
2418#elif __has_include(<experimental/filesystem>)
2419#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2420#endif
2421
2422// std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2423#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2424#undef JSON_HAS_FILESYSTEM
2425#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2426#endif
2427
2428// no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2429#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2430#undef JSON_HAS_FILESYSTEM
2431#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2432#endif
2433
2434// no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2435#if defined(__clang_major__) && __clang_major__ < 7
2436#undef JSON_HAS_FILESYSTEM
2437#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2438#endif
2439
2440// no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2441#if defined(_MSC_VER) && _MSC_VER < 1914
2442#undef JSON_HAS_FILESYSTEM
2443#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2444#endif
2445
2446// no filesystem support before iOS 13
2447#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2448#undef JSON_HAS_FILESYSTEM
2449#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2450#endif
2451
2452// no filesystem support before macOS Catalina
2453#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2454#undef JSON_HAS_FILESYSTEM
2455#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2456#endif
2457#endif
2458#endif
2459
2460#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2461#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2462#endif
2463
2464#ifndef JSON_HAS_FILESYSTEM
2465#define JSON_HAS_FILESYSTEM 0
2466#endif
2467
2468#ifndef JSON_HAS_THREE_WAY_COMPARISON
2469#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2470 && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2471#define JSON_HAS_THREE_WAY_COMPARISON 1
2472#else
2473#define JSON_HAS_THREE_WAY_COMPARISON 0
2474#endif
2475#endif
2476
2477#ifndef JSON_HAS_RANGES
2478 // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2479#if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2480#define JSON_HAS_RANGES 0
2481#elif defined(__cpp_lib_ranges)
2482#define JSON_HAS_RANGES 1
2483#else
2484#define JSON_HAS_RANGES 0
2485#endif
2486#endif
2487
2488#ifndef JSON_HAS_STATIC_RTTI
2489#if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0
2490#define JSON_HAS_STATIC_RTTI 1
2491#else
2492#define JSON_HAS_STATIC_RTTI 0
2493#endif
2494#endif
2495
2496#ifdef JSON_HAS_CPP_17
2497#define JSON_INLINE_VARIABLE inline
2498#else
2499#define JSON_INLINE_VARIABLE
2500#endif
2501
2502#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2503#define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2504#else
2505#define JSON_NO_UNIQUE_ADDRESS
2506#endif
2507
2508// disable documentation warnings on clang
2509#if defined(__clang__)
2510#pragma clang diagnostic push
2511#pragma clang diagnostic ignored "-Wdocumentation"
2512#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2513#endif
2514
2515// allow disabling exceptions
2516#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2517#define JSON_THROW(exception) throw exception
2518#define JSON_TRY try
2519#define JSON_CATCH(exception) catch(exception)
2520#define JSON_INTERNAL_CATCH(exception) catch(exception)
2521#else
2522#include <cstdlib>
2523#define JSON_THROW(exception) std::abort()
2524#define JSON_TRY if(true)
2525#define JSON_CATCH(exception) if(false)
2526#define JSON_INTERNAL_CATCH(exception) if(false)
2527#endif
2528
2529// override exception macros
2530#if defined(JSON_THROW_USER)
2531#undef JSON_THROW
2532#define JSON_THROW JSON_THROW_USER
2533#endif
2534#if defined(JSON_TRY_USER)
2535#undef JSON_TRY
2536#define JSON_TRY JSON_TRY_USER
2537#endif
2538#if defined(JSON_CATCH_USER)
2539#undef JSON_CATCH
2540#define JSON_CATCH JSON_CATCH_USER
2541#undef JSON_INTERNAL_CATCH
2542#define JSON_INTERNAL_CATCH JSON_CATCH_USER
2543#endif
2544#if defined(JSON_INTERNAL_CATCH_USER)
2545#undef JSON_INTERNAL_CATCH
2546#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2547#endif
2548
2549// allow overriding assert
2550#if !defined(JSON_ASSERT)
2551#include <cassert> // assert
2552#define JSON_ASSERT(x) assert(x)
2553#endif
2554
2555// allow to access some private functions (needed by the test suite)
2556#if defined(JSON_TESTS_PRIVATE)
2557#define JSON_PRIVATE_UNLESS_TESTED public
2558#else
2559#define JSON_PRIVATE_UNLESS_TESTED private
2560#endif
2561
2567#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2568 template<typename BasicJsonType> \
2569 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2570 { \
2571 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2572 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2573 auto it = std::find_if(std::begin(m), std::end(m), \
2574 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2575 { \
2576 return ej_pair.first == e; \
2577 }); \
2578 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2579 } \
2580 template<typename BasicJsonType> \
2581 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2582 { \
2583 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2584 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2585 auto it = std::find_if(std::begin(m), std::end(m), \
2586 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2587 { \
2588 return ej_pair.second == j; \
2589 }); \
2590 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2591 }
2592
2593// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2594// may be removed in the future once the class is split.
2595
2596#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2597 template<template<typename, typename, typename...> class ObjectType, \
2598 template<typename, typename...> class ArrayType, \
2599 class StringType, class BooleanType, class NumberIntegerType, \
2600 class NumberUnsignedType, class NumberFloatType, \
2601 template<typename> class AllocatorType, \
2602 template<typename, typename = void> class JSONSerializer, \
2603 class BinaryType, \
2604 class CustomBaseClass>
2605
2606#define NLOHMANN_BASIC_JSON_TPL \
2607 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2608 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2609 AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>
2610
2611// Macros to simplify conversion from/to types
2612
2613#define NLOHMANN_JSON_EXPAND( x ) x
2614#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
2615#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2616 NLOHMANN_JSON_PASTE64, \
2617 NLOHMANN_JSON_PASTE63, \
2618 NLOHMANN_JSON_PASTE62, \
2619 NLOHMANN_JSON_PASTE61, \
2620 NLOHMANN_JSON_PASTE60, \
2621 NLOHMANN_JSON_PASTE59, \
2622 NLOHMANN_JSON_PASTE58, \
2623 NLOHMANN_JSON_PASTE57, \
2624 NLOHMANN_JSON_PASTE56, \
2625 NLOHMANN_JSON_PASTE55, \
2626 NLOHMANN_JSON_PASTE54, \
2627 NLOHMANN_JSON_PASTE53, \
2628 NLOHMANN_JSON_PASTE52, \
2629 NLOHMANN_JSON_PASTE51, \
2630 NLOHMANN_JSON_PASTE50, \
2631 NLOHMANN_JSON_PASTE49, \
2632 NLOHMANN_JSON_PASTE48, \
2633 NLOHMANN_JSON_PASTE47, \
2634 NLOHMANN_JSON_PASTE46, \
2635 NLOHMANN_JSON_PASTE45, \
2636 NLOHMANN_JSON_PASTE44, \
2637 NLOHMANN_JSON_PASTE43, \
2638 NLOHMANN_JSON_PASTE42, \
2639 NLOHMANN_JSON_PASTE41, \
2640 NLOHMANN_JSON_PASTE40, \
2641 NLOHMANN_JSON_PASTE39, \
2642 NLOHMANN_JSON_PASTE38, \
2643 NLOHMANN_JSON_PASTE37, \
2644 NLOHMANN_JSON_PASTE36, \
2645 NLOHMANN_JSON_PASTE35, \
2646 NLOHMANN_JSON_PASTE34, \
2647 NLOHMANN_JSON_PASTE33, \
2648 NLOHMANN_JSON_PASTE32, \
2649 NLOHMANN_JSON_PASTE31, \
2650 NLOHMANN_JSON_PASTE30, \
2651 NLOHMANN_JSON_PASTE29, \
2652 NLOHMANN_JSON_PASTE28, \
2653 NLOHMANN_JSON_PASTE27, \
2654 NLOHMANN_JSON_PASTE26, \
2655 NLOHMANN_JSON_PASTE25, \
2656 NLOHMANN_JSON_PASTE24, \
2657 NLOHMANN_JSON_PASTE23, \
2658 NLOHMANN_JSON_PASTE22, \
2659 NLOHMANN_JSON_PASTE21, \
2660 NLOHMANN_JSON_PASTE20, \
2661 NLOHMANN_JSON_PASTE19, \
2662 NLOHMANN_JSON_PASTE18, \
2663 NLOHMANN_JSON_PASTE17, \
2664 NLOHMANN_JSON_PASTE16, \
2665 NLOHMANN_JSON_PASTE15, \
2666 NLOHMANN_JSON_PASTE14, \
2667 NLOHMANN_JSON_PASTE13, \
2668 NLOHMANN_JSON_PASTE12, \
2669 NLOHMANN_JSON_PASTE11, \
2670 NLOHMANN_JSON_PASTE10, \
2671 NLOHMANN_JSON_PASTE9, \
2672 NLOHMANN_JSON_PASTE8, \
2673 NLOHMANN_JSON_PASTE7, \
2674 NLOHMANN_JSON_PASTE6, \
2675 NLOHMANN_JSON_PASTE5, \
2676 NLOHMANN_JSON_PASTE4, \
2677 NLOHMANN_JSON_PASTE3, \
2678 NLOHMANN_JSON_PASTE2, \
2679 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2680#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2681#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2682#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2683#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2684#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2685#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)
2686#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)
2687#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)
2688#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)
2689#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)
2690#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)
2691#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)
2692#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)
2693#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)
2694#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)
2695#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)
2696#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)
2697#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)
2698#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)
2699#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)
2700#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)
2701#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)
2702#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)
2703#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)
2704#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)
2705#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)
2706#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)
2707#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)
2708#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)
2709#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)
2710#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)
2711#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)
2712#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)
2713#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)
2714#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)
2715#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)
2716#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)
2717#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)
2718#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)
2719#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)
2720#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)
2721#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)
2722#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)
2723#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)
2724#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)
2725#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)
2726#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)
2727#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)
2728#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)
2729#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)
2730#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)
2731#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)
2732#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)
2733#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)
2734#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)
2735#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)
2736#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)
2737#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)
2738#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)
2739#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)
2740#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)
2741#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)
2742#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)
2743
2744#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2745#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2746#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2747
2753#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2754 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__)) } \
2755 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__)) }
2756
2757#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2758 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__)) } \
2759 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2760
2761#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2762 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__)) }
2763
2769#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2770 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__)) } \
2771 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__)) }
2772
2773#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \
2774 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__)) }
2775
2776#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2777 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__)) } \
2778 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2779
2780// inspired from https://stackoverflow.com/a/26745591
2781// allows to call any std function as if (e.g. with begin):
2782// using std::begin; begin(x);
2783//
2784// it allows using the detected idiom to retrieve the return type
2785// of such an expression
2786#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2787 namespace detail { \
2788 using std::std_name; \
2789 \
2790 template<typename... T> \
2791 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2792 } \
2793 \
2794 namespace detail2 { \
2795 struct std_name##_tag \
2796 { \
2797 }; \
2798 \
2799 template<typename... T> \
2800 std_name##_tag std_name(T&&...); \
2801 \
2802 template<typename... T> \
2803 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2804 \
2805 template<typename... T> \
2806 struct would_call_std_##std_name \
2807 { \
2808 static constexpr auto const value = ::nlohmann::detail:: \
2809 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2810 }; \
2811 } /* namespace detail2 */ \
2812 \
2813 template<typename... T> \
2814 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2815 { \
2816 }
2817
2818#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2819#define JSON_USE_IMPLICIT_CONVERSIONS 1
2820#endif
2821
2822#if JSON_USE_IMPLICIT_CONVERSIONS
2823#define JSON_EXPLICIT
2824#else
2825#define JSON_EXPLICIT explicit
2826#endif
2827
2828#ifndef JSON_DISABLE_ENUM_SERIALIZATION
2829#define JSON_DISABLE_ENUM_SERIALIZATION 0
2830#endif
2831
2832#ifndef JSON_USE_GLOBAL_UDLS
2833#define JSON_USE_GLOBAL_UDLS 1
2834#endif
2835
2836#if JSON_HAS_THREE_WAY_COMPARISON
2837#include <compare> // partial_ordering
2838#endif
2839
2841namespace detail
2842{
2843
2845 // JSON type enumeration //
2847
2885
2899#if JSON_HAS_THREE_WAY_COMPARISON
2900 inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2901#else
2902 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2903#endif
2904 {
2905 static constexpr std::array<std::uint8_t, 9> order = { {
2906 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2907 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2908 6 /* binary */
2909 }
2910 };
2911
2912 const auto l_index = static_cast<std::size_t>(lhs);
2913 const auto r_index = static_cast<std::size_t>(rhs);
2914#if JSON_HAS_THREE_WAY_COMPARISON
2915 if (l_index < order.size() && r_index < order.size())
2916 {
2917 return order[l_index] <=> order[r_index]; // *NOPAD*
2918 }
2919 return std::partial_ordering::unordered;
2920#else
2921 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2922#endif
2923 }
2924
2925 // GCC selects the built-in operator< over an operator rewritten from
2926 // a user-defined spaceship operator
2927 // Clang, MSVC, and ICC select the rewritten candidate
2928 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2929#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2930 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2931 {
2932 return std::is_lt(lhs <=> rhs); // *NOPAD*
2933 }
2934#endif
2935
2936} // namespace detail
2938
2939// #include <nlohmann/detail/string_escape.hpp>
2940// __ _____ _____ _____
2941// __| | __| | | | JSON for Modern C++
2942// | | |__ | | | | | | version 3.11.3
2943// |_____|_____|_____|_|___| https://github.com/nlohmann/json
2944//
2945// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
2946// SPDX-License-Identifier: MIT
2947
2948
2949
2950// #include <nlohmann/detail/abi_macros.hpp>
2951
2952
2954namespace detail
2955{
2956
2970 template<typename StringType>
2971 inline void replace_substring(StringType& s, const StringType& f,
2972 const StringType& t)
2973 {
2974 JSON_ASSERT(!f.empty());
2975 for (auto pos = s.find(f); // find first occurrence of f
2976 pos != StringType::npos; // make sure f was found
2977 s.replace(pos, f.size(), t), // replace with t, and
2978 pos = s.find(f, pos + t.size())) // find next occurrence of f
2979 {
2980 }
2981 }
2982
2990 template<typename StringType>
2991 inline StringType escape(StringType s)
2992 {
2993 replace_substring(s, StringType{ "~" }, StringType{ "~0" });
2994 replace_substring(s, StringType{ "/" }, StringType{ "~1" });
2995 return s;
2996 }
2997
3005 template<typename StringType>
3006 static void unescape(StringType& s)
3007 {
3008 replace_substring(s, StringType{ "~1" }, StringType{ "/" });
3009 replace_substring(s, StringType{ "~0" }, StringType{ "~" });
3010 }
3011
3012} // namespace detail
3014
3015// #include <nlohmann/detail/input/position_t.hpp>
3016// __ _____ _____ _____
3017// __| | __| | | | JSON for Modern C++
3018// | | |__ | | | | | | version 3.11.3
3019// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3020//
3021// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3022// SPDX-License-Identifier: MIT
3023
3024
3025
3026#include <cstddef> // size_t
3027
3028// #include <nlohmann/detail/abi_macros.hpp>
3029
3030
3032namespace detail
3033{
3034
3037 {
3039 std::size_t chars_read_total = 0;
3043 std::size_t lines_read = 0;
3044
3046 constexpr operator size_t() const
3047 {
3048 return chars_read_total;
3049 }
3050 };
3051
3052} // namespace detail
3054
3055// #include <nlohmann/detail/macro_scope.hpp>
3056
3057// #include <nlohmann/detail/meta/cpp_future.hpp>
3058// __ _____ _____ _____
3059// __| | __| | | | JSON for Modern C++
3060// | | |__ | | | | | | version 3.11.3
3061// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3062//
3063// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3064// SPDX-FileCopyrightText: 2018 The Abseil Authors
3065// SPDX-License-Identifier: MIT
3066
3067
3068
3069#include <array> // array
3070#include <cstddef> // size_t
3071#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3072#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3073
3074// #include <nlohmann/detail/macro_scope.hpp>
3075
3076
3078namespace detail
3079{
3080
3081 template<typename T>
3082 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3083
3084#ifdef JSON_HAS_CPP_14
3085
3086 // the following utilities are natively available in C++14
3087 using std::enable_if_t;
3088 using std::index_sequence;
3089 using std::make_index_sequence;
3090 using std::index_sequence_for;
3091
3092#else
3093
3094 // alias templates to reduce boilerplate
3095 template<bool B, typename T = void>
3096 using enable_if_t = typename std::enable_if<B, T>::type;
3097
3098 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3099 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3100
3102
3103 // integer_sequence
3104 //
3105 // Class template representing a compile-time integer sequence. An instantiation
3106 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3107 // type through its template arguments (which is a common need when
3108 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3109 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3110 //
3111 // Example:
3112 //
3113 // template< class T, T... Ints >
3114 // void user_function(integer_sequence<T, Ints...>);
3115 //
3116 // int main()
3117 // {
3118 // // user_function's `T` will be deduced to `int` and `Ints...`
3119 // // will be deduced to `0, 1, 2, 3, 4`.
3120 // user_function(make_integer_sequence<int, 5>());
3121 // }
3122 template <typename T, T... Ints>
3124 {
3125 using value_type = T;
3126 static constexpr std::size_t size() noexcept
3127 {
3128 return sizeof...(Ints);
3129 }
3130 };
3131
3132 // index_sequence
3133 //
3134 // A helper template for an `integer_sequence` of `size_t`,
3135 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3136 // `std::index_sequence`.
3137 template <size_t... Ints>
3138 using index_sequence = integer_sequence<size_t, Ints...>;
3139
3141 {
3142
3143 template <typename Seq, size_t SeqSize, size_t Rem>
3144 struct Extend;
3145
3146 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3147 template <typename T, T... Ints, size_t SeqSize>
3148 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3149 {
3150 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3151 };
3152
3153 template <typename T, T... Ints, size_t SeqSize>
3154 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3155 {
3156 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3157 };
3158
3159 // Recursion helper for 'make_integer_sequence<T, N>'.
3160 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3161 template <typename T, size_t N>
3162 struct Gen
3163 {
3164 using type =
3165 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3166 };
3167
3168 template <typename T>
3169 struct Gen<T, 0>
3170 {
3172 };
3173
3174 } // namespace utility_internal
3175
3176 // Compile-time sequences of integers
3177
3178 // make_integer_sequence
3179 //
3180 // This template alias is equivalent to
3181 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3182 // replacement for C++14's `std::make_integer_sequence`.
3183 template <typename T, T N>
3185
3186 // make_index_sequence
3187 //
3188 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3189 // and is designed to be a drop-in replacement for C++14's
3190 // `std::make_index_sequence`.
3191 template <size_t N>
3193
3194 // index_sequence_for
3195 //
3196 // Converts a typename pack into an index sequence of the same length, and
3197 // is designed to be a drop-in replacement for C++14's
3198 // `std::index_sequence_for()`
3199 template <typename... Ts>
3201
3203
3204#endif
3205
3206// dispatch utility (taken from ranges-v3)
3207 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3208 template<> struct priority_tag<0> {};
3209
3210 // taken from ranges-v3
3211 template<typename T>
3213 {
3214 static JSON_INLINE_VARIABLE constexpr T value{};
3215 };
3216
3217#ifndef JSON_HAS_CPP_17
3218 template<typename T>
3220#endif
3221
3222 template<typename T, typename... Args>
3223 inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args)
3224 {
3225 return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}};
3226 }
3227
3228} // namespace detail
3230
3231// #include <nlohmann/detail/meta/type_traits.hpp>
3232// __ _____ _____ _____
3233// __| | __| | | | JSON for Modern C++
3234// | | |__ | | | | | | version 3.11.3
3235// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3236//
3237// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3238// SPDX-License-Identifier: MIT
3239
3240
3241
3242#include <limits> // numeric_limits
3243#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3244#include <utility> // declval
3245#include <tuple> // tuple
3246#include <string> // char_traits
3247
3248// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3249// __ _____ _____ _____
3250// __| | __| | | | JSON for Modern C++
3251// | | |__ | | | | | | version 3.11.3
3252// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3253//
3254// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3255// SPDX-License-Identifier: MIT
3256
3257
3258
3259#include <iterator> // random_access_iterator_tag
3260
3261// #include <nlohmann/detail/abi_macros.hpp>
3262
3263// #include <nlohmann/detail/meta/void_t.hpp>
3264
3265// #include <nlohmann/detail/meta/cpp_future.hpp>
3266
3267
3269namespace detail
3270{
3271
3272 template<typename It, typename = void>
3274
3275 template<typename It>
3277 It,
3278 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3279 typename It::reference, typename It::iterator_category >>
3280 {
3281 using difference_type = typename It::difference_type;
3282 using value_type = typename It::value_type;
3283 using pointer = typename It::pointer;
3284 using reference = typename It::reference;
3285 using iterator_category = typename It::iterator_category;
3286 };
3287
3288 // This is required as some compilers implement std::iterator_traits in a way that
3289 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3290 template<typename T, typename = void>
3292 {
3293 };
3294
3295 template<typename T>
3296 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3297 : iterator_types<T>
3298 {
3299 };
3300
3301 template<typename T>
3303 {
3304 using iterator_category = std::random_access_iterator_tag;
3305 using value_type = T;
3306 using difference_type = ptrdiff_t;
3307 using pointer = T*;
3308 using reference = T&;
3309 };
3310
3311} // namespace detail
3313
3314// #include <nlohmann/detail/macro_scope.hpp>
3315
3316// #include <nlohmann/detail/meta/call_std/begin.hpp>
3317// __ _____ _____ _____
3318// __| | __| | | | JSON for Modern C++
3319// | | |__ | | | | | | version 3.11.3
3320// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3321//
3322// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3323// SPDX-License-Identifier: MIT
3324
3325
3326
3327// #include <nlohmann/detail/macro_scope.hpp>
3328
3329
3331
3333
3335
3336// #include <nlohmann/detail/meta/call_std/end.hpp>
3337// __ _____ _____ _____
3338// __| | __| | | | JSON for Modern C++
3339// | | |__ | | | | | | version 3.11.3
3340// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3341//
3342// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3343// SPDX-License-Identifier: MIT
3344
3345
3346
3347// #include <nlohmann/detail/macro_scope.hpp>
3348
3349
3351
3353
3355
3356// #include <nlohmann/detail/meta/cpp_future.hpp>
3357
3358// #include <nlohmann/detail/meta/detected.hpp>
3359
3360// #include <nlohmann/json_fwd.hpp>
3361// __ _____ _____ _____
3362// __| | __| | | | JSON for Modern C++
3363// | | |__ | | | | | | version 3.11.3
3364// |_____|_____|_____|_|___| https://github.com/nlohmann/json
3365//
3366// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
3367// SPDX-License-Identifier: MIT
3368
3369#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3370#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3371
3372#include <cstdint> // int64_t, uint64_t
3373#include <map> // map
3374#include <memory> // allocator
3375#include <string> // string
3376#include <vector> // vector
3377
3378// #include <nlohmann/detail/abi_macros.hpp>
3379
3380
3387
3395template<typename T = void, typename SFINAE = void>
3396struct adl_serializer;
3397
3400template<template<typename U, typename V, typename... Args> class ObjectType =
3401 std::map,
3402 template<typename U, typename... Args> class ArrayType = std::vector,
3403 class StringType = std::string, class BooleanType = bool,
3404 class NumberIntegerType = std::int64_t,
3405 class NumberUnsignedType = std::uint64_t,
3406 class NumberFloatType = double,
3407 template<typename U> class AllocatorType = std::allocator,
3408 template<typename T, typename SFINAE = void> class JSONSerializer =
3410 class BinaryType = std::vector<std::uint8_t>, // cppcheck-suppress syntaxError
3411 class CustomBaseClass = void>
3412class basic_json;
3413
3416template<typename RefStringType>
3417class json_pointer;
3418
3424
3427template<class Key, class T, class IgnoredLess, class Allocator>
3428struct ordered_map;
3429
3433
3435
3436#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3437
3438
3448namespace detail
3449{
3450
3452 // helpers //
3454
3455 // Note to maintainers:
3456 //
3457 // Every trait in this file expects a non CV-qualified type.
3458 // The only exceptions are in the 'aliases for detected' section
3459 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3460 //
3461 // In this case, T has to be properly CV-qualified to constraint the function arguments
3462 // (e.g. to_json(BasicJsonType&, const T&))
3463
3464 template<typename> struct is_basic_json : std::false_type {};
3465
3467 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3468
3469 // used by exceptions create() member functions
3470 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3471 // false_type otherwise
3472 template<typename BasicJsonContext>
3474 std::integral_constant < bool,
3475 is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3476 || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3477 {};
3478
3480 // json_ref helpers //
3482
3483 template<typename>
3484 class json_ref;
3485
3486 template<typename>
3487 struct is_json_ref : std::false_type {};
3488
3489 template<typename T>
3490 struct is_json_ref<json_ref<T>> : std::true_type {};
3491
3493 // aliases for detected //
3495
3496 template<typename T>
3497 using mapped_type_t = typename T::mapped_type;
3498
3499 template<typename T>
3500 using key_type_t = typename T::key_type;
3501
3502 template<typename T>
3503 using value_type_t = typename T::value_type;
3504
3505 template<typename T>
3506 using difference_type_t = typename T::difference_type;
3507
3508 template<typename T>
3509 using pointer_t = typename T::pointer;
3510
3511 template<typename T>
3512 using reference_t = typename T::reference;
3513
3514 template<typename T>
3515 using iterator_category_t = typename T::iterator_category;
3516
3517 template<typename T, typename... Args>
3518 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3519
3520 template<typename T, typename... Args>
3521 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3522
3523 template<typename T, typename U>
3524 using get_template_function = decltype(std::declval<T>().template get<U>());
3525
3526 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3527 template<typename BasicJsonType, typename T, typename = void>
3528 struct has_from_json : std::false_type {};
3529
3530 // trait checking if j.get<T> is valid
3531 // use this trait instead of std::is_constructible or std::is_convertible,
3532 // both rely on, or make use of implicit conversions, and thus fail when T
3533 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3534 template <typename BasicJsonType, typename T>
3539
3540 template<typename BasicJsonType, typename T>
3541 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3542 {
3543 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3544
3545 static constexpr bool value =
3547 const BasicJsonType&, T&>::value;
3548 };
3549
3550 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3551 // this overload is used for non-default-constructible user-defined-types
3552 template<typename BasicJsonType, typename T, typename = void>
3553 struct has_non_default_from_json : std::false_type {};
3554
3555 template<typename BasicJsonType, typename T>
3557 {
3558 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3559
3560 static constexpr bool value =
3562 const BasicJsonType&>::value;
3563 };
3564
3565 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3566 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3567 template<typename BasicJsonType, typename T, typename = void>
3568 struct has_to_json : std::false_type {};
3569
3570 template<typename BasicJsonType, typename T>
3571 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3572 {
3573 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3574
3575 static constexpr bool value =
3576 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3577 T>::value;
3578 };
3579
3580 template<typename T>
3581 using detect_key_compare = typename T::key_compare;
3582
3583 template<typename T>
3584 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3585
3586 // obtains the actual object key comparator
3587 template<typename BasicJsonType>
3589 {
3590 using object_t = typename BasicJsonType::object_t;
3591 using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3592 using type = typename std::conditional < has_key_compare<object_t>::value,
3593 typename object_t::key_compare, object_comparator_t>::type;
3594 };
3595
3596 template<typename BasicJsonType>
3598
3600 // char_traits //
3602
3603 // Primary template of char_traits calls std char_traits
3604 template<typename T>
3605 struct char_traits : std::char_traits<T>
3606 {};
3607
3608 // Explicitly define char traits for unsigned char since it is not standard
3609 template<>
3610 struct char_traits<unsigned char> : std::char_traits<char>
3611 {
3612 using char_type = unsigned char;
3613 using int_type = uint64_t;
3614
3615 // Redefine to_int_type function
3616 static int_type to_int_type(char_type c) noexcept
3617 {
3618 return static_cast<int_type>(c);
3619 }
3620
3622 {
3623 return static_cast<char_type>(i);
3624 }
3625
3626 static constexpr int_type eof() noexcept
3627 {
3628 return static_cast<int_type>(EOF);
3629 }
3630 };
3631
3632 // Explicitly define char traits for signed char since it is not standard
3633 template<>
3634 struct char_traits<signed char> : std::char_traits<char>
3635 {
3636 using char_type = signed char;
3637 using int_type = uint64_t;
3638
3639 // Redefine to_int_type function
3640 static int_type to_int_type(char_type c) noexcept
3641 {
3642 return static_cast<int_type>(c);
3643 }
3644
3646 {
3647 return static_cast<char_type>(i);
3648 }
3649
3650 static constexpr int_type eof() noexcept
3651 {
3652 return static_cast<int_type>(EOF);
3653 }
3654 };
3655
3657 // is_ functions //
3659
3660 // https://en.cppreference.com/w/cpp/types/conjunction
3661 template<class...> struct conjunction : std::true_type { };
3662 template<class B> struct conjunction<B> : B { };
3663 template<class B, class... Bn>
3664 struct conjunction<B, Bn...>
3665 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3666
3667 // https://en.cppreference.com/w/cpp/types/negation
3668 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3669
3670 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3671 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3672 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3673 template <typename T>
3674 struct is_default_constructible : std::is_default_constructible<T> {};
3675
3676 template <typename T1, typename T2>
3677 struct is_default_constructible<std::pair<T1, T2>>
3678 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3679
3680 template <typename T1, typename T2>
3681 struct is_default_constructible<const std::pair<T1, T2>>
3682 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3683
3684 template <typename... Ts>
3685 struct is_default_constructible<std::tuple<Ts...>>
3686 : conjunction<is_default_constructible<Ts>...> {};
3687
3688 template <typename... Ts>
3689 struct is_default_constructible<const std::tuple<Ts...>>
3690 : conjunction<is_default_constructible<Ts>...> {};
3691
3692 template <typename T, typename... Args>
3693 struct is_constructible : std::is_constructible<T, Args...> {};
3694
3695 template <typename T1, typename T2>
3696 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3697
3698 template <typename T1, typename T2>
3699 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3700
3701 template <typename... Ts>
3702 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3703
3704 template <typename... Ts>
3705 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3706
3707 template<typename T, typename = void>
3708 struct is_iterator_traits : std::false_type {};
3709
3710 template<typename T>
3724
3725 template<typename T>
3727 {
3728 private:
3729 using t_ref = typename std::add_lvalue_reference<T>::type;
3730
3733
3734 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3735 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3736 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3737 static constexpr auto is_iterator_begin =
3739
3740 public:
3741 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value&& is_iterator_begin;
3742 };
3743
3744 template<typename R>
3745 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3746
3747 template<typename T>
3749
3750 // The following implementation of is_complete_type is taken from
3751 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3752 // and is written by Xiang Fan who agreed to using it in this library.
3753
3754 template<typename T, typename = void>
3755 struct is_complete_type : std::false_type {};
3756
3757 template<typename T>
3758 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3759
3760 template<typename BasicJsonType, typename CompatibleObjectType,
3761 typename = void>
3762 struct is_compatible_object_type_impl : std::false_type {};
3763
3764 template<typename BasicJsonType, typename CompatibleObjectType>
3766 BasicJsonType, CompatibleObjectType,
3767 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3768 is_detected<key_type_t, CompatibleObjectType>::value >>
3769 {
3770 using object_t = typename BasicJsonType::object_t;
3771
3772 // macOS's is_constructible does not play well with nonesuch...
3773 static constexpr bool value =
3774 is_constructible<typename object_t::key_type,
3775 typename CompatibleObjectType::key_type>::value&&
3776 is_constructible<typename object_t::mapped_type,
3777 typename CompatibleObjectType::mapped_type>::value;
3778 };
3779
3780 template<typename BasicJsonType, typename CompatibleObjectType>
3782 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3783
3784 template<typename BasicJsonType, typename ConstructibleObjectType,
3785 typename = void>
3786 struct is_constructible_object_type_impl : std::false_type {};
3787
3788 template<typename BasicJsonType, typename ConstructibleObjectType>
3790 BasicJsonType, ConstructibleObjectType,
3791 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3792 is_detected<key_type_t, ConstructibleObjectType>::value >>
3793 {
3794 using object_t = typename BasicJsonType::object_t;
3795
3796 static constexpr bool value =
3798 (std::is_move_assignable<ConstructibleObjectType>::value ||
3799 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3800 (is_constructible<typename ConstructibleObjectType::key_type,
3801 typename object_t::key_type>::value &&
3802 std::is_same <
3803 typename object_t::mapped_type,
3804 typename ConstructibleObjectType::mapped_type >::value)) ||
3805 (has_from_json<BasicJsonType,
3806 typename ConstructibleObjectType::mapped_type>::value ||
3808 BasicJsonType,
3809 typename ConstructibleObjectType::mapped_type >::value);
3810 };
3811
3812 template<typename BasicJsonType, typename ConstructibleObjectType>
3814 : is_constructible_object_type_impl<BasicJsonType,
3815 ConstructibleObjectType> {};
3816
3817 template<typename BasicJsonType, typename CompatibleStringType>
3823
3824 template<typename BasicJsonType, typename ConstructibleStringType>
3826 {
3827 // launder type through decltype() to fix compilation failure on ICPC
3828#ifdef __INTEL_COMPILER
3829 using laundered_type = decltype(std::declval<ConstructibleStringType>());
3830#else
3831 using laundered_type = ConstructibleStringType;
3832#endif
3833
3834 static constexpr auto value =
3835 conjunction <
3837 is_detected_exact<typename BasicJsonType::string_t::value_type,
3839 };
3840
3841 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3842 struct is_compatible_array_type_impl : std::false_type {};
3843
3844 template<typename BasicJsonType, typename CompatibleArrayType>
3846 BasicJsonType, CompatibleArrayType,
3847 enable_if_t <
3848 is_detected<iterator_t, CompatibleArrayType>::value&&
3849 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value &&
3850 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3851 // c.f. https://github.com/nlohmann/json/pull/3073
3852 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3853 {
3854 static constexpr bool value =
3855 is_constructible<BasicJsonType,
3857 };
3858
3859 template<typename BasicJsonType, typename CompatibleArrayType>
3861 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3862
3863 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3864 struct is_constructible_array_type_impl : std::false_type {};
3865
3866 template<typename BasicJsonType, typename ConstructibleArrayType>
3868 BasicJsonType, ConstructibleArrayType,
3869 enable_if_t<std::is_same<ConstructibleArrayType,
3870 typename BasicJsonType::value_type>::value >>
3871 : std::true_type {};
3872
3873 template<typename BasicJsonType, typename ConstructibleArrayType>
3875 BasicJsonType, ConstructibleArrayType,
3876 enable_if_t < !std::is_same<ConstructibleArrayType,
3877 typename BasicJsonType::value_type>::value &&
3878 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3879 is_default_constructible<ConstructibleArrayType>::value &&
3880 (std::is_move_assignable<ConstructibleArrayType>::value ||
3881 std::is_copy_assignable<ConstructibleArrayType>::value) &&
3882 is_detected<iterator_t, ConstructibleArrayType>::value&&
3883 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3884 is_detected<range_value_t, ConstructibleArrayType>::value &&
3885 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3886 // c.f. https://github.com/nlohmann/json/pull/3073
3887 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3889 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3890 {
3892
3893 static constexpr bool value =
3894 std::is_same<value_type,
3895 typename BasicJsonType::array_t::value_type>::value ||
3896 has_from_json<BasicJsonType,
3899 BasicJsonType,
3901 };
3902
3903 template<typename BasicJsonType, typename ConstructibleArrayType>
3905 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3906
3907 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3908 typename = void>
3909 struct is_compatible_integer_type_impl : std::false_type {};
3910
3911 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3913 RealIntegerType, CompatibleNumberIntegerType,
3914 enable_if_t < std::is_integral<RealIntegerType>::value&&
3915 std::is_integral<CompatibleNumberIntegerType>::value &&
3916 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3917 {
3918 // is there an assert somewhere on overflows?
3919 using RealLimits = std::numeric_limits<RealIntegerType>;
3920 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3921
3922 static constexpr auto value =
3923 is_constructible<RealIntegerType,
3924 CompatibleNumberIntegerType>::value&&
3925 CompatibleLimits::is_integer&&
3926 RealLimits::is_signed == CompatibleLimits::is_signed;
3927 };
3928
3929 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3931 : is_compatible_integer_type_impl<RealIntegerType,
3932 CompatibleNumberIntegerType> {};
3933
3934 template<typename BasicJsonType, typename CompatibleType, typename = void>
3935 struct is_compatible_type_impl : std::false_type {};
3936
3937 template<typename BasicJsonType, typename CompatibleType>
3939 BasicJsonType, CompatibleType,
3940 enable_if_t<is_complete_type<CompatibleType>::value >>
3941 {
3942 static constexpr bool value =
3944 };
3945
3946 template<typename BasicJsonType, typename CompatibleType>
3948 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3949
3950 template<typename T1, typename T2>
3951 struct is_constructible_tuple : std::false_type {};
3952
3953 template<typename T1, typename... Args>
3954 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3955
3956 template<typename BasicJsonType, typename T>
3957 struct is_json_iterator_of : std::false_type {};
3958
3959 template<typename BasicJsonType>
3960 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3961
3962 template<typename BasicJsonType>
3963 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3964 {};
3965
3966 // checks if a given type T is a template specialization of Primary
3967 template<template <typename...> class Primary, typename T>
3968 struct is_specialization_of : std::false_type {};
3969
3970 template<template <typename...> class Primary, typename... Args>
3971 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3972
3973 template<typename T>
3975
3976 // checks if A and B are comparable using Compare functor
3977 template<typename Compare, typename A, typename B, typename = void>
3978 struct is_comparable : std::false_type {};
3979
3980 template<typename Compare, typename A, typename B>
3981 struct is_comparable<Compare, A, B, void_t<
3982 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3983 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3984 >> : std::true_type {};
3985
3986 template<typename T>
3987 using detect_is_transparent = typename T::is_transparent;
3988
3989 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
3990 // see is_usable_as_basic_json_key_type below
3991 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3992 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3993 using is_usable_as_key_type = typename std::conditional <
3995 && !(ExcludeObjectKeyType&& std::is_same<KeyType,
3996 ObjectKeyType>::value)
3997 && (!RequireTransparentComparator
3998 || is_detected <detect_is_transparent, Comparator>::value)
4000 std::true_type,
4001 std::false_type >::type;
4002
4003 // type trait to check if KeyType can be used as object key
4004 // true if:
4005 // - KeyType is comparable with BasicJsonType::object_t::key_type
4006 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
4007 // - the comparator is transparent or RequireTransparentComparator is false
4008 // - KeyType is not a JSON iterator or json_pointer
4009 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
4010 bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
4011 using is_usable_as_basic_json_key_type = typename std::conditional <
4012 is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
4013 typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
4014 RequireTransparentComparator, ExcludeObjectKeyType>::value
4016 std::true_type,
4017 std::false_type >::type;
4018
4019 template<typename ObjectType, typename KeyType>
4020 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
4021
4022 // type trait to check if object_t has an erase() member functions accepting KeyType
4023 template<typename BasicJsonType, typename KeyType>
4024 using has_erase_with_key_type = typename std::conditional <
4025 is_detected <
4027 typename BasicJsonType::object_t, KeyType >::value,
4028 std::true_type,
4029 std::false_type >::type;
4030
4031 // a naive helper to check if a type is an ordered_map (exploits the fact that
4032 // ordered_map inherits capacity() from std::vector)
4033 template <typename T>
4035 {
4036 using one = char;
4037
4038 struct two
4039 {
4040 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4041 };
4042
4043 template <typename C> static one test(decltype(&C::capacity));
4044 template <typename C> static two test(...);
4045
4046 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
4047 };
4048
4049 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
4050 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
4052 {
4053 return static_cast<T>(value);
4054 }
4055
4056 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
4058 {
4059 return value;
4060 }
4061
4062 template<typename... Types>
4064
4065 template<typename... Types>
4067
4068 template<typename... Types>
4070
4071 // there's a disjunction trait in another PR; replace when merged
4072 template<typename... Types>
4073 using same_sign = std::integral_constant < bool,
4074 all_signed<Types...>::value || all_unsigned<Types...>::value >;
4075
4076 template<typename OfType, typename T>
4077 using never_out_of_range = std::integral_constant < bool,
4078 (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
4079 || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
4080
4081 template<typename OfType, typename T,
4082 bool OfTypeSigned = std::is_signed<OfType>::value,
4083 bool TSigned = std::is_signed<T>::value>
4085
4086 template<typename OfType, typename T>
4087 struct value_in_range_of_impl2<OfType, T, false, false>
4088 {
4089 static constexpr bool test(T val)
4090 {
4091 using CommonType = typename std::common_type<OfType, T>::type;
4092 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4093 }
4094 };
4095
4096 template<typename OfType, typename T>
4097 struct value_in_range_of_impl2<OfType, T, true, false>
4098 {
4099 static constexpr bool test(T val)
4100 {
4101 using CommonType = typename std::common_type<OfType, T>::type;
4102 return static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4103 }
4104 };
4105
4106 template<typename OfType, typename T>
4107 struct value_in_range_of_impl2<OfType, T, false, true>
4108 {
4109 static constexpr bool test(T val)
4110 {
4111 using CommonType = typename std::common_type<OfType, T>::type;
4112 return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4113 }
4114 };
4115
4116 template<typename OfType, typename T>
4117 struct value_in_range_of_impl2<OfType, T, true, true>
4118 {
4119 static constexpr bool test(T val)
4120 {
4121 using CommonType = typename std::common_type<OfType, T>::type;
4122 return static_cast<CommonType>(val) >= static_cast<CommonType>((std::numeric_limits<OfType>::min)())
4123 && static_cast<CommonType>(val) <= static_cast<CommonType>((std::numeric_limits<OfType>::max)());
4124 }
4125 };
4126
4127 template<typename OfType, typename T,
4128 bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
4131
4132 template<typename OfType, typename T>
4133 struct value_in_range_of_impl1<OfType, T, false>
4134 {
4135 static constexpr bool test(T val)
4136 {
4138 }
4139 };
4140
4141 template<typename OfType, typename T>
4142 struct value_in_range_of_impl1<OfType, T, true>
4143 {
4144 static constexpr bool test(T /*val*/)
4145 {
4146 return true;
4147 }
4148 };
4149
4150 template<typename OfType, typename T>
4151 inline constexpr bool value_in_range_of(T val)
4152 {
4154 }
4155
4156 template<bool Value>
4157 using bool_constant = std::integral_constant<bool, Value>;
4158
4160 // is_c_string
4162
4163 namespace impl
4164 {
4165
4166 template<typename T>
4167 inline constexpr bool is_c_string()
4168 {
4169 using TUnExt = typename std::remove_extent<T>::type;
4170 using TUnCVExt = typename std::remove_cv<TUnExt>::type;
4171 using TUnPtr = typename std::remove_pointer<T>::type;
4172 using TUnCVPtr = typename std::remove_cv<TUnPtr>::type;
4173 return
4174 (std::is_array<T>::value && std::is_same<TUnCVExt, char>::value)
4175 || (std::is_pointer<T>::value && std::is_same<TUnCVPtr, char>::value);
4176 }
4177
4178 } // namespace impl
4179
4180 // checks whether T is a [cv] char */[cv] char[] C string
4181 template<typename T>
4182 struct is_c_string : bool_constant<impl::is_c_string<T>()> {};
4183
4184 template<typename T>
4186
4188 // is_transparent
4190
4191 namespace impl
4192 {
4193
4194 template<typename T>
4195 inline constexpr bool is_transparent()
4196 {
4198 }
4199
4200 } // namespace impl
4201
4202 // checks whether T has a member named is_transparent
4203 template<typename T>
4204 struct is_transparent : bool_constant<impl::is_transparent<T>()> {};
4205
4207
4208} // namespace detail
4210
4211// #include <nlohmann/detail/string_concat.hpp>
4212// __ _____ _____ _____
4213// __| | __| | | | JSON for Modern C++
4214// | | |__ | | | | | | version 3.11.3
4215// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4216//
4217// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4218// SPDX-License-Identifier: MIT
4219
4220
4221
4222#include <cstring> // strlen
4223#include <string> // string
4224#include <utility> // forward
4225
4226// #include <nlohmann/detail/meta/cpp_future.hpp>
4227
4228// #include <nlohmann/detail/meta/detected.hpp>
4229
4230
4232namespace detail
4233{
4234
4235 inline std::size_t concat_length()
4236 {
4237 return 0;
4238 }
4239
4240 template<typename... Args>
4241 inline std::size_t concat_length(const char* cstr, const Args& ... rest);
4242
4243 template<typename StringType, typename... Args>
4244 inline std::size_t concat_length(const StringType& str, const Args& ... rest);
4245
4246 template<typename... Args>
4247 inline std::size_t concat_length(const char /*c*/, const Args& ... rest)
4248 {
4249 return 1 + concat_length(rest...);
4250 }
4251
4252 template<typename... Args>
4253 inline std::size_t concat_length(const char* cstr, const Args& ... rest)
4254 {
4255 // cppcheck-suppress ignoredReturnValue
4256 return ::strlen(cstr) + concat_length(rest...);
4257 }
4258
4259 template<typename StringType, typename... Args>
4260 inline std::size_t concat_length(const StringType& str, const Args& ... rest)
4261 {
4262 return str.size() + concat_length(rest...);
4263 }
4264
4265 template<typename OutStringType>
4266 inline void concat_into(OutStringType& /*out*/)
4267 {}
4268
4269 template<typename StringType, typename Arg>
4270 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg&& >()));
4271
4272 template<typename StringType, typename Arg>
4274
4275 template<typename StringType, typename Arg>
4276 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg&& >());
4277
4278 template<typename StringType, typename Arg>
4280
4281 template<typename StringType, typename Arg>
4282 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
4283
4284 template<typename StringType, typename Arg>
4286
4287 template<typename StringType, typename Arg>
4288 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
4289
4290 template<typename StringType, typename Arg>
4292
4293 template < typename OutStringType, typename Arg, typename... Args,
4294 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4296 inline void concat_into(OutStringType& out, Arg&& arg, Args && ... rest);
4297
4298 template < typename OutStringType, typename Arg, typename... Args,
4299 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4302 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4303
4304 template < typename OutStringType, typename Arg, typename... Args,
4305 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4309 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
4310
4311 template<typename OutStringType, typename Arg, typename... Args,
4313 inline void concat_into(OutStringType& out, Arg&& arg, Args && ... rest)
4314 {
4315 out.append(std::forward<Arg>(arg));
4316 concat_into(out, std::forward<Args>(rest)...);
4317 }
4318
4319 template < typename OutStringType, typename Arg, typename... Args,
4320 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4321 && detect_string_can_append_op<OutStringType, Arg>::value, int > >
4322 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
4323 {
4324 out += std::forward<Arg>(arg);
4325 concat_into(out, std::forward<Args>(rest)...);
4326 }
4327
4328 template < typename OutStringType, typename Arg, typename... Args,
4329 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4332 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4333 {
4334 out.append(arg.begin(), arg.end());
4335 concat_into(out, std::forward<Args>(rest)...);
4336 }
4337
4338 template < typename OutStringType, typename Arg, typename... Args,
4339 enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
4340 && !detect_string_can_append_op<OutStringType, Arg>::value
4341 && !detect_string_can_append_iter<OutStringType, Arg>::value
4342 && detect_string_can_append_data<OutStringType, Arg>::value, int > >
4343 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4344 {
4345 out.append(arg.data(), arg.size());
4346 concat_into(out, std::forward<Args>(rest)...);
4347 }
4348
4349 template<typename OutStringType = std::string, typename... Args>
4350 inline OutStringType concat(Args && ... args)
4351 {
4352 OutStringType str;
4353 str.reserve(concat_length(args...));
4354 concat_into(str, std::forward<Args>(args)...);
4355 return str;
4356 }
4357
4358} // namespace detail
4360
4361
4363namespace detail
4364{
4365
4367 // exceptions //
4369
4372 class exception : public std::exception
4373 {
4374 public:
4376 const char* what() const noexcept override
4377 {
4378 return m.what();
4379 }
4380
4382 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4383
4384 protected:
4386 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4387
4388 static std::string name(const std::string& ename, int id_)
4389 {
4390 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4391 }
4392
4393 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4394 {
4395 return "";
4396 }
4397
4398 template<typename BasicJsonType>
4399 static std::string diagnostics(const BasicJsonType* leaf_element)
4400 {
4401#if JSON_DIAGNOSTICS
4402 std::vector<std::string> tokens;
4403 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4404 {
4405 switch (current->m_parent->type())
4406 {
4407 case value_t::array:
4408 {
4409 for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
4410 {
4411 if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
4412 {
4413 tokens.emplace_back(std::to_string(i));
4414 break;
4415 }
4416 }
4417 break;
4418 }
4419
4420 case value_t::object:
4421 {
4422 for (const auto& element : *current->m_parent->m_data.m_value.object)
4423 {
4424 if (&element.second == current)
4425 {
4426 tokens.emplace_back(element.first.c_str());
4427 break;
4428 }
4429 }
4430 break;
4431 }
4432
4433 case value_t::null: // LCOV_EXCL_LINE
4434 case value_t::string: // LCOV_EXCL_LINE
4435 case value_t::boolean: // LCOV_EXCL_LINE
4436 case value_t::number_integer: // LCOV_EXCL_LINE
4437 case value_t::number_unsigned: // LCOV_EXCL_LINE
4438 case value_t::number_float: // LCOV_EXCL_LINE
4439 case value_t::binary: // LCOV_EXCL_LINE
4440 case value_t::discarded: // LCOV_EXCL_LINE
4441 default: // LCOV_EXCL_LINE
4442 break; // LCOV_EXCL_LINE
4443 }
4444 }
4445
4446 if (tokens.empty())
4447 {
4448 return "";
4449 }
4450
4451 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4452 [](const std::string& a, const std::string& b)
4453 {
4454 return concat(a, '/', detail::escape(b));
4455 });
4456 return concat('(', str, ") ");
4457#else
4458 static_cast<void>(leaf_element);
4459 return "";
4460#endif
4461 }
4462
4463 private:
4465 std::runtime_error m;
4466 };
4467
4470 class parse_error : public exception
4471 {
4472 public:
4482 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4483 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4484 {
4485 const std::string w = concat(exception::name("parse_error", id_), "parse error",
4486 position_string(pos), ": ", exception::diagnostics(context), what_arg);
4487 return { id_, pos.chars_read_total, w.c_str() };
4488 }
4489
4490 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4491 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4492 {
4493 const std::string w = concat(exception::name("parse_error", id_), "parse error",
4494 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4495 ": ", exception::diagnostics(context), what_arg);
4496 return { id_, byte_, w.c_str() };
4497 }
4498
4508 const std::size_t byte;
4509
4510 private:
4511 parse_error(int id_, std::size_t byte_, const char* what_arg)
4512 : exception(id_, what_arg), byte(byte_) {}
4513
4514 static std::string position_string(const position_t& pos)
4515 {
4516 return concat(" at line ", std::to_string(pos.lines_read + 1),
4517 ", column ", std::to_string(pos.chars_read_current_line));
4518 }
4519 };
4520
4524 {
4525 public:
4526 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4527 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4528 {
4529 const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4530 return { id_, w.c_str() };
4531 }
4532
4533 private:
4535 invalid_iterator(int id_, const char* what_arg)
4536 : exception(id_, what_arg) {}
4537 };
4538
4541 class type_error : public exception
4542 {
4543 public:
4544 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4545 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4546 {
4547 const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4548 return { id_, w.c_str() };
4549 }
4550
4551 private:
4553 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4554 };
4555
4559 {
4560 public:
4561 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4562 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4563 {
4564 const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4565 return { id_, w.c_str() };
4566 }
4567
4568 private:
4570 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4571 };
4572
4575 class other_error : public exception
4576 {
4577 public:
4578 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4579 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4580 {
4581 const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4582 return { id_, w.c_str() };
4583 }
4584
4585 private:
4587 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4588 };
4589
4590} // namespace detail
4592
4593// #include <nlohmann/detail/macro_scope.hpp>
4594
4595// #include <nlohmann/detail/meta/cpp_future.hpp>
4596
4597// #include <nlohmann/detail/meta/identity_tag.hpp>
4598// __ _____ _____ _____
4599// __| | __| | | | JSON for Modern C++
4600// | | |__ | | | | | | version 3.11.3
4601// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4602//
4603// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4604// SPDX-License-Identifier: MIT
4605
4606
4607
4608// #include <nlohmann/detail/abi_macros.hpp>
4609
4610
4612namespace detail
4613{
4614
4615 // dispatching helper struct
4616 template <class T> struct identity_tag {};
4617
4618} // namespace detail
4620
4621// #include <nlohmann/detail/meta/std_fs.hpp>
4622// __ _____ _____ _____
4623// __| | __| | | | JSON for Modern C++
4624// | | |__ | | | | | | version 3.11.3
4625// |_____|_____|_____|_|___| https://github.com/nlohmann/json
4626//
4627// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
4628// SPDX-License-Identifier: MIT
4629
4630
4631
4632// #include <nlohmann/detail/macro_scope.hpp>
4633
4634
4635#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4636#include <experimental/filesystem>
4638namespace detail
4639{
4640 namespace std_fs = std::experimental::filesystem;
4641} // namespace detail
4643#elif JSON_HAS_FILESYSTEM
4644#include <filesystem>
4646namespace detail
4647{
4648 namespace std_fs = std::filesystem;
4649} // namespace detail
4651#endif
4652
4653// #include <nlohmann/detail/meta/type_traits.hpp>
4654
4655// #include <nlohmann/detail/string_concat.hpp>
4656
4657// #include <nlohmann/detail/value_t.hpp>
4658
4659
4661namespace detail
4662{
4663
4664 template<typename BasicJsonType>
4665 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4666 {
4667 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4668 {
4669 JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4670 }
4671 n = nullptr;
4672 }
4673
4674 // overloads for basic_json template parameters
4675 template < typename BasicJsonType, typename ArithmeticType,
4676 enable_if_t < std::is_arithmetic<ArithmeticType>::value &&
4677 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4678 int > = 0 >
4679 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4680 {
4681 switch (static_cast<value_t>(j))
4682 {
4684 {
4685 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4686 break;
4687 }
4689 {
4690 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4691 break;
4692 }
4694 {
4695 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4696 break;
4697 }
4698
4699 case value_t::null:
4700 case value_t::object:
4701 case value_t::array:
4702 case value_t::string:
4703 case value_t::boolean:
4704 case value_t::binary:
4705 case value_t::discarded:
4706 default:
4707 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4708 }
4709 }
4710
4711 template<typename BasicJsonType>
4712 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4713 {
4714 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4715 {
4716 JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4717 }
4718 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4719 }
4720
4721 template<typename BasicJsonType>
4722 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4723 {
4724 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4725 {
4726 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4727 }
4728 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4729 }
4730
4731 template <
4732 typename BasicJsonType, typename StringType,
4733 enable_if_t <
4734 std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4735 && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
4736 && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4737 && !is_json_ref<StringType>::value, int > = 0 >
4738 inline void from_json(const BasicJsonType& j, StringType& s)
4739 {
4740 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4741 {
4742 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4743 }
4744
4745 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4746 }
4747
4748 template<typename BasicJsonType>
4749 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4750 {
4751 get_arithmetic_value(j, val);
4752 }
4753
4754 template<typename BasicJsonType>
4755 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4756 {
4757 get_arithmetic_value(j, val);
4758 }
4759
4760 template<typename BasicJsonType>
4761 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4762 {
4763 get_arithmetic_value(j, val);
4764 }
4765
4766#if !JSON_DISABLE_ENUM_SERIALIZATION
4767 template<typename BasicJsonType, typename EnumType,
4768 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4769 inline void from_json(const BasicJsonType& j, EnumType& e)
4770 {
4771 typename std::underlying_type<EnumType>::type val;
4772 get_arithmetic_value(j, val);
4773 e = static_cast<EnumType>(val);
4774 }
4775#endif // JSON_DISABLE_ENUM_SERIALIZATION
4776
4777 // forward_list doesn't have an insert method
4778 template<typename BasicJsonType, typename T, typename Allocator,
4779 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4780 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4781 {
4782 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4783 {
4784 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4785 }
4786 l.clear();
4787 std::transform(j.rbegin(), j.rend(),
4788 std::front_inserter(l), [](const BasicJsonType& i)
4789 {
4790 return i.template get<T>();
4791 });
4792 }
4793
4794 // valarray doesn't have an insert method
4795 template<typename BasicJsonType, typename T,
4796 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4797 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4798 {
4799 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4800 {
4801 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4802 }
4803 l.resize(j.size());
4804 std::transform(j.begin(), j.end(), std::begin(l),
4805 [](const BasicJsonType& elem)
4806 {
4807 return elem.template get<T>();
4808 });
4809 }
4810
4811 template<typename BasicJsonType, typename T, std::size_t N>
4812 auto from_json(const BasicJsonType& j, T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4813 -> decltype(j.template get<T>(), void())
4814 {
4815 for (std::size_t i = 0; i < N; ++i)
4816 {
4817 arr[i] = j.at(i).template get<T>();
4818 }
4819 }
4820
4821 template<typename BasicJsonType>
4822 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4823 {
4824 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4825 }
4826
4827 template<typename BasicJsonType, typename T, std::size_t N>
4828 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4829 priority_tag<2> /*unused*/)
4830 -> decltype(j.template get<T>(), void())
4831 {
4832 for (std::size_t i = 0; i < N; ++i)
4833 {
4834 arr[i] = j.at(i).template get<T>();
4835 }
4836 }
4837
4838 template<typename BasicJsonType, typename ConstructibleArrayType,
4840 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4841 int> = 0>
4842 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4843 -> decltype(
4844 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4846 void())
4847 {
4848 using std::end;
4849
4850 ConstructibleArrayType ret;
4851 ret.reserve(j.size());
4852 std::transform(j.begin(), j.end(),
4853 std::inserter(ret, end(ret)), [](const BasicJsonType& i)
4854 {
4855 // get<BasicJsonType>() returns *this, this won't call a from_json
4856 // method when value_type is BasicJsonType
4858 });
4859 arr = std::move(ret);
4860 }
4861
4862 template<typename BasicJsonType, typename ConstructibleArrayType,
4864 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4865 int> = 0>
4866 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4867 priority_tag<0> /*unused*/)
4868 {
4869 using std::end;
4870
4871 ConstructibleArrayType ret;
4872 std::transform(
4873 j.begin(), j.end(), std::inserter(ret, end(ret)),
4874 [](const BasicJsonType& i)
4875 {
4876 // get<BasicJsonType>() returns *this, this won't call a from_json
4877 // method when value_type is BasicJsonType
4879 });
4880 arr = std::move(ret);
4881 }
4882
4883 template < typename BasicJsonType, typename ConstructibleArrayType,
4884 enable_if_t <
4885 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value &&
4886 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value &&
4888 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value &&
4889 !is_basic_json<ConstructibleArrayType>::value,
4890 int > = 0 >
4891 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4892 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4894 void())
4895 {
4896 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4897 {
4898 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4899 }
4900
4902 }
4903
4904 template < typename BasicJsonType, typename T, std::size_t... Idx >
4905 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4906 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4907 {
4908 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4909 }
4910
4911 template < typename BasicJsonType, typename T, std::size_t N >
4912 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4913 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4914 {
4915 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4916 {
4917 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4918 }
4919
4920 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4921 }
4922
4923 template<typename BasicJsonType>
4924 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4925 {
4926 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4927 {
4928 JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4929 }
4930
4931 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4932 }
4933
4934 template<typename BasicJsonType, typename ConstructibleObjectType,
4935 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4936 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4937 {
4938 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4939 {
4940 JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4941 }
4942
4943 ConstructibleObjectType ret;
4944 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4945 using value_type = typename ConstructibleObjectType::value_type;
4946 std::transform(
4947 inner_object->begin(), inner_object->end(),
4948 std::inserter(ret, ret.begin()),
4949 [](typename BasicJsonType::object_t::value_type const& p)
4950 {
4951 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4952 });
4953 obj = std::move(ret);
4954 }
4955
4956 // overload for arithmetic types, not chosen for basic_json template arguments
4957 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4958 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4959 // an arithmetic type?
4960 template < typename BasicJsonType, typename ArithmeticType,
4961 enable_if_t <
4962 std::is_arithmetic<ArithmeticType>::value &&
4963 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value &&
4964 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value &&
4965 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value &&
4966 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4967 int > = 0 >
4968 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4969 {
4970 switch (static_cast<value_t>(j))
4971 {
4973 {
4974 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4975 break;
4976 }
4978 {
4979 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4980 break;
4981 }
4983 {
4984 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4985 break;
4986 }
4987 case value_t::boolean:
4988 {
4989 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4990 break;
4991 }
4992
4993 case value_t::null:
4994 case value_t::object:
4995 case value_t::array:
4996 case value_t::string:
4997 case value_t::binary:
4998 case value_t::discarded:
4999 default:
5000 JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
5001 }
5002 }
5003
5004 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
5005 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
5006 {
5007 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
5008 }
5009
5010 template < typename BasicJsonType, class A1, class A2 >
5011 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
5012 {
5013 return { std::forward<BasicJsonType>(j).at(0).template get<A1>(),
5014 std::forward<BasicJsonType>(j).at(1).template get<A2>() };
5015 }
5016
5017 template<typename BasicJsonType, typename A1, typename A2>
5018 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
5019 {
5020 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
5021 }
5022
5023 template<typename BasicJsonType, typename... Args>
5024 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
5025 {
5026 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5027 }
5028
5029 template<typename BasicJsonType, typename... Args>
5030 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
5031 {
5032 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
5033 }
5034
5035 template<typename BasicJsonType, typename TupleRelated>
5036 auto from_json(BasicJsonType&& j, TupleRelated&& t)
5037 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
5038 {
5039 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5040 {
5041 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5042 }
5043
5044 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
5045 }
5046
5047 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
5048 typename = enable_if_t < !std::is_constructible <
5049 typename BasicJsonType::string_t, Key >::value >>
5050 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
5051 {
5052 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5053 {
5054 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5055 }
5056 m.clear();
5057 for (const auto& p : j)
5058 {
5059 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5060 {
5061 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5062 }
5063 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5064 }
5065 }
5066
5067 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
5068 typename = enable_if_t < !std::is_constructible <
5069 typename BasicJsonType::string_t, Key >::value >>
5070 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
5071 {
5072 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
5073 {
5074 JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
5075 }
5076 m.clear();
5077 for (const auto& p : j)
5078 {
5079 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
5080 {
5081 JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
5082 }
5083 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
5084 }
5085 }
5086
5087#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5088 template<typename BasicJsonType>
5089 inline void from_json(const BasicJsonType& j, std_fs::path& p)
5090 {
5091 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
5092 {
5093 JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
5094 }
5095 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
5096 }
5097#endif
5098
5100 {
5101 template<typename BasicJsonType, typename T>
5102 auto operator()(const BasicJsonType& j, T&& val) const
5103 noexcept(noexcept(from_json(j, std::forward<T>(val))))
5104 -> decltype(from_json(j, std::forward<T>(val)))
5105 {
5106 return from_json(j, std::forward<T>(val));
5107 }
5108 };
5109
5110} // namespace detail
5111
5112#ifndef JSON_HAS_CPP_17
5116namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5117{
5118#endif
5119 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
5121#ifndef JSON_HAS_CPP_17
5122} // namespace
5123#endif
5124
5126
5127// #include <nlohmann/detail/conversions/to_json.hpp>
5128// __ _____ _____ _____
5129// __| | __| | | | JSON for Modern C++
5130// | | |__ | | | | | | version 3.11.3
5131// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5132//
5133// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5134// SPDX-License-Identifier: MIT
5135
5136
5137
5138#include <algorithm> // copy
5139#include <iterator> // begin, end
5140#include <string> // string
5141#include <tuple> // tuple, get
5142#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
5143#include <utility> // move, forward, declval, pair
5144#include <valarray> // valarray
5145#include <vector> // vector
5146
5147// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
5148// __ _____ _____ _____
5149// __| | __| | | | JSON for Modern C++
5150// | | |__ | | | | | | version 3.11.3
5151// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5152//
5153// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5154// SPDX-License-Identifier: MIT
5155
5156
5157
5158#include <cstddef> // size_t
5159#include <iterator> // input_iterator_tag
5160#include <string> // string, to_string
5161#include <tuple> // tuple_size, get, tuple_element
5162#include <utility> // move
5163
5164#if JSON_HAS_RANGES
5165#include <ranges> // enable_borrowed_range
5166#endif
5167
5168// #include <nlohmann/detail/abi_macros.hpp>
5169
5170// #include <nlohmann/detail/meta/type_traits.hpp>
5171
5172// #include <nlohmann/detail/value_t.hpp>
5173
5174
5176namespace detail
5177{
5178
5179 template<typename string_type>
5180 void int_to_string(string_type& target, std::size_t value)
5181 {
5182 // For ADL
5183 using std::to_string;
5184 target = to_string(value);
5185 }
5186 template<typename IteratorType> class iteration_proxy_value
5187 {
5188 public:
5189 using difference_type = std::ptrdiff_t;
5193 using iterator_category = std::input_iterator_tag;
5194 using string_type = typename std::remove_cv< typename std::remove_reference<decltype(std::declval<IteratorType>().key()) >::type >::type;
5195
5196 private:
5198 IteratorType anchor{};
5200 std::size_t array_index = 0;
5202 mutable std::size_t array_index_last = 0;
5207
5208 public:
5209 explicit iteration_proxy_value() = default;
5210 explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
5211 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5212 && std::is_nothrow_default_constructible<string_type>::value)
5213 : anchor(std::move(it))
5214 , array_index(array_index_)
5215 {}
5216
5219 // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
5221 noexcept(std::is_nothrow_move_constructible<IteratorType>::value
5222 && std::is_nothrow_move_constructible<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5224 noexcept(std::is_nothrow_move_assignable<IteratorType>::value
5225 && std::is_nothrow_move_assignable<string_type>::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations)
5227
5229 const iteration_proxy_value& operator*() const
5230 {
5231 return *this;
5232 }
5233
5236 {
5237 ++anchor;
5238 ++array_index;
5239
5240 return *this;
5241 }
5242
5243 iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
5244 {
5246 ++anchor;
5247 ++array_index;
5248 return tmp;
5249 }
5250
5253 {
5254 return anchor == o.anchor;
5255 }
5256
5259 {
5260 return anchor != o.anchor;
5261 }
5262
5264 const string_type& key() const
5265 {
5266 JSON_ASSERT(anchor.m_object != nullptr);
5267
5268 switch (anchor.m_object->type())
5269 {
5270 // use integer array index as key
5271 case value_t::array:
5272 {
5274 {
5277 }
5278 return array_index_str;
5279 }
5280
5281 // use key from the object
5282 case value_t::object:
5283 return anchor.key();
5284
5285 // use an empty key for all primitive types
5286 case value_t::null:
5287 case value_t::string:
5288 case value_t::boolean:
5292 case value_t::binary:
5293 case value_t::discarded:
5294 default:
5295 return empty_str;
5296 }
5297 }
5298
5300 typename IteratorType::reference value() const
5301 {
5302 return anchor.value();
5303 }
5304 };
5305
5307 template<typename IteratorType> class iteration_proxy
5308 {
5309 private:
5311 typename IteratorType::pointer container = nullptr;
5312
5313 public:
5314 explicit iteration_proxy() = default;
5315
5317 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
5318 : container(&cont) {}
5319
5322 iteration_proxy(iteration_proxy&&) noexcept = default;
5323 iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
5324 ~iteration_proxy() = default;
5325
5327 iteration_proxy_value<IteratorType> begin() const noexcept
5328 {
5330 }
5331
5337 };
5338
5339 // Structured Bindings Support
5340 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5341 // And see https://github.com/nlohmann/json/pull/1391
5342 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
5343 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
5344 {
5345 return i.key();
5346 }
5347 // Structured Bindings Support
5348 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
5349 // And see https://github.com/nlohmann/json/pull/1391
5350 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
5351 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
5352 {
5353 return i.value();
5354 }
5355
5356} // namespace detail
5358
5359// The Addition to the STD Namespace is required to add
5360// Structured Bindings Support to the iteration_proxy_value class
5361// For further reference see https://blog.tartanllama.xyz/structured-bindings/
5362// And see https://github.com/nlohmann/json/pull/1391
5363namespace std
5364{
5365
5366#if defined(__clang__)
5367 // Fix: https://github.com/nlohmann/json/issues/1401
5368#pragma clang diagnostic push
5369#pragma clang diagnostic ignored "-Wmismatched-tags"
5370#endif
5371 template<typename IteratorType>
5372 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>> // NOLINT(cert-dcl58-cpp)
5373 : public std::integral_constant<std::size_t, 2> {};
5374
5375 template<std::size_t N, typename IteratorType>
5376 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >> // NOLINT(cert-dcl58-cpp)
5377 {
5378 public:
5379 using type = decltype(
5380 get<N>(std::declval <
5381 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
5382 };
5383#if defined(__clang__)
5384#pragma clang diagnostic pop
5385#endif
5386
5387} // namespace std
5388
5389#if JSON_HAS_RANGES
5390template <typename IteratorType>
5391inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
5392#endif
5393
5394// #include <nlohmann/detail/macro_scope.hpp>
5395
5396// #include <nlohmann/detail/meta/cpp_future.hpp>
5397
5398// #include <nlohmann/detail/meta/std_fs.hpp>
5399
5400// #include <nlohmann/detail/meta/type_traits.hpp>
5401
5402// #include <nlohmann/detail/value_t.hpp>
5403
5404
5406namespace detail
5407{
5408
5410 // constructors //
5412
5413 /*
5414 * Note all external_constructor<>::construct functions need to call
5415 * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an
5416 * allocated value (e.g., a string). See bug issue
5417 * https://github.com/nlohmann/json/issues/2865 for more information.
5418 */
5419
5420 template<value_t> struct external_constructor;
5421
5422 template<>
5424 {
5425 template<typename BasicJsonType>
5426 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5427 {
5428 j.m_data.m_value.destroy(j.m_data.m_type);
5429 j.m_data.m_type = value_t::boolean;
5430 j.m_data.m_value = b;
5431 j.assert_invariant();
5432 }
5433 };
5434
5435 template<>
5437 {
5438 template<typename BasicJsonType>
5439 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5440 {
5441 j.m_data.m_value.destroy(j.m_data.m_type);
5442 j.m_data.m_type = value_t::string;
5443 j.m_data.m_value = s;
5444 j.assert_invariant();
5445 }
5446
5447 template<typename BasicJsonType>
5448 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5449 {
5450 j.m_data.m_value.destroy(j.m_data.m_type);
5451 j.m_data.m_type = value_t::string;
5452 j.m_data.m_value = std::move(s);
5453 j.assert_invariant();
5454 }
5455
5456 template < typename BasicJsonType, typename CompatibleStringType,
5457 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
5458 int > = 0 >
5459 static void construct(BasicJsonType& j, const CompatibleStringType& str)
5460 {
5461 j.m_data.m_value.destroy(j.m_data.m_type);
5462 j.m_data.m_type = value_t::string;
5463 j.m_data.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5464 j.assert_invariant();
5465 }
5466 };
5467
5468 template<>
5470 {
5471 template<typename BasicJsonType>
5472 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5473 {
5474 j.m_data.m_value.destroy(j.m_data.m_type);
5475 j.m_data.m_type = value_t::binary;
5476 j.m_data.m_value = typename BasicJsonType::binary_t(b);
5477 j.assert_invariant();
5478 }
5479
5480 template<typename BasicJsonType>
5481 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5482 {
5483 j.m_data.m_value.destroy(j.m_data.m_type);
5484 j.m_data.m_type = value_t::binary;
5485 j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b));
5486 j.assert_invariant();
5487 }
5488 };
5489
5490 template<>
5492 {
5493 template<typename BasicJsonType>
5494 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5495 {
5496 j.m_data.m_value.destroy(j.m_data.m_type);
5497 j.m_data.m_type = value_t::number_float;
5498 j.m_data.m_value = val;
5499 j.assert_invariant();
5500 }
5501 };
5502
5503 template<>
5505 {
5506 template<typename BasicJsonType>
5507 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5508 {
5509 j.m_data.m_value.destroy(j.m_data.m_type);
5510 j.m_data.m_type = value_t::number_unsigned;
5511 j.m_data.m_value = val;
5512 j.assert_invariant();
5513 }
5514 };
5515
5516 template<>
5518 {
5519 template<typename BasicJsonType>
5520 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5521 {
5522 j.m_data.m_value.destroy(j.m_data.m_type);
5523 j.m_data.m_type = value_t::number_integer;
5524 j.m_data.m_value = val;
5525 j.assert_invariant();
5526 }
5527 };
5528
5529 template<>
5531 {
5532 template<typename BasicJsonType>
5533 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5534 {
5535 j.m_data.m_value.destroy(j.m_data.m_type);
5536 j.m_data.m_type = value_t::array;
5537 j.m_data.m_value = arr;
5538 j.set_parents();
5539 j.assert_invariant();
5540 }
5541
5542 template<typename BasicJsonType>
5543 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5544 {
5545 j.m_data.m_value.destroy(j.m_data.m_type);
5546 j.m_data.m_type = value_t::array;
5547 j.m_data.m_value = std::move(arr);
5548 j.set_parents();
5549 j.assert_invariant();
5550 }
5551
5552 template < typename BasicJsonType, typename CompatibleArrayType,
5553 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
5554 int > = 0 >
5555 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5556 {
5557 using std::begin;
5558 using std::end;
5559
5560 j.m_data.m_value.destroy(j.m_data.m_type);
5561 j.m_data.m_type = value_t::array;
5562 j.m_data.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5563 j.set_parents();
5564 j.assert_invariant();
5565 }
5566
5567 template<typename BasicJsonType>
5568 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5569 {
5570 j.m_data.m_value.destroy(j.m_data.m_type);
5571 j.m_data.m_type = value_t::array;
5572 j.m_data.m_value = value_t::array;
5573 j.m_data.m_value.array->reserve(arr.size());
5574 for (const bool x : arr)
5575 {
5576 j.m_data.m_value.array->push_back(x);
5577 j.set_parent(j.m_data.m_value.array->back());
5578 }
5579 j.assert_invariant();
5580 }
5581
5582 template<typename BasicJsonType, typename T,
5584 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5585 {
5586 j.m_data.m_value.destroy(j.m_data.m_type);
5587 j.m_data.m_type = value_t::array;
5588 j.m_data.m_value = value_t::array;
5589 j.m_data.m_value.array->resize(arr.size());
5590 if (arr.size() > 0)
5591 {
5592 std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin());
5593 }
5594 j.set_parents();
5595 j.assert_invariant();
5596 }
5597 };
5598
5599 template<>
5601 {
5602 template<typename BasicJsonType>
5603 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5604 {
5605 j.m_data.m_value.destroy(j.m_data.m_type);
5606 j.m_data.m_type = value_t::object;
5607 j.m_data.m_value = obj;
5608 j.set_parents();
5609 j.assert_invariant();
5610 }
5611
5612 template<typename BasicJsonType>
5613 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5614 {
5615 j.m_data.m_value.destroy(j.m_data.m_type);
5616 j.m_data.m_type = value_t::object;
5617 j.m_data.m_value = std::move(obj);
5618 j.set_parents();
5619 j.assert_invariant();
5620 }
5621
5622 template < typename BasicJsonType, typename CompatibleObjectType,
5623 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
5624 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5625 {
5626 using std::begin;
5627 using std::end;
5628
5629 j.m_data.m_value.destroy(j.m_data.m_type);
5630 j.m_data.m_type = value_t::object;
5631 j.m_data.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5632 j.set_parents();
5633 j.assert_invariant();
5634 }
5635 };
5636
5638 // to_json //
5640
5641 template<typename BasicJsonType, typename T,
5642 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5643 inline void to_json(BasicJsonType& j, T b) noexcept
5644 {
5646 }
5647
5648 template < typename BasicJsonType, typename BoolRef,
5649 enable_if_t <
5650 ((std::is_same<std::vector<bool>::reference, BoolRef>::value
5651 && !std::is_same <std::vector<bool>::reference, typename BasicJsonType::boolean_t&>::value)
5652 || (std::is_same<std::vector<bool>::const_reference, BoolRef>::value
5653 && !std::is_same <detail::uncvref_t<std::vector<bool>::const_reference>,
5654 typename BasicJsonType::boolean_t >::value))
5655 && std::is_convertible<const BoolRef&, typename BasicJsonType::boolean_t>::value, int > = 0 >
5656 inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept
5657 {
5658 external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5659 }
5660
5661 template<typename BasicJsonType, typename CompatibleString,
5662 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5663 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5664 {
5666 }
5667
5668 template<typename BasicJsonType>
5669 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5670 {
5672 }
5673
5674 template<typename BasicJsonType, typename FloatType,
5675 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5676 inline void to_json(BasicJsonType& j, FloatType val) noexcept
5677 {
5678 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5679 }
5680
5681 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5682 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5683 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5684 {
5685 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5686 }
5687
5688 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5689 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5690 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5691 {
5692 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5693 }
5694
5695#if !JSON_DISABLE_ENUM_SERIALIZATION
5696 template<typename BasicJsonType, typename EnumType,
5697 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5698 inline void to_json(BasicJsonType& j, EnumType e) noexcept
5699 {
5700 using underlying_type = typename std::underlying_type<EnumType>::type;
5701 static constexpr value_t integral_value_t = std::is_unsigned<underlying_type>::value ? value_t::number_unsigned : value_t::number_integer;
5702 external_constructor<integral_value_t>::construct(j, static_cast<underlying_type>(e));
5703 }
5704#endif // JSON_DISABLE_ENUM_SERIALIZATION
5705
5706 template<typename BasicJsonType>
5707 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5708 {
5710 }
5711
5712 template < typename BasicJsonType, typename CompatibleArrayType,
5713 enable_if_t < is_compatible_array_type<BasicJsonType,
5714 CompatibleArrayType>::value &&
5715 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value &&
5717 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value &&
5718 !is_basic_json<CompatibleArrayType>::value,
5719 int > = 0 >
5720 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5721 {
5723 }
5724
5725 template<typename BasicJsonType>
5726 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5727 {
5729 }
5730
5731 template<typename BasicJsonType, typename T,
5732 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5733 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5734 {
5736 }
5737
5738 template<typename BasicJsonType>
5739 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5740 {
5742 }
5743
5744 template < typename BasicJsonType, typename CompatibleObjectType,
5745 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value && !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5746 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5747 {
5749 }
5750
5751 template<typename BasicJsonType>
5752 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5753 {
5755 }
5756
5757 template <
5758 typename BasicJsonType, typename T, std::size_t N,
5759 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5760 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5761 int > = 0 >
5762 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5763 {
5765 }
5766
5767 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5768 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5769 {
5770 j = { p.first, p.second };
5771 }
5772
5773 // for https://github.com/nlohmann/json/pull/1134
5774 template<typename BasicJsonType, typename T,
5776 inline void to_json(BasicJsonType& j, const T& b)
5777 {
5778 j = { {b.key(), b.value()} };
5779 }
5780
5781 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5782 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5783 {
5784 j = { std::get<Idx>(t)... };
5785 }
5786
5787 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5788 inline void to_json(BasicJsonType& j, const T& t)
5789 {
5790 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5791 }
5792
5793#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5794 template<typename BasicJsonType>
5795 inline void to_json(BasicJsonType& j, const std_fs::path& p)
5796 {
5797 j = p.string();
5798 }
5799#endif
5800
5802 {
5803 template<typename BasicJsonType, typename T>
5804 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5805 -> decltype(to_json(j, std::forward<T>(val)), void())
5806 {
5807 return to_json(j, std::forward<T>(val));
5808 }
5809 };
5810} // namespace detail
5811
5812#ifndef JSON_HAS_CPP_17
5816namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5817{
5818#endif
5819 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5821#ifndef JSON_HAS_CPP_17
5822} // namespace
5823#endif
5824
5826
5827// #include <nlohmann/detail/meta/identity_tag.hpp>
5828
5829
5831
5833template<typename ValueType, typename>
5835{
5838 template<typename BasicJsonType, typename TargetType = ValueType>
5839 static auto from_json(BasicJsonType&& j, TargetType& val) noexcept(
5840 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5841 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5842 {
5843 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5844 }
5845
5848 template<typename BasicJsonType, typename TargetType = ValueType>
5849 static auto from_json(BasicJsonType&& j) noexcept(
5850 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5851 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5852 {
5853 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5854 }
5855
5858 template<typename BasicJsonType, typename TargetType = ValueType>
5859 static auto to_json(BasicJsonType& j, TargetType&& val) noexcept(
5860 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5861 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5862 {
5863 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5864 }
5865};
5866
5868
5869// #include <nlohmann/byte_container_with_subtype.hpp>
5870// __ _____ _____ _____
5871// __| | __| | | | JSON for Modern C++
5872// | | |__ | | | | | | version 3.11.3
5873// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5874//
5875// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5876// SPDX-License-Identifier: MIT
5877
5878
5879
5880#include <cstdint> // uint8_t, uint64_t
5881#include <tuple> // tie
5882#include <utility> // move
5883
5884// #include <nlohmann/detail/abi_macros.hpp>
5885
5886
5888
5891template<typename BinaryType>
5892class byte_container_with_subtype : public BinaryType
5893{
5894public:
5895 using container_type = BinaryType;
5896 using subtype_type = std::uint64_t;
5897
5900 : container_type()
5901 {}
5902
5905 : container_type(b)
5906 {}
5907
5909 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5910 : container_type(std::move(b))
5911 {}
5912
5915 : container_type(b)
5916 , m_subtype(subtype_)
5917 , m_has_subtype(true)
5918 {}
5919
5921 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5922 : container_type(std::move(b))
5923 , m_subtype(subtype_)
5924 , m_has_subtype(true)
5925 {}
5926
5928 {
5929 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5930 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5931 }
5932
5934 {
5935 return !(rhs == *this);
5936 }
5937
5940 void set_subtype(subtype_type subtype_) noexcept
5941 {
5942 m_subtype = subtype_;
5943 m_has_subtype = true;
5944 }
5945
5948 constexpr subtype_type subtype() const noexcept
5949 {
5950 return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5951 }
5952
5955 constexpr bool has_subtype() const noexcept
5956 {
5957 return m_has_subtype;
5958 }
5959
5962 void clear_subtype() noexcept
5963 {
5964 m_subtype = 0;
5965 m_has_subtype = false;
5966 }
5967
5968private:
5970 bool m_has_subtype = false;
5971};
5972
5974
5975// #include <nlohmann/detail/conversions/from_json.hpp>
5976
5977// #include <nlohmann/detail/conversions/to_json.hpp>
5978
5979// #include <nlohmann/detail/exceptions.hpp>
5980
5981// #include <nlohmann/detail/hash.hpp>
5982// __ _____ _____ _____
5983// __| | __| | | | JSON for Modern C++
5984// | | |__ | | | | | | version 3.11.3
5985// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5986//
5987// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
5988// SPDX-License-Identifier: MIT
5989
5990
5991
5992#include <cstdint> // uint8_t
5993#include <cstddef> // size_t
5994#include <functional> // hash
5995
5996// #include <nlohmann/detail/abi_macros.hpp>
5997
5998// #include <nlohmann/detail/value_t.hpp>
5999
6000
6002namespace detail
6003{
6004
6005 // boost::hash_combine
6006 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
6007 {
6008 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
6009 return seed;
6010 }
6011
6023 template<typename BasicJsonType>
6024 std::size_t hash(const BasicJsonType& j)
6025 {
6026 using string_t = typename BasicJsonType::string_t;
6027 using number_integer_t = typename BasicJsonType::number_integer_t;
6028 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6029 using number_float_t = typename BasicJsonType::number_float_t;
6030
6031 const auto type = static_cast<std::size_t>(j.type());
6032 switch (j.type())
6033 {
6034 case BasicJsonType::value_t::null:
6035 case BasicJsonType::value_t::discarded:
6036 {
6037 return combine(type, 0);
6038 }
6039
6040 case BasicJsonType::value_t::object:
6041 {
6042 auto seed = combine(type, j.size());
6043 for (const auto& element : j.items())
6044 {
6045 const auto h = std::hash<string_t>{}(element.key());
6046 seed = combine(seed, h);
6047 seed = combine(seed, hash(element.value()));
6048 }
6049 return seed;
6050 }
6051
6052 case BasicJsonType::value_t::array:
6053 {
6054 auto seed = combine(type, j.size());
6055 for (const auto& element : j)
6056 {
6057 seed = combine(seed, hash(element));
6058 }
6059 return seed;
6060 }
6061
6062 case BasicJsonType::value_t::string:
6063 {
6064 const auto h = std::hash<string_t>{}(j.template get_ref<const string_t&>());
6065 return combine(type, h);
6066 }
6067
6068 case BasicJsonType::value_t::boolean:
6069 {
6070 const auto h = std::hash<bool>{}(j.template get<bool>());
6071 return combine(type, h);
6072 }
6073
6074 case BasicJsonType::value_t::number_integer:
6075 {
6076 const auto h = std::hash<number_integer_t>{}(j.template get<number_integer_t>());
6077 return combine(type, h);
6078 }
6079
6080 case BasicJsonType::value_t::number_unsigned:
6081 {
6082 const auto h = std::hash<number_unsigned_t>{}(j.template get<number_unsigned_t>());
6083 return combine(type, h);
6084 }
6085
6086 case BasicJsonType::value_t::number_float:
6087 {
6088 const auto h = std::hash<number_float_t>{}(j.template get<number_float_t>());
6089 return combine(type, h);
6090 }
6091
6092 case BasicJsonType::value_t::binary:
6093 {
6094 auto seed = combine(type, j.get_binary().size());
6095 const auto h = std::hash<bool>{}(j.get_binary().has_subtype());
6096 seed = combine(seed, h);
6097 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
6098 for (const auto byte : j.get_binary())
6099 {
6100 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
6101 }
6102 return seed;
6103 }
6104
6105 default: // LCOV_EXCL_LINE
6106 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
6107 return 0; // LCOV_EXCL_LINE
6108 }
6109 }
6110
6111} // namespace detail
6113
6114// #include <nlohmann/detail/input/binary_reader.hpp>
6115// __ _____ _____ _____
6116// __| | __| | | | JSON for Modern C++
6117// | | |__ | | | | | | version 3.11.3
6118// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6119//
6120// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6121// SPDX-License-Identifier: MIT
6122
6123
6124
6125#include <algorithm> // generate_n
6126#include <array> // array
6127#include <cmath> // ldexp
6128#include <cstddef> // size_t
6129#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
6130#include <cstdio> // snprintf
6131#include <cstring> // memcpy
6132#include <iterator> // back_inserter
6133#include <limits> // numeric_limits
6134#include <string> // char_traits, string
6135#include <utility> // make_pair, move
6136#include <vector> // vector
6137
6138// #include <nlohmann/detail/exceptions.hpp>
6139
6140// #include <nlohmann/detail/input/input_adapters.hpp>
6141// __ _____ _____ _____
6142// __| | __| | | | JSON for Modern C++
6143// | | |__ | | | | | | version 3.11.3
6144// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6145//
6146// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6147// SPDX-License-Identifier: MIT
6148
6149
6150
6151#include <array> // array
6152#include <cstddef> // size_t
6153#include <cstring> // strlen
6154#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
6155#include <memory> // shared_ptr, make_shared, addressof
6156#include <numeric> // accumulate
6157#include <string> // string, char_traits
6158#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
6159#include <utility> // pair, declval
6160
6161#ifndef JSON_NO_IO
6162#include <cstdio> // FILE *
6163#include <istream> // istream
6164#endif // JSON_NO_IO
6165
6166// #include <nlohmann/detail/iterators/iterator_traits.hpp>
6167
6168// #include <nlohmann/detail/macro_scope.hpp>
6169
6170// #include <nlohmann/detail/meta/type_traits.hpp>
6171
6172
6174namespace detail
6175{
6176
6179
6181 // input adapters //
6183
6184#ifndef JSON_NO_IO
6190 {
6191 public:
6192 using char_type = char;
6193
6195 explicit file_input_adapter(std::FILE* f) noexcept
6196 : m_file(f)
6197 {
6198 JSON_ASSERT(m_file != nullptr);
6199 }
6200
6201 // make class move-only
6204 file_input_adapter& operator=(const file_input_adapter&) = delete;
6207
6208 std::char_traits<char>::int_type get_character() noexcept
6209 {
6210 return std::fgetc(m_file);
6211 }
6212
6213 private:
6215 std::FILE* m_file;
6216 };
6217
6228 {
6229 public:
6230 using char_type = char;
6231
6233 {
6234 // clear stream flags; we use underlying streambuf I/O, do not
6235 // maintain ifstream flags, except eof
6236 if (is != nullptr)
6237 {
6238 is->clear(is->rdstate() & std::ios::eofbit);
6239 }
6240 }
6241
6242 explicit input_stream_adapter(std::istream& i)
6243 : is(&i), sb(i.rdbuf())
6244 {}
6245
6246 // delete because of pointer members
6250
6252 : is(rhs.is), sb(rhs.sb)
6253 {
6254 rhs.is = nullptr;
6255 rhs.sb = nullptr;
6256 }
6257
6258 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
6259 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
6260 // end up as the same value, e.g. 0xFFFFFFFF.
6261 std::char_traits<char>::int_type get_character()
6262 {
6263 auto res = sb->sbumpc();
6264 // set eof manually, as we don't use the istream interface.
6265 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
6266 {
6267 is->clear(is->rdstate() | std::ios::eofbit);
6268 }
6269 return res;
6270 }
6271
6272 private:
6274 std::istream* is = nullptr;
6275 std::streambuf* sb = nullptr;
6276 };
6277#endif // JSON_NO_IO
6278
6279 // General-purpose iterator-based adapter. It might not be as fast as
6280 // theoretically possible for some containers, but it is extremely versatile.
6281 template<typename IteratorType>
6283 {
6284 public:
6285 using char_type = typename std::iterator_traits<IteratorType>::value_type;
6286
6287 iterator_input_adapter(IteratorType first, IteratorType last)
6288 : current(std::move(first)), end(std::move(last))
6289 {}
6290
6292 {
6294 {
6296 std::advance(current, 1);
6297 return result;
6298 }
6299
6301 }
6302
6303 private:
6304 IteratorType current;
6305 IteratorType end;
6306
6307 template<typename BaseInputAdapter, size_t T>
6309
6310 bool empty() const
6311 {
6312 return current == end;
6313 }
6314 };
6315
6316 template<typename BaseInputAdapter, size_t T>
6318
6319 template<typename BaseInputAdapter>
6320 struct wide_string_input_helper<BaseInputAdapter, 4>
6321 {
6322 // UTF-32
6323 static void fill_buffer(BaseInputAdapter& input,
6324 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6325 size_t& utf8_bytes_index,
6326 size_t& utf8_bytes_filled)
6327 {
6328 utf8_bytes_index = 0;
6329
6330 if (JSON_HEDLEY_UNLIKELY(input.empty()))
6331 {
6332 utf8_bytes[0] = std::char_traits<char>::eof();
6333 utf8_bytes_filled = 1;
6334 }
6335 else
6336 {
6337 // get the current character
6338 const auto wc = input.get_character();
6339
6340 // UTF-32 to UTF-8 encoding
6341 if (wc < 0x80)
6342 {
6343 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6344 utf8_bytes_filled = 1;
6345 }
6346 else if (wc <= 0x7FF)
6347 {
6348 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
6349 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6350 utf8_bytes_filled = 2;
6351 }
6352 else if (wc <= 0xFFFF)
6353 {
6354 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
6355 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6356 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6357 utf8_bytes_filled = 3;
6358 }
6359 else if (wc <= 0x10FFFF)
6360 {
6361 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
6362 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
6363 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6364 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6365 utf8_bytes_filled = 4;
6366 }
6367 else
6368 {
6369 // unknown character
6370 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6371 utf8_bytes_filled = 1;
6372 }
6373 }
6374 }
6375 };
6376
6377 template<typename BaseInputAdapter>
6378 struct wide_string_input_helper<BaseInputAdapter, 2>
6379 {
6380 // UTF-16
6381 static void fill_buffer(BaseInputAdapter& input,
6382 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
6383 size_t& utf8_bytes_index,
6384 size_t& utf8_bytes_filled)
6385 {
6386 utf8_bytes_index = 0;
6387
6388 if (JSON_HEDLEY_UNLIKELY(input.empty()))
6389 {
6390 utf8_bytes[0] = std::char_traits<char>::eof();
6391 utf8_bytes_filled = 1;
6392 }
6393 else
6394 {
6395 // get the current character
6396 const auto wc = input.get_character();
6397
6398 // UTF-16 to UTF-8 encoding
6399 if (wc < 0x80)
6400 {
6401 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6402 utf8_bytes_filled = 1;
6403 }
6404 else if (wc <= 0x7FF)
6405 {
6406 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
6407 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6408 utf8_bytes_filled = 2;
6409 }
6410 else if (0xD800 > wc || wc >= 0xE000)
6411 {
6412 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
6413 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
6414 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
6415 utf8_bytes_filled = 3;
6416 }
6417 else
6418 {
6419 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
6420 {
6421 const auto wc2 = static_cast<unsigned int>(input.get_character());
6422 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6423 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6424 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6425 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6426 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6427 utf8_bytes_filled = 4;
6428 }
6429 else
6430 {
6431 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6432 utf8_bytes_filled = 1;
6433 }
6434 }
6435 }
6436 }
6437 };
6438
6439 // Wraps another input adapter to convert wide character types into individual bytes.
6440 template<typename BaseInputAdapter, typename WideCharType>
6442 {
6443 public:
6444 using char_type = char;
6445
6446 wide_string_input_adapter(BaseInputAdapter base)
6447 : base_adapter(base) {}
6448
6449 typename std::char_traits<char>::int_type get_character() noexcept
6450 {
6451 // check if buffer needs to be filled
6453 {
6455
6458 }
6459
6460 // use buffer
6463 return utf8_bytes[utf8_bytes_index++];
6464 }
6465
6466 private:
6467 BaseInputAdapter base_adapter;
6468
6469 template<size_t T>
6474
6476 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = { {0, 0, 0, 0} };
6477
6479 std::size_t utf8_bytes_index = 0;
6481 std::size_t utf8_bytes_filled = 0;
6482 };
6483
6484 template<typename IteratorType, typename Enable = void>
6486 {
6487 using iterator_type = IteratorType;
6488 using char_type = typename std::iterator_traits<iterator_type>::value_type;
6490
6491 static adapter_type create(IteratorType first, IteratorType last)
6492 {
6493 return adapter_type(std::move(first), std::move(last));
6494 }
6495 };
6496
6497 template<typename T>
6499 {
6500 using value_type = typename std::iterator_traits<T>::value_type;
6501 enum
6502 {
6503 value = sizeof(value_type) > 1
6504 };
6505 };
6506
6507 template<typename IteratorType>
6509 {
6510 using iterator_type = IteratorType;
6511 using char_type = typename std::iterator_traits<iterator_type>::value_type;
6514
6515 static adapter_type create(IteratorType first, IteratorType last)
6516 {
6517 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6518 }
6519 };
6520
6521 // General purpose iterator-based input
6522 template<typename IteratorType>
6524 {
6526 return factory_type::create(first, last);
6527 }
6528
6529 // Convenience shorthand from container to iterator
6530 // Enables ADL on begin(container) and end(container)
6531 // Encloses the using declarations in namespace for not to leak them to outside scope
6532
6534 {
6535
6536 using std::begin;
6537 using std::end;
6538
6539 template<typename ContainerType, typename Enable = void>
6541
6542 template<typename ContainerType>
6543 struct container_input_adapter_factory< ContainerType,
6544 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6545 {
6546 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6547
6548 static adapter_type create(const ContainerType& container)
6549 {
6550 return input_adapter(begin(container), end(container));
6551 }
6552 };
6553
6554 } // namespace container_input_adapter_factory_impl
6555
6556 template<typename ContainerType>
6561
6562#ifndef JSON_NO_IO
6563 // Special cases with fast paths
6564 inline file_input_adapter input_adapter(std::FILE* file)
6565 {
6566 return file_input_adapter(file);
6567 }
6568
6569 inline input_stream_adapter input_adapter(std::istream& stream)
6570 {
6571 return input_stream_adapter(stream);
6572 }
6573
6574 inline input_stream_adapter input_adapter(std::istream&& stream)
6575 {
6576 return input_stream_adapter(stream);
6577 }
6578#endif // JSON_NO_IO
6579
6580 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6581
6582 // Null-delimited strings, and the like.
6583 template < typename CharT,
6584 typename std::enable_if <
6585 std::is_pointer<CharT>::value &&
6586 !std::is_array<CharT>::value&&
6587 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
6588 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6589 int >::type = 0 >
6591 {
6592 auto length = std::strlen(reinterpret_cast<const char*>(b));
6593 const auto* ptr = reinterpret_cast<const char*>(b);
6594 return input_adapter(ptr, ptr + length);
6595 }
6596
6597 template<typename T, std::size_t N>
6598 auto input_adapter(T(&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6599 {
6600 return input_adapter(array, array + N);
6601 }
6602
6603 // This class only handles inputs of input_buffer_adapter type.
6604 // It's required so that expressions like {ptr, len} can be implicitly cast
6605 // to the correct adapter.
6607 {
6608 public:
6609 template < typename CharT,
6610 typename std::enable_if <
6611 std::is_pointer<CharT>::value&&
6612 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
6613 sizeof(typename std::remove_pointer<CharT>::type) == 1,
6614 int >::type = 0 >
6615 span_input_adapter(CharT b, std::size_t l)
6616 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6617
6618 template<class IteratorType,
6619 typename std::enable_if<
6620 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6621 int>::type = 0>
6622 span_input_adapter(IteratorType first, IteratorType last)
6623 : ia(input_adapter(first, last)) {}
6624
6626 {
6627 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6628 }
6629
6630 private:
6632 };
6633
6634} // namespace detail
6636
6637// #include <nlohmann/detail/input/json_sax.hpp>
6638// __ _____ _____ _____
6639// __| | __| | | | JSON for Modern C++
6640// | | |__ | | | | | | version 3.11.3
6641// |_____|_____|_____|_|___| https://github.com/nlohmann/json
6642//
6643// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
6644// SPDX-License-Identifier: MIT
6645
6646
6647
6648#include <cstddef>
6649#include <string> // string
6650#include <utility> // move
6651#include <vector> // vector
6652
6653// #include <nlohmann/detail/exceptions.hpp>
6654
6655// #include <nlohmann/detail/macro_scope.hpp>
6656
6657// #include <nlohmann/detail/string_concat.hpp>
6658
6659
6661
6670template<typename BasicJsonType>
6672{
6673 using number_integer_t = typename BasicJsonType::number_integer_t;
6674 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6675 using number_float_t = typename BasicJsonType::number_float_t;
6676 using string_t = typename BasicJsonType::string_t;
6677 using binary_t = typename BasicJsonType::binary_t;
6678
6683 virtual bool null() = 0;
6684
6690 virtual bool boolean(bool val) = 0;
6691
6697 virtual bool number_integer(number_integer_t val) = 0;
6698
6704 virtual bool number_unsigned(number_unsigned_t val) = 0;
6705
6712 virtual bool number_float(number_float_t val, const string_t& s) = 0;
6713
6720 virtual bool string(string_t& val) = 0;
6721
6728 virtual bool binary(binary_t& val) = 0;
6729
6736 virtual bool start_object(std::size_t elements) = 0;
6737
6744 virtual bool key(string_t& val) = 0;
6745
6750 virtual bool end_object() = 0;
6751
6758 virtual bool start_array(std::size_t elements) = 0;
6759
6764 virtual bool end_array() = 0;
6765
6773 virtual bool parse_error(std::size_t position,
6774 const std::string& last_token,
6775 const detail::exception& ex) = 0;
6776
6777 json_sax() = default;
6778 json_sax(const json_sax&) = default;
6779 json_sax(json_sax&&) noexcept = default;
6780 json_sax& operator=(const json_sax&) = default;
6781 json_sax& operator=(json_sax&&) noexcept = default;
6782 virtual ~json_sax() = default;
6783};
6784
6785namespace detail
6786{
6800 template<typename BasicJsonType>
6802 {
6803 public:
6804 using number_integer_t = typename BasicJsonType::number_integer_t;
6805 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6806 using number_float_t = typename BasicJsonType::number_float_t;
6807 using string_t = typename BasicJsonType::string_t;
6808 using binary_t = typename BasicJsonType::binary_t;
6809
6815 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6816 : root(r), allow_exceptions(allow_exceptions_)
6817 {}
6818
6819 // make class move-only
6821 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6823 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6825
6826 bool null()
6827 {
6828 handle_value(nullptr);
6829 return true;
6830 }
6831
6832 bool boolean(bool val)
6833 {
6834 handle_value(val);
6835 return true;
6836 }
6837
6839 {
6840 handle_value(val);
6841 return true;
6842 }
6843
6845 {
6846 handle_value(val);
6847 return true;
6848 }
6849
6850 bool number_float(number_float_t val, const string_t& /*unused*/)
6851 {
6852 handle_value(val);
6853 return true;
6854 }
6855
6856 bool string(string_t& val)
6857 {
6858 handle_value(val);
6859 return true;
6860 }
6861
6862 bool binary(binary_t& val)
6863 {
6864 handle_value(std::move(val));
6865 return true;
6866 }
6867
6868 bool start_object(std::size_t len)
6869 {
6870 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6871
6872 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6873 {
6874 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6875 }
6876
6877 return true;
6878 }
6879
6880 bool key(string_t& val)
6881 {
6882 JSON_ASSERT(!ref_stack.empty());
6883 JSON_ASSERT(ref_stack.back()->is_object());
6884
6885 // add null at given key and store the reference for later
6886 object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val));
6887 return true;
6888 }
6889
6891 {
6892 JSON_ASSERT(!ref_stack.empty());
6893 JSON_ASSERT(ref_stack.back()->is_object());
6894
6895 ref_stack.back()->set_parents();
6896 ref_stack.pop_back();
6897 return true;
6898 }
6899
6900 bool start_array(std::size_t len)
6901 {
6902 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6903
6904 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6905 {
6906 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6907 }
6908
6909 return true;
6910 }
6911
6913 {
6914 JSON_ASSERT(!ref_stack.empty());
6915 JSON_ASSERT(ref_stack.back()->is_array());
6916
6917 ref_stack.back()->set_parents();
6918 ref_stack.pop_back();
6919 return true;
6920 }
6921
6922 template<class Exception>
6923 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6924 const Exception& ex)
6925 {
6926 errored = true;
6927 static_cast<void>(ex);
6928 if (allow_exceptions)
6929 {
6930 JSON_THROW(ex);
6931 }
6932 return false;
6933 }
6934
6935 constexpr bool is_errored() const
6936 {
6937 return errored;
6938 }
6939
6940 private:
6947 template<typename Value>
6949 BasicJsonType* handle_value(Value&& v)
6950 {
6951 if (ref_stack.empty())
6952 {
6953 root = BasicJsonType(std::forward<Value>(v));
6954 return &root;
6955 }
6956
6957 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6958
6959 if (ref_stack.back()->is_array())
6960 {
6961 ref_stack.back()->m_data.m_value.array->emplace_back(std::forward<Value>(v));
6962 return &(ref_stack.back()->m_data.m_value.array->back());
6963 }
6964
6965 JSON_ASSERT(ref_stack.back()->is_object());
6967 *object_element = BasicJsonType(std::forward<Value>(v));
6968 return object_element;
6969 }
6970
6972 BasicJsonType& root;
6974 std::vector<BasicJsonType*> ref_stack{};
6976 BasicJsonType* object_element = nullptr;
6978 bool errored = false;
6980 const bool allow_exceptions = true;
6981 };
6982
6983 template<typename BasicJsonType>
6985 {
6986 public:
6987 using number_integer_t = typename BasicJsonType::number_integer_t;
6988 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6989 using number_float_t = typename BasicJsonType::number_float_t;
6990 using string_t = typename BasicJsonType::string_t;
6991 using binary_t = typename BasicJsonType::binary_t;
6992 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6993 using parse_event_t = typename BasicJsonType::parse_event_t;
6994
6996 const parser_callback_t cb,
6997 const bool allow_exceptions_ = true)
6998 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6999 {
7000 keep_stack.push_back(true);
7001 }
7002
7003 // make class move-only
7005 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7007 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7009
7010 bool null()
7011 {
7012 handle_value(nullptr);
7013 return true;
7014 }
7015
7016 bool boolean(bool val)
7017 {
7018 handle_value(val);
7019 return true;
7020 }
7021
7023 {
7024 handle_value(val);
7025 return true;
7026 }
7027
7029 {
7030 handle_value(val);
7031 return true;
7032 }
7033
7034 bool number_float(number_float_t val, const string_t& /*unused*/)
7035 {
7036 handle_value(val);
7037 return true;
7038 }
7039
7040 bool string(string_t& val)
7041 {
7042 handle_value(val);
7043 return true;
7044 }
7045
7046 bool binary(binary_t& val)
7047 {
7048 handle_value(std::move(val));
7049 return true;
7050 }
7051
7052 bool start_object(std::size_t len)
7053 {
7054 // check callback for object start
7055 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
7056 keep_stack.push_back(keep);
7057
7058 auto val = handle_value(BasicJsonType::value_t::object, true);
7059 ref_stack.push_back(val.second);
7060
7061 // check object limit
7062 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7063 {
7064 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
7065 }
7066
7067 return true;
7068 }
7069
7070 bool key(string_t& val)
7071 {
7072 BasicJsonType k = BasicJsonType(val);
7073
7074 // check callback for key
7075 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
7076 key_keep_stack.push_back(keep);
7077
7078 // add discarded value at given key and store the reference for later
7079 if (keep && ref_stack.back())
7080 {
7081 object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded);
7082 }
7083
7084 return true;
7085 }
7086
7088 {
7089 if (ref_stack.back())
7090 {
7091 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
7092 {
7093 // discard object
7094 *ref_stack.back() = discarded;
7095 }
7096 else
7097 {
7098 ref_stack.back()->set_parents();
7099 }
7100 }
7101
7102 JSON_ASSERT(!ref_stack.empty());
7103 JSON_ASSERT(!keep_stack.empty());
7104 ref_stack.pop_back();
7105 keep_stack.pop_back();
7106
7107 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
7108 {
7109 // remove discarded value
7110 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
7111 {
7112 if (it->is_discarded())
7113 {
7114 ref_stack.back()->erase(it);
7115 break;
7116 }
7117 }
7118 }
7119
7120 return true;
7121 }
7122
7123 bool start_array(std::size_t len)
7124 {
7125 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
7126 keep_stack.push_back(keep);
7127
7128 auto val = handle_value(BasicJsonType::value_t::array, true);
7129 ref_stack.push_back(val.second);
7130
7131 // check array limit
7132 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
7133 {
7134 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
7135 }
7136
7137 return true;
7138 }
7139
7141 {
7142 bool keep = true;
7143
7144 if (ref_stack.back())
7145 {
7146 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
7147 if (keep)
7148 {
7149 ref_stack.back()->set_parents();
7150 }
7151 else
7152 {
7153 // discard array
7154 *ref_stack.back() = discarded;
7155 }
7156 }
7157
7158 JSON_ASSERT(!ref_stack.empty());
7159 JSON_ASSERT(!keep_stack.empty());
7160 ref_stack.pop_back();
7161 keep_stack.pop_back();
7162
7163 // remove discarded value
7164 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
7165 {
7166 ref_stack.back()->m_data.m_value.array->pop_back();
7167 }
7168
7169 return true;
7170 }
7171
7172 template<class Exception>
7173 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
7174 const Exception& ex)
7175 {
7176 errored = true;
7177 static_cast<void>(ex);
7178 if (allow_exceptions)
7179 {
7180 JSON_THROW(ex);
7181 }
7182 return false;
7183 }
7184
7185 constexpr bool is_errored() const
7186 {
7187 return errored;
7188 }
7189
7190 private:
7206 template<typename Value>
7207 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
7208 {
7209 JSON_ASSERT(!keep_stack.empty());
7210
7211 // do not handle this value if we know it would be added to a discarded
7212 // container
7213 if (!keep_stack.back())
7214 {
7215 return { false, nullptr };
7216 }
7217
7218 // create value
7219 auto value = BasicJsonType(std::forward<Value>(v));
7220
7221 // check callback
7222 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
7223
7224 // do not handle this value if we just learnt it shall be discarded
7225 if (!keep)
7226 {
7227 return { false, nullptr };
7228 }
7229
7230 if (ref_stack.empty())
7231 {
7232 root = std::move(value);
7233 return { true, &root };
7234 }
7235
7236 // skip this value if we already decided to skip the parent
7237 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
7238 if (!ref_stack.back())
7239 {
7240 return { false, nullptr };
7241 }
7242
7243 // we now only expect arrays and objects
7244 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
7245
7246 // array
7247 if (ref_stack.back()->is_array())
7248 {
7249 ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value));
7250 return { true, &(ref_stack.back()->m_data.m_value.array->back()) };
7251 }
7252
7253 // object
7254 JSON_ASSERT(ref_stack.back()->is_object());
7255 // check if we should store an element for the current key
7256 JSON_ASSERT(!key_keep_stack.empty());
7257 const bool store_element = key_keep_stack.back();
7258 key_keep_stack.pop_back();
7259
7260 if (!store_element)
7261 {
7262 return { false, nullptr };
7263 }
7264
7266 *object_element = std::move(value);
7267 return { true, object_element };
7268 }
7269
7271 BasicJsonType& root;
7273 std::vector<BasicJsonType*> ref_stack{};
7275 std::vector<bool> keep_stack{}; // NOLINT(readability-redundant-member-init)
7277 std::vector<bool> key_keep_stack{}; // NOLINT(readability-redundant-member-init)
7279 BasicJsonType* object_element = nullptr;
7281 bool errored = false;
7285 const bool allow_exceptions = true;
7287 BasicJsonType discarded = BasicJsonType::value_t::discarded;
7288 };
7289
7290 template<typename BasicJsonType>
7292 {
7293 public:
7294 using number_integer_t = typename BasicJsonType::number_integer_t;
7295 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7296 using number_float_t = typename BasicJsonType::number_float_t;
7297 using string_t = typename BasicJsonType::string_t;
7298 using binary_t = typename BasicJsonType::binary_t;
7299
7300 bool null()
7301 {
7302 return true;
7303 }
7304
7305 bool boolean(bool /*unused*/)
7306 {
7307 return true;
7308 }
7309
7311 {
7312 return true;
7313 }
7314
7316 {
7317 return true;
7318 }
7319
7320 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
7321 {
7322 return true;
7323 }
7324
7325 bool string(string_t& /*unused*/)
7326 {
7327 return true;
7328 }
7329
7330 bool binary(binary_t& /*unused*/)
7331 {
7332 return true;
7333 }
7334
7335 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7336 {
7337 return true;
7338 }
7339
7340 bool key(string_t& /*unused*/)
7341 {
7342 return true;
7343 }
7344
7346 {
7347 return true;
7348 }
7349
7350 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
7351 {
7352 return true;
7353 }
7354
7356 {
7357 return true;
7358 }
7359
7360 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
7361 {
7362 return false;
7363 }
7364 };
7365
7366} // namespace detail
7368
7369// #include <nlohmann/detail/input/lexer.hpp>
7370// __ _____ _____ _____
7371// __| | __| | | | JSON for Modern C++
7372// | | |__ | | | | | | version 3.11.3
7373// |_____|_____|_____|_|___| https://github.com/nlohmann/json
7374//
7375// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
7376// SPDX-License-Identifier: MIT
7377
7378
7379
7380#include <array> // array
7381#include <clocale> // localeconv
7382#include <cstddef> // size_t
7383#include <cstdio> // snprintf
7384#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
7385#include <initializer_list> // initializer_list
7386#include <string> // char_traits, string
7387#include <utility> // move
7388#include <vector> // vector
7389
7390// #include <nlohmann/detail/input/input_adapters.hpp>
7391
7392// #include <nlohmann/detail/input/position_t.hpp>
7393
7394// #include <nlohmann/detail/macro_scope.hpp>
7395
7396// #include <nlohmann/detail/meta/type_traits.hpp>
7397
7398
7400namespace detail
7401{
7402
7404 // lexer //
7406
7407 template<typename BasicJsonType>
7409 {
7410 public:
7432
7436 static const char* token_type_name(const token_type t) noexcept
7437 {
7438 switch (t)
7439 {
7441 return "<uninitialized>";
7443 return "true literal";
7445 return "false literal";
7447 return "null literal";
7449 return "string literal";
7453 return "number literal";
7455 return "'['";
7457 return "'{'";
7459 return "']'";
7461 return "'}'";
7463 return "':'";
7465 return "','";
7467 return "<parse error>";
7469 return "end of input";
7471 return "'[', '{', or a literal";
7472 // LCOV_EXCL_START
7473 default: // catch non-enum values
7474 return "unknown token";
7475 // LCOV_EXCL_STOP
7476 }
7477 }
7478 };
7479
7484 template<typename BasicJsonType, typename InputAdapterType>
7485 class lexer : public lexer_base<BasicJsonType>
7486 {
7487 using number_integer_t = typename BasicJsonType::number_integer_t;
7488 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7489 using number_float_t = typename BasicJsonType::number_float_t;
7490 using string_t = typename BasicJsonType::string_t;
7491 using char_type = typename InputAdapterType::char_type;
7493
7494 public:
7496
7497 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7498 : ia(std::move(adapter))
7499 , ignore_comments(ignore_comments_)
7501 {}
7502
7503 // delete because of pointer members
7504 lexer(const lexer&) = delete;
7505 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7506 lexer& operator=(lexer&) = delete;
7507 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7508 ~lexer() = default;
7509
7510 private:
7512 // locales
7514
7517 static char get_decimal_point() noexcept
7518 {
7519 const auto* loc = localeconv();
7520 JSON_ASSERT(loc != nullptr);
7521 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7522 }
7523
7525 // scan functions
7527
7544 {
7545 // this function only makes sense after reading `\u`
7546 JSON_ASSERT(current == 'u');
7547 int codepoint = 0;
7548
7549 const auto factors = { 12u, 8u, 4u, 0u };
7550 for (const auto factor : factors)
7551 {
7552 get();
7553
7554 if (current >= '0' && current <= '9')
7555 {
7556 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7557 }
7558 else if (current >= 'A' && current <= 'F')
7559 {
7560 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7561 }
7562 else if (current >= 'a' && current <= 'f')
7563 {
7564 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7565 }
7566 else
7567 {
7568 return -1;
7569 }
7570 }
7571
7572 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7573 return codepoint;
7574 }
7575
7591 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7592 {
7593 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7594 add(current);
7595
7596 for (auto range = ranges.begin(); range != ranges.end(); ++range)
7597 {
7598 get();
7599 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions)
7600 {
7601 add(current);
7602 }
7603 else
7604 {
7605 error_message = "invalid string: ill-formed UTF-8 byte";
7606 return false;
7607 }
7608 }
7609
7610 return true;
7611 }
7612
7629 {
7630 // reset token_buffer (ignore opening quote)
7631 reset();
7632
7633 // we entered the function by reading an open quote
7634 JSON_ASSERT(current == '\"');
7635
7636 while (true)
7637 {
7638 // get next character
7639 switch (get())
7640 {
7641 // end of file while parsing string
7643 {
7644 error_message = "invalid string: missing closing quote";
7645 return token_type::parse_error;
7646 }
7647
7648 // closing quote
7649 case '\"':
7650 {
7651 return token_type::value_string;
7652 }
7653
7654 // escapes
7655 case '\\':
7656 {
7657 switch (get())
7658 {
7659 // quotation mark
7660 case '\"':
7661 add('\"');
7662 break;
7663 // reverse solidus
7664 case '\\':
7665 add('\\');
7666 break;
7667 // solidus
7668 case '/':
7669 add('/');
7670 break;
7671 // backspace
7672 case 'b':
7673 add('\b');
7674 break;
7675 // form feed
7676 case 'f':
7677 add('\f');
7678 break;
7679 // line feed
7680 case 'n':
7681 add('\n');
7682 break;
7683 // carriage return
7684 case 'r':
7685 add('\r');
7686 break;
7687 // tab
7688 case 't':
7689 add('\t');
7690 break;
7691
7692 // unicode escapes
7693 case 'u':
7694 {
7695 const int codepoint1 = get_codepoint();
7696 int codepoint = codepoint1; // start with codepoint1
7697
7698 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7699 {
7700 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7701 return token_type::parse_error;
7702 }
7703
7704 // check if code point is a high surrogate
7705 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7706 {
7707 // expect next \uxxxx entry
7708 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7709 {
7710 const int codepoint2 = get_codepoint();
7711
7712 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7713 {
7714 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7715 return token_type::parse_error;
7716 }
7717
7718 // check if codepoint2 is a low surrogate
7719 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7720 {
7721 // overwrite codepoint
7722 codepoint = static_cast<int>(
7723 // high surrogate occupies the most significant 22 bits
7724 (static_cast<unsigned int>(codepoint1) << 10u)
7725 // low surrogate occupies the least significant 15 bits
7726 + static_cast<unsigned int>(codepoint2)
7727 // there is still the 0xD800, 0xDC00 and 0x10000 noise
7728 // in the result, so we have to subtract with:
7729 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7730 -0x35FDC00u);
7731 }
7732 else
7733 {
7734 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7735 return token_type::parse_error;
7736 }
7737 }
7738 else
7739 {
7740 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7741 return token_type::parse_error;
7742 }
7743 }
7744 else
7745 {
7746 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7747 {
7748 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7749 return token_type::parse_error;
7750 }
7751 }
7752
7753 // result of the above calculation yields a proper codepoint
7754 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7755
7756 // translate codepoint into bytes
7757 if (codepoint < 0x80)
7758 {
7759 // 1-byte characters: 0xxxxxxx (ASCII)
7760 add(static_cast<char_int_type>(codepoint));
7761 }
7762 else if (codepoint <= 0x7FF)
7763 {
7764 // 2-byte characters: 110xxxxx 10xxxxxx
7765 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7766 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7767 }
7768 else if (codepoint <= 0xFFFF)
7769 {
7770 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7771 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7772 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7773 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7774 }
7775 else
7776 {
7777 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7778 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7779 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7780 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7781 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7782 }
7783
7784 break;
7785 }
7786
7787 // other characters after escape
7788 default:
7789 error_message = "invalid string: forbidden character after backslash";
7790 return token_type::parse_error;
7791 }
7792
7793 break;
7794 }
7795
7796 // invalid control characters
7797 case 0x00:
7798 {
7799 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7800 return token_type::parse_error;
7801 }
7802
7803 case 0x01:
7804 {
7805 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7806 return token_type::parse_error;
7807 }
7808
7809 case 0x02:
7810 {
7811 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7812 return token_type::parse_error;
7813 }
7814
7815 case 0x03:
7816 {
7817 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7818 return token_type::parse_error;
7819 }
7820
7821 case 0x04:
7822 {
7823 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7824 return token_type::parse_error;
7825 }
7826
7827 case 0x05:
7828 {
7829 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7830 return token_type::parse_error;
7831 }
7832
7833 case 0x06:
7834 {
7835 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7836 return token_type::parse_error;
7837 }
7838
7839 case 0x07:
7840 {
7841 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7842 return token_type::parse_error;
7843 }
7844
7845 case 0x08:
7846 {
7847 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7848 return token_type::parse_error;
7849 }
7850
7851 case 0x09:
7852 {
7853 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7854 return token_type::parse_error;
7855 }
7856
7857 case 0x0A:
7858 {
7859 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7860 return token_type::parse_error;
7861 }
7862
7863 case 0x0B:
7864 {
7865 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7866 return token_type::parse_error;
7867 }
7868
7869 case 0x0C:
7870 {
7871 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7872 return token_type::parse_error;
7873 }
7874
7875 case 0x0D:
7876 {
7877 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7878 return token_type::parse_error;
7879 }
7880
7881 case 0x0E:
7882 {
7883 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7884 return token_type::parse_error;
7885 }
7886
7887 case 0x0F:
7888 {
7889 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7890 return token_type::parse_error;
7891 }
7892
7893 case 0x10:
7894 {
7895 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7896 return token_type::parse_error;
7897 }
7898
7899 case 0x11:
7900 {
7901 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7902 return token_type::parse_error;
7903 }
7904
7905 case 0x12:
7906 {
7907 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7908 return token_type::parse_error;
7909 }
7910
7911 case 0x13:
7912 {
7913 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7914 return token_type::parse_error;
7915 }
7916
7917 case 0x14:
7918 {
7919 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7920 return token_type::parse_error;
7921 }
7922
7923 case 0x15:
7924 {
7925 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7926 return token_type::parse_error;
7927 }
7928
7929 case 0x16:
7930 {
7931 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7932 return token_type::parse_error;
7933 }
7934
7935 case 0x17:
7936 {
7937 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7938 return token_type::parse_error;
7939 }
7940
7941 case 0x18:
7942 {
7943 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7944 return token_type::parse_error;
7945 }
7946
7947 case 0x19:
7948 {
7949 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7950 return token_type::parse_error;
7951 }
7952
7953 case 0x1A:
7954 {
7955 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7956 return token_type::parse_error;
7957 }
7958
7959 case 0x1B:
7960 {
7961 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7962 return token_type::parse_error;
7963 }
7964
7965 case 0x1C:
7966 {
7967 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7968 return token_type::parse_error;
7969 }
7970
7971 case 0x1D:
7972 {
7973 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7974 return token_type::parse_error;
7975 }
7976
7977 case 0x1E:
7978 {
7979 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7980 return token_type::parse_error;
7981 }
7982
7983 case 0x1F:
7984 {
7985 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7986 return token_type::parse_error;
7987 }
7988
7989 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7990 case 0x20:
7991 case 0x21:
7992 case 0x23:
7993 case 0x24:
7994 case 0x25:
7995 case 0x26:
7996 case 0x27:
7997 case 0x28:
7998 case 0x29:
7999 case 0x2A:
8000 case 0x2B:
8001 case 0x2C:
8002 case 0x2D:
8003 case 0x2E:
8004 case 0x2F:
8005 case 0x30:
8006 case 0x31:
8007 case 0x32:
8008 case 0x33:
8009 case 0x34:
8010 case 0x35:
8011 case 0x36:
8012 case 0x37:
8013 case 0x38:
8014 case 0x39:
8015 case 0x3A:
8016 case 0x3B:
8017 case 0x3C:
8018 case 0x3D:
8019 case 0x3E:
8020 case 0x3F:
8021 case 0x40:
8022 case 0x41:
8023 case 0x42:
8024 case 0x43:
8025 case 0x44:
8026 case 0x45:
8027 case 0x46:
8028 case 0x47:
8029 case 0x48:
8030 case 0x49:
8031 case 0x4A:
8032 case 0x4B:
8033 case 0x4C:
8034 case 0x4D:
8035 case 0x4E:
8036 case 0x4F:
8037 case 0x50:
8038 case 0x51:
8039 case 0x52:
8040 case 0x53:
8041 case 0x54:
8042 case 0x55:
8043 case 0x56:
8044 case 0x57:
8045 case 0x58:
8046 case 0x59:
8047 case 0x5A:
8048 case 0x5B:
8049 case 0x5D:
8050 case 0x5E:
8051 case 0x5F:
8052 case 0x60:
8053 case 0x61:
8054 case 0x62:
8055 case 0x63:
8056 case 0x64:
8057 case 0x65:
8058 case 0x66:
8059 case 0x67:
8060 case 0x68:
8061 case 0x69:
8062 case 0x6A:
8063 case 0x6B:
8064 case 0x6C:
8065 case 0x6D:
8066 case 0x6E:
8067 case 0x6F:
8068 case 0x70:
8069 case 0x71:
8070 case 0x72:
8071 case 0x73:
8072 case 0x74:
8073 case 0x75:
8074 case 0x76:
8075 case 0x77:
8076 case 0x78:
8077 case 0x79:
8078 case 0x7A:
8079 case 0x7B:
8080 case 0x7C:
8081 case 0x7D:
8082 case 0x7E:
8083 case 0x7F:
8084 {
8085 add(current);
8086 break;
8087 }
8088
8089 // U+0080..U+07FF: bytes C2..DF 80..BF
8090 case 0xC2:
8091 case 0xC3:
8092 case 0xC4:
8093 case 0xC5:
8094 case 0xC6:
8095 case 0xC7:
8096 case 0xC8:
8097 case 0xC9:
8098 case 0xCA:
8099 case 0xCB:
8100 case 0xCC:
8101 case 0xCD:
8102 case 0xCE:
8103 case 0xCF:
8104 case 0xD0:
8105 case 0xD1:
8106 case 0xD2:
8107 case 0xD3:
8108 case 0xD4:
8109 case 0xD5:
8110 case 0xD6:
8111 case 0xD7:
8112 case 0xD8:
8113 case 0xD9:
8114 case 0xDA:
8115 case 0xDB:
8116 case 0xDC:
8117 case 0xDD:
8118 case 0xDE:
8119 case 0xDF:
8120 {
8121 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({ 0x80, 0xBF })))
8122 {
8123 return token_type::parse_error;
8124 }
8125 break;
8126 }
8127
8128 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8129 case 0xE0:
8130 {
8131 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0xA0, 0xBF, 0x80, 0xBF }))))
8132 {
8133 return token_type::parse_error;
8134 }
8135 break;
8136 }
8137
8138 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8139 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8140 case 0xE1:
8141 case 0xE2:
8142 case 0xE3:
8143 case 0xE4:
8144 case 0xE5:
8145 case 0xE6:
8146 case 0xE7:
8147 case 0xE8:
8148 case 0xE9:
8149 case 0xEA:
8150 case 0xEB:
8151 case 0xEC:
8152 case 0xEE:
8153 case 0xEF:
8154 {
8155 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF }))))
8156 {
8157 return token_type::parse_error;
8158 }
8159 break;
8160 }
8161
8162 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8163 case 0xED:
8164 {
8165 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x9F, 0x80, 0xBF }))))
8166 {
8167 return token_type::parse_error;
8168 }
8169 break;
8170 }
8171
8172 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8173 case 0xF0:
8174 {
8175 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
8176 {
8177 return token_type::parse_error;
8178 }
8179 break;
8180 }
8181
8182 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8183 case 0xF1:
8184 case 0xF2:
8185 case 0xF3:
8186 {
8187 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
8188 {
8189 return token_type::parse_error;
8190 }
8191 break;
8192 }
8193
8194 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8195 case 0xF4:
8196 {
8197 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF }))))
8198 {
8199 return token_type::parse_error;
8200 }
8201 break;
8202 }
8203
8204 // remaining bytes (80..C1 and F5..FF) are ill-formed
8205 default:
8206 {
8207 error_message = "invalid string: ill-formed UTF-8 byte";
8208 return token_type::parse_error;
8209 }
8210 }
8211 }
8212 }
8213
8219 {
8220 switch (get())
8221 {
8222 // single-line comments skip input until a newline or EOF is read
8223 case '/':
8224 {
8225 while (true)
8226 {
8227 switch (get())
8228 {
8229 case '\n':
8230 case '\r':
8232 case '\0':
8233 return true;
8234
8235 default:
8236 break;
8237 }
8238 }
8239 }
8240
8241 // multi-line comments skip input until */ is read
8242 case '*':
8243 {
8244 while (true)
8245 {
8246 switch (get())
8247 {
8249 case '\0':
8250 {
8251 error_message = "invalid comment; missing closing '*/'";
8252 return false;
8253 }
8254
8255 case '*':
8256 {
8257 switch (get())
8258 {
8259 case '/':
8260 return true;
8261
8262 default:
8263 {
8264 unget();
8265 continue;
8266 }
8267 }
8268 }
8269
8270 default:
8271 continue;
8272 }
8273 }
8274 }
8275
8276 // unexpected character after reading '/'
8277 default:
8278 {
8279 error_message = "invalid comment; expecting '/' or '*' after '/'";
8280 return false;
8281 }
8282 }
8283 }
8284
8286 static void strtof(float& f, const char* str, char** endptr) noexcept
8287 {
8288 f = std::strtof(str, endptr);
8289 }
8290
8292 static void strtof(double& f, const char* str, char** endptr) noexcept
8293 {
8294 f = std::strtod(str, endptr);
8295 }
8296
8298 static void strtof(long double& f, const char* str, char** endptr) noexcept
8299 {
8300 f = std::strtold(str, endptr);
8301 }
8302
8343 token_type scan_number() // lgtm [cpp/use-of-goto]
8344 {
8345 // reset token_buffer to store the number's bytes
8346 reset();
8347
8348 // the type of the parsed number; initially set to unsigned; will be
8349 // changed if minus sign, decimal point or exponent is read
8350 token_type number_type = token_type::value_unsigned;
8351
8352 // state (init): we just found out we need to scan a number
8353 switch (current)
8354 {
8355 case '-':
8356 {
8357 add(current);
8358 goto scan_number_minus;
8359 }
8360
8361 case '0':
8362 {
8363 add(current);
8364 goto scan_number_zero;
8365 }
8366
8367 case '1':
8368 case '2':
8369 case '3':
8370 case '4':
8371 case '5':
8372 case '6':
8373 case '7':
8374 case '8':
8375 case '9':
8376 {
8377 add(current);
8378 goto scan_number_any1;
8379 }
8380
8381 // all other characters are rejected outside scan_number()
8382 default: // LCOV_EXCL_LINE
8383 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8384 }
8385
8386 scan_number_minus:
8387 // state: we just parsed a leading minus sign
8388 number_type = token_type::value_integer;
8389 switch (get())
8390 {
8391 case '0':
8392 {
8393 add(current);
8394 goto scan_number_zero;
8395 }
8396
8397 case '1':
8398 case '2':
8399 case '3':
8400 case '4':
8401 case '5':
8402 case '6':
8403 case '7':
8404 case '8':
8405 case '9':
8406 {
8407 add(current);
8408 goto scan_number_any1;
8409 }
8410
8411 default:
8412 {
8413 error_message = "invalid number; expected digit after '-'";
8414 return token_type::parse_error;
8415 }
8416 }
8417
8418 scan_number_zero:
8419 // state: we just parse a zero (maybe with a leading minus sign)
8420 switch (get())
8421 {
8422 case '.':
8423 {
8425 goto scan_number_decimal1;
8426 }
8427
8428 case 'e':
8429 case 'E':
8430 {
8431 add(current);
8432 goto scan_number_exponent;
8433 }
8434
8435 default:
8436 goto scan_number_done;
8437 }
8438
8439 scan_number_any1:
8440 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8441 switch (get())
8442 {
8443 case '0':
8444 case '1':
8445 case '2':
8446 case '3':
8447 case '4':
8448 case '5':
8449 case '6':
8450 case '7':
8451 case '8':
8452 case '9':
8453 {
8454 add(current);
8455 goto scan_number_any1;
8456 }
8457
8458 case '.':
8459 {
8461 goto scan_number_decimal1;
8462 }
8463
8464 case 'e':
8465 case 'E':
8466 {
8467 add(current);
8468 goto scan_number_exponent;
8469 }
8470
8471 default:
8472 goto scan_number_done;
8473 }
8474
8475 scan_number_decimal1:
8476 // state: we just parsed a decimal point
8477 number_type = token_type::value_float;
8478 switch (get())
8479 {
8480 case '0':
8481 case '1':
8482 case '2':
8483 case '3':
8484 case '4':
8485 case '5':
8486 case '6':
8487 case '7':
8488 case '8':
8489 case '9':
8490 {
8491 add(current);
8492 goto scan_number_decimal2;
8493 }
8494
8495 default:
8496 {
8497 error_message = "invalid number; expected digit after '.'";
8498 return token_type::parse_error;
8499 }
8500 }
8501
8502 scan_number_decimal2:
8503 // we just parsed at least one number after a decimal point
8504 switch (get())
8505 {
8506 case '0':
8507 case '1':
8508 case '2':
8509 case '3':
8510 case '4':
8511 case '5':
8512 case '6':
8513 case '7':
8514 case '8':
8515 case '9':
8516 {
8517 add(current);
8518 goto scan_number_decimal2;
8519 }
8520
8521 case 'e':
8522 case 'E':
8523 {
8524 add(current);
8525 goto scan_number_exponent;
8526 }
8527
8528 default:
8529 goto scan_number_done;
8530 }
8531
8532 scan_number_exponent:
8533 // we just parsed an exponent
8534 number_type = token_type::value_float;
8535 switch (get())
8536 {
8537 case '+':
8538 case '-':
8539 {
8540 add(current);
8541 goto scan_number_sign;
8542 }
8543
8544 case '0':
8545 case '1':
8546 case '2':
8547 case '3':
8548 case '4':
8549 case '5':
8550 case '6':
8551 case '7':
8552 case '8':
8553 case '9':
8554 {
8555 add(current);
8556 goto scan_number_any2;
8557 }
8558
8559 default:
8560 {
8562 "invalid number; expected '+', '-', or digit after exponent";
8563 return token_type::parse_error;
8564 }
8565 }
8566
8567 scan_number_sign:
8568 // we just parsed an exponent sign
8569 switch (get())
8570 {
8571 case '0':
8572 case '1':
8573 case '2':
8574 case '3':
8575 case '4':
8576 case '5':
8577 case '6':
8578 case '7':
8579 case '8':
8580 case '9':
8581 {
8582 add(current);
8583 goto scan_number_any2;
8584 }
8585
8586 default:
8587 {
8588 error_message = "invalid number; expected digit after exponent sign";
8589 return token_type::parse_error;
8590 }
8591 }
8592
8593 scan_number_any2:
8594 // we just parsed a number after the exponent or exponent sign
8595 switch (get())
8596 {
8597 case '0':
8598 case '1':
8599 case '2':
8600 case '3':
8601 case '4':
8602 case '5':
8603 case '6':
8604 case '7':
8605 case '8':
8606 case '9':
8607 {
8608 add(current);
8609 goto scan_number_any2;
8610 }
8611
8612 default:
8613 goto scan_number_done;
8614 }
8615
8616 scan_number_done:
8617 // unget the character after the number (we only read it to know that
8618 // we are done scanning a number)
8619 unget();
8620
8621 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8622 errno = 0;
8623
8624 // try to parse integers first and fall back to floats
8625 if (number_type == token_type::value_unsigned)
8626 {
8627 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8628
8629 // we checked the number format before
8630 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8631
8632 if (errno == 0)
8633 {
8634 value_unsigned = static_cast<number_unsigned_t>(x);
8635 if (value_unsigned == x)
8636 {
8637 return token_type::value_unsigned;
8638 }
8639 }
8640 }
8641 else if (number_type == token_type::value_integer)
8642 {
8643 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8644
8645 // we checked the number format before
8646 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8647
8648 if (errno == 0)
8649 {
8650 value_integer = static_cast<number_integer_t>(x);
8651 if (value_integer == x)
8652 {
8653 return token_type::value_integer;
8654 }
8655 }
8656 }
8657
8658 // this code is reached if we parse a floating-point number or if an
8659 // integer conversion above failed
8660 strtof(value_float, token_buffer.data(), &endptr);
8661
8662 // we checked the number format before
8663 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8664
8665 return token_type::value_float;
8666 }
8667
8674 token_type scan_literal(const char_type* literal_text, const std::size_t length,
8675 token_type return_type)
8676 {
8678 for (std::size_t i = 1; i < length; ++i)
8679 {
8681 {
8682 error_message = "invalid literal";
8683 return token_type::parse_error;
8684 }
8685 }
8686 return return_type;
8687 }
8688
8690 // input management
8692
8694 void reset() noexcept
8695 {
8696 token_buffer.clear();
8697 token_string.clear();
8699 }
8700
8701 /*
8702 @brief get next character from the input
8703
8704 This function provides the interface to the used input adapter. It does
8705 not throw in case the input reached EOF, but returns a
8706 `char_traits<char>::eof()` in that case. Stores the scanned characters
8707 for use in error messages.
8708
8709 @return character read from the input
8710 */
8712 {
8713 ++position.chars_read_total;
8714 ++position.chars_read_current_line;
8715
8716 if (next_unget)
8717 {
8718 // just reset the next_unget variable and work with current
8719 next_unget = false;
8720 }
8721 else
8722 {
8723 current = ia.get_character();
8724 }
8725
8727 {
8729 }
8730
8731 if (current == '\n')
8732 {
8733 ++position.lines_read;
8734 position.chars_read_current_line = 0;
8735 }
8736
8737 return current;
8738 }
8739
8748 void unget()
8749 {
8750 next_unget = true;
8751
8752 --position.chars_read_total;
8753
8754 // in case we "unget" a newline, we have to also decrement the lines_read
8755 if (position.chars_read_current_line == 0)
8756 {
8757 if (position.lines_read > 0)
8758 {
8759 --position.lines_read;
8760 }
8761 }
8762 else
8763 {
8764 --position.chars_read_current_line;
8765 }
8766
8768 {
8769 JSON_ASSERT(!token_string.empty());
8770 token_string.pop_back();
8771 }
8772 }
8773
8776 {
8777 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8778 }
8779
8780 public:
8782 // value getters
8784
8786 constexpr number_integer_t get_number_integer() const noexcept
8787 {
8788 return value_integer;
8789 }
8790
8792 constexpr number_unsigned_t get_number_unsigned() const noexcept
8793 {
8794 return value_unsigned;
8795 }
8796
8798 constexpr number_float_t get_number_float() const noexcept
8799 {
8800 return value_float;
8801 }
8802
8805 {
8806 return token_buffer;
8807 }
8808
8810 // diagnostics
8812
8814 constexpr position_t get_position() const noexcept
8815 {
8816 return position;
8817 }
8818
8822 std::string get_token_string() const
8823 {
8824 // escape control characters
8825 std::string result;
8826 for (const auto c : token_string)
8827 {
8828 if (static_cast<unsigned char>(c) <= '\x1F')
8829 {
8830 // escape control characters
8831 std::array<char, 9> cs{ {} };
8832 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8833 result += cs.data();
8834 }
8835 else
8836 {
8837 // add character as is
8838 result.push_back(static_cast<std::string::value_type>(c));
8839 }
8840 }
8841
8842 return result;
8843 }
8844
8847 constexpr const char* get_error_message() const noexcept
8848 {
8849 return error_message;
8850 }
8851
8853 // actual scanner
8855
8861 {
8862 if (get() == 0xEF)
8863 {
8864 // check if we completely parse the BOM
8865 return get() == 0xBB && get() == 0xBF;
8866 }
8867
8868 // the first character is not the beginning of the BOM; unget it to
8869 // process is later
8870 unget();
8871 return true;
8872 }
8873
8875 {
8876 do
8877 {
8878 get();
8879 } while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8880 }
8881
8883 {
8884 // initially, skip the BOM
8885 if (position.chars_read_total == 0 && !skip_bom())
8886 {
8887 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8888 return token_type::parse_error;
8889 }
8890
8891 // read next character and ignore whitespace
8893
8894 // ignore comments
8895 while (ignore_comments && current == '/')
8896 {
8897 if (!scan_comment())
8898 {
8899 return token_type::parse_error;
8900 }
8901
8902 // skip following whitespace
8904 }
8905
8906 switch (current)
8907 {
8908 // structural characters
8909 case '[':
8910 return token_type::begin_array;
8911 case ']':
8912 return token_type::end_array;
8913 case '{':
8914 return token_type::begin_object;
8915 case '}':
8916 return token_type::end_object;
8917 case ':':
8918 return token_type::name_separator;
8919 case ',':
8920 return token_type::value_separator;
8921
8922 // literals
8923 case 't':
8924 {
8925 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')} };
8926 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8927 }
8928 case 'f':
8929 {
8930 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')} };
8931 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8932 }
8933 case 'n':
8934 {
8935 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')} };
8936 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8937 }
8938
8939 // string
8940 case '\"':
8941 return scan_string();
8942
8943 // number
8944 case '-':
8945 case '0':
8946 case '1':
8947 case '2':
8948 case '3':
8949 case '4':
8950 case '5':
8951 case '6':
8952 case '7':
8953 case '8':
8954 case '9':
8955 return scan_number();
8956
8957 // end of input (the null byte is needed when parsing from
8958 // string literals)
8959 case '\0':
8961 return token_type::end_of_input;
8962
8963 // error
8964 default:
8965 error_message = "invalid literal";
8966 return token_type::parse_error;
8967 }
8968 }
8969
8970 private:
8972 InputAdapterType ia;
8973
8975 const bool ignore_comments = false;
8976
8979
8981 bool next_unget = false;
8982
8985
8987 std::vector<char_type> token_string{};
8988
8991
8993 const char* error_message = "";
8994
8995 // number values
8999
9002 };
9003
9004} // namespace detail
9006
9007// #include <nlohmann/detail/macro_scope.hpp>
9008
9009// #include <nlohmann/detail/meta/is_sax.hpp>
9010// __ _____ _____ _____
9011// __| | __| | | | JSON for Modern C++
9012// | | |__ | | | | | | version 3.11.3
9013// |_____|_____|_____|_|___| https://github.com/nlohmann/json
9014//
9015// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
9016// SPDX-License-Identifier: MIT
9017
9018
9019
9020#include <cstdint> // size_t
9021#include <utility> // declval
9022#include <string> // string
9023
9024// #include <nlohmann/detail/abi_macros.hpp>
9025
9026// #include <nlohmann/detail/meta/detected.hpp>
9027
9028// #include <nlohmann/detail/meta/type_traits.hpp>
9029
9030
9032namespace detail
9033{
9034
9035 template<typename T>
9036 using null_function_t = decltype(std::declval<T&>().null());
9037
9038 template<typename T>
9040 decltype(std::declval<T&>().boolean(std::declval<bool>()));
9041
9042 template<typename T, typename Integer>
9044 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
9045
9046 template<typename T, typename Unsigned>
9048 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
9049
9050 template<typename T, typename Float, typename String>
9051 using number_float_function_t = decltype(std::declval<T&>().number_float(
9052 std::declval<Float>(), std::declval<const String&>()));
9053
9054 template<typename T, typename String>
9056 decltype(std::declval<T&>().string(std::declval<String&>()));
9057
9058 template<typename T, typename Binary>
9060 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
9061
9062 template<typename T>
9064 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
9065
9066 template<typename T, typename String>
9068 decltype(std::declval<T&>().key(std::declval<String&>()));
9069
9070 template<typename T>
9071 using end_object_function_t = decltype(std::declval<T&>().end_object());
9072
9073 template<typename T>
9075 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
9076
9077 template<typename T>
9078 using end_array_function_t = decltype(std::declval<T&>().end_array());
9079
9080 template<typename T, typename Exception>
9081 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
9082 std::declval<std::size_t>(), std::declval<const std::string&>(),
9083 std::declval<const Exception&>()));
9084
9085 template<typename SAX, typename BasicJsonType>
9086 struct is_sax
9087 {
9088 private:
9090 "BasicJsonType must be of type basic_json<...>");
9091
9092 using number_integer_t = typename BasicJsonType::number_integer_t;
9093 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9094 using number_float_t = typename BasicJsonType::number_float_t;
9095 using string_t = typename BasicJsonType::string_t;
9096 using binary_t = typename BasicJsonType::binary_t;
9097 using exception_t = typename BasicJsonType::exception;
9098
9099 public:
9100 static constexpr bool value =
9114 };
9115
9116 template<typename SAX, typename BasicJsonType>
9118 {
9119 private:
9121 "BasicJsonType must be of type basic_json<...>");
9122
9123 using number_integer_t = typename BasicJsonType::number_integer_t;
9124 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9125 using number_float_t = typename BasicJsonType::number_float_t;
9126 using string_t = typename BasicJsonType::string_t;
9127 using binary_t = typename BasicJsonType::binary_t;
9128 using exception_t = typename BasicJsonType::exception;
9129
9130 public:
9132 "Missing/invalid function: bool null()");
9134 "Missing/invalid function: bool boolean(bool)");
9136 "Missing/invalid function: bool boolean(bool)");
9137 static_assert(
9140 "Missing/invalid function: bool number_integer(number_integer_t)");
9141 static_assert(
9144 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
9145 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
9147 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
9148 static_assert(
9150 "Missing/invalid function: bool string(string_t&)");
9151 static_assert(
9153 "Missing/invalid function: bool binary(binary_t&)");
9155 "Missing/invalid function: bool start_object(std::size_t)");
9157 "Missing/invalid function: bool key(string_t&)");
9159 "Missing/invalid function: bool end_object()");
9161 "Missing/invalid function: bool start_array(std::size_t)");
9163 "Missing/invalid function: bool end_array()");
9164 static_assert(
9166 "Missing/invalid function: bool parse_error(std::size_t, const "
9167 "std::string&, const exception&)");
9168 };
9169
9170} // namespace detail
9172
9173// #include <nlohmann/detail/meta/type_traits.hpp>
9174
9175// #include <nlohmann/detail/string_concat.hpp>
9176
9177// #include <nlohmann/detail/value_t.hpp>
9178
9179
9181namespace detail
9182{
9183
9191
9199 static inline bool little_endianness(int num = 1) noexcept
9200 {
9201 return *reinterpret_cast<char*>(&num) == 1;
9202 }
9203
9205 // binary reader //
9207
9211 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
9213 {
9214 using number_integer_t = typename BasicJsonType::number_integer_t;
9215 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9216 using number_float_t = typename BasicJsonType::number_float_t;
9217 using string_t = typename BasicJsonType::string_t;
9218 using binary_t = typename BasicJsonType::binary_t;
9219 using json_sax_t = SAX;
9220 using char_type = typename InputAdapterType::char_type;
9222
9223 public:
9229 explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
9230 {
9232 }
9233
9234 // make class move-only
9236 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9238 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
9239 ~binary_reader() = default;
9240
9250 bool sax_parse(const input_format_t format,
9251 json_sax_t* sax_,
9252 const bool strict = true,
9253 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
9254 {
9255 sax = sax_;
9256 bool result = false;
9257
9258 switch (format)
9259 {
9261 result = parse_bson_internal();
9262 break;
9263
9265 result = parse_cbor_internal(true, tag_handler);
9266 break;
9267
9269 result = parse_msgpack_internal();
9270 break;
9271
9274 result = parse_ubjson_internal();
9275 break;
9276
9277 case input_format_t::json: // LCOV_EXCL_LINE
9278 default: // LCOV_EXCL_LINE
9279 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9280 }
9281
9282 // strict mode: next byte must be EOF
9283 if (result && strict)
9284 {
9286 {
9288 }
9289 else
9290 {
9291 get();
9292 }
9293
9295 {
9296 return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
9297 exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
9298 }
9299 }
9300
9301 return result;
9302 }
9303
9304 private:
9306 // BSON //
9308
9314 {
9315 std::int32_t document_size{};
9317
9318 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
9319 {
9320 return false;
9321 }
9322
9323 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
9324 {
9325 return false;
9326 }
9327
9328 return sax->end_object();
9329 }
9330
9339 {
9340 auto out = std::back_inserter(result);
9341 while (true)
9342 {
9343 get();
9345 {
9346 return false;
9347 }
9348 if (current == 0x00)
9349 {
9350 return true;
9351 }
9352 *out++ = static_cast<typename string_t::value_type>(current);
9353 }
9354 }
9355
9367 template<typename NumberType>
9368 bool get_bson_string(const NumberType len, string_t& result)
9369 {
9370 if (JSON_HEDLEY_UNLIKELY(len < 1))
9371 {
9372 auto last_token = get_token_string();
9373 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9374 exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
9375 }
9376
9377 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != char_traits<char_type>::eof();
9378 }
9379
9389 template<typename NumberType>
9390 bool get_bson_binary(const NumberType len, binary_t& result)
9391 {
9392 if (JSON_HEDLEY_UNLIKELY(len < 0))
9393 {
9394 auto last_token = get_token_string();
9395 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9396 exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
9397 }
9398
9399 // All BSON binary values have a subtype
9400 std::uint8_t subtype{};
9402 result.set_subtype(subtype);
9403
9404 return get_binary(input_format_t::bson, len, result);
9405 }
9406
9418 const std::size_t element_type_parse_position)
9419 {
9420 switch (element_type)
9421 {
9422 case 0x01: // double
9423 {
9424 double number{};
9425 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9426 }
9427
9428 case 0x02: // string
9429 {
9430 std::int32_t len{};
9433 }
9434
9435 case 0x03: // object
9436 {
9437 return parse_bson_internal();
9438 }
9439
9440 case 0x04: // array
9441 {
9442 return parse_bson_array();
9443 }
9444
9445 case 0x05: // binary
9446 {
9447 std::int32_t len{};
9450 }
9451
9452 case 0x08: // boolean
9453 {
9454 return sax->boolean(get() != 0);
9455 }
9456
9457 case 0x0A: // null
9458 {
9459 return sax->null();
9460 }
9461
9462 case 0x10: // int32
9463 {
9464 std::int32_t value{};
9466 }
9467
9468 case 0x12: // int64
9469 {
9470 std::int64_t value{};
9472 }
9473
9474 default: // anything else not supported (yet)
9475 {
9476 std::array<char, 3> cr{ {} };
9477 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9478 const std::string cr_str{ cr.data() };
9479 return sax->parse_error(element_type_parse_position, cr_str,
9480 parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9481 }
9482 }
9483 }
9484
9497 bool parse_bson_element_list(const bool is_array)
9498 {
9499 string_t key;
9500
9501 while (auto element_type = get())
9502 {
9504 {
9505 return false;
9506 }
9507
9508 const std::size_t element_type_parse_position = chars_read;
9510 {
9511 return false;
9512 }
9513
9514 if (!is_array && !sax->key(key))
9515 {
9516 return false;
9517 }
9518
9519 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9520 {
9521 return false;
9522 }
9523
9524 // get_bson_cstr only appends
9525 key.clear();
9526 }
9527
9528 return true;
9529 }
9530
9536 {
9537 std::int32_t document_size{};
9539
9540 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9541 {
9542 return false;
9543 }
9544
9545 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9546 {
9547 return false;
9548 }
9549
9550 return sax->end_array();
9551 }
9552
9554 // CBOR //
9556
9565 bool parse_cbor_internal(const bool get_char,
9566 const cbor_tag_handler_t tag_handler)
9567 {
9568 switch (get_char ? get() : current)
9569 {
9570 // EOF
9572 return unexpect_eof(input_format_t::cbor, "value");
9573
9574 // Integer 0x00..0x17 (0..23)
9575 case 0x00:
9576 case 0x01:
9577 case 0x02:
9578 case 0x03:
9579 case 0x04:
9580 case 0x05:
9581 case 0x06:
9582 case 0x07:
9583 case 0x08:
9584 case 0x09:
9585 case 0x0A:
9586 case 0x0B:
9587 case 0x0C:
9588 case 0x0D:
9589 case 0x0E:
9590 case 0x0F:
9591 case 0x10:
9592 case 0x11:
9593 case 0x12:
9594 case 0x13:
9595 case 0x14:
9596 case 0x15:
9597 case 0x16:
9598 case 0x17:
9599 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9600
9601 case 0x18: // Unsigned integer (one-byte uint8_t follows)
9602 {
9603 std::uint8_t number{};
9604 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9605 }
9606
9607 case 0x19: // Unsigned integer (two-byte uint16_t follows)
9608 {
9609 std::uint16_t number{};
9610 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9611 }
9612
9613 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9614 {
9615 std::uint32_t number{};
9616 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9617 }
9618
9619 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9620 {
9621 std::uint64_t number{};
9622 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9623 }
9624
9625 // Negative integer -1-0x00..-1-0x17 (-1..-24)
9626 case 0x20:
9627 case 0x21:
9628 case 0x22:
9629 case 0x23:
9630 case 0x24:
9631 case 0x25:
9632 case 0x26:
9633 case 0x27:
9634 case 0x28:
9635 case 0x29:
9636 case 0x2A:
9637 case 0x2B:
9638 case 0x2C:
9639 case 0x2D:
9640 case 0x2E:
9641 case 0x2F:
9642 case 0x30:
9643 case 0x31:
9644 case 0x32:
9645 case 0x33:
9646 case 0x34:
9647 case 0x35:
9648 case 0x36:
9649 case 0x37:
9650 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9651
9652 case 0x38: // Negative integer (one-byte uint8_t follows)
9653 {
9654 std::uint8_t number{};
9655 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9656 }
9657
9658 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9659 {
9660 std::uint16_t number{};
9661 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9662 }
9663
9664 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9665 {
9666 std::uint32_t number{};
9667 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9668 }
9669
9670 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9671 {
9672 std::uint64_t number{};
9673 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9674 - static_cast<number_integer_t>(number));
9675 }
9676
9677 // Binary data (0x00..0x17 bytes follow)
9678 case 0x40:
9679 case 0x41:
9680 case 0x42:
9681 case 0x43:
9682 case 0x44:
9683 case 0x45:
9684 case 0x46:
9685 case 0x47:
9686 case 0x48:
9687 case 0x49:
9688 case 0x4A:
9689 case 0x4B:
9690 case 0x4C:
9691 case 0x4D:
9692 case 0x4E:
9693 case 0x4F:
9694 case 0x50:
9695 case 0x51:
9696 case 0x52:
9697 case 0x53:
9698 case 0x54:
9699 case 0x55:
9700 case 0x56:
9701 case 0x57:
9702 case 0x58: // Binary data (one-byte uint8_t for n follows)
9703 case 0x59: // Binary data (two-byte uint16_t for n follow)
9704 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9705 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9706 case 0x5F: // Binary data (indefinite length)
9707 {
9708 binary_t b;
9709 return get_cbor_binary(b) && sax->binary(b);
9710 }
9711
9712 // UTF-8 string (0x00..0x17 bytes follow)
9713 case 0x60:
9714 case 0x61:
9715 case 0x62:
9716 case 0x63:
9717 case 0x64:
9718 case 0x65:
9719 case 0x66:
9720 case 0x67:
9721 case 0x68:
9722 case 0x69:
9723 case 0x6A:
9724 case 0x6B:
9725 case 0x6C:
9726 case 0x6D:
9727 case 0x6E:
9728 case 0x6F:
9729 case 0x70:
9730 case 0x71:
9731 case 0x72:
9732 case 0x73:
9733 case 0x74:
9734 case 0x75:
9735 case 0x76:
9736 case 0x77:
9737 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9738 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9739 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9740 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9741 case 0x7F: // UTF-8 string (indefinite length)
9742 {
9743 string_t s;
9744 return get_cbor_string(s) && sax->string(s);
9745 }
9746
9747 // array (0x00..0x17 data items follow)
9748 case 0x80:
9749 case 0x81:
9750 case 0x82:
9751 case 0x83:
9752 case 0x84:
9753 case 0x85:
9754 case 0x86:
9755 case 0x87:
9756 case 0x88:
9757 case 0x89:
9758 case 0x8A:
9759 case 0x8B:
9760 case 0x8C:
9761 case 0x8D:
9762 case 0x8E:
9763 case 0x8F:
9764 case 0x90:
9765 case 0x91:
9766 case 0x92:
9767 case 0x93:
9768 case 0x94:
9769 case 0x95:
9770 case 0x96:
9771 case 0x97:
9772 return get_cbor_array(
9773 conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9774
9775 case 0x98: // array (one-byte uint8_t for n follows)
9776 {
9777 std::uint8_t len{};
9778 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9779 }
9780
9781 case 0x99: // array (two-byte uint16_t for n follow)
9782 {
9783 std::uint16_t len{};
9784 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9785 }
9786
9787 case 0x9A: // array (four-byte uint32_t for n follow)
9788 {
9789 std::uint32_t len{};
9791 }
9792
9793 case 0x9B: // array (eight-byte uint64_t for n follow)
9794 {
9795 std::uint64_t len{};
9797 }
9798
9799 case 0x9F: // array (indefinite length)
9800 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9801
9802 // map (0x00..0x17 pairs of data items follow)
9803 case 0xA0:
9804 case 0xA1:
9805 case 0xA2:
9806 case 0xA3:
9807 case 0xA4:
9808 case 0xA5:
9809 case 0xA6:
9810 case 0xA7:
9811 case 0xA8:
9812 case 0xA9:
9813 case 0xAA:
9814 case 0xAB:
9815 case 0xAC:
9816 case 0xAD:
9817 case 0xAE:
9818 case 0xAF:
9819 case 0xB0:
9820 case 0xB1:
9821 case 0xB2:
9822 case 0xB3:
9823 case 0xB4:
9824 case 0xB5:
9825 case 0xB6:
9826 case 0xB7:
9827 return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9828
9829 case 0xB8: // map (one-byte uint8_t for n follows)
9830 {
9831 std::uint8_t len{};
9832 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9833 }
9834
9835 case 0xB9: // map (two-byte uint16_t for n follow)
9836 {
9837 std::uint16_t len{};
9838 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9839 }
9840
9841 case 0xBA: // map (four-byte uint32_t for n follow)
9842 {
9843 std::uint32_t len{};
9845 }
9846
9847 case 0xBB: // map (eight-byte uint64_t for n follow)
9848 {
9849 std::uint64_t len{};
9851 }
9852
9853 case 0xBF: // map (indefinite length)
9854 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9855
9856 case 0xC6: // tagged item
9857 case 0xC7:
9858 case 0xC8:
9859 case 0xC9:
9860 case 0xCA:
9861 case 0xCB:
9862 case 0xCC:
9863 case 0xCD:
9864 case 0xCE:
9865 case 0xCF:
9866 case 0xD0:
9867 case 0xD1:
9868 case 0xD2:
9869 case 0xD3:
9870 case 0xD4:
9871 case 0xD8: // tagged item (1 bytes follow)
9872 case 0xD9: // tagged item (2 bytes follow)
9873 case 0xDA: // tagged item (4 bytes follow)
9874 case 0xDB: // tagged item (8 bytes follow)
9875 {
9876 switch (tag_handler)
9877 {
9879 {
9880 auto last_token = get_token_string();
9881 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9882 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9883 }
9884
9886 {
9887 // ignore binary subtype
9888 switch (current)
9889 {
9890 case 0xD8:
9891 {
9892 std::uint8_t subtype_to_ignore{};
9893 get_number(input_format_t::cbor, subtype_to_ignore);
9894 break;
9895 }
9896 case 0xD9:
9897 {
9898 std::uint16_t subtype_to_ignore{};
9899 get_number(input_format_t::cbor, subtype_to_ignore);
9900 break;
9901 }
9902 case 0xDA:
9903 {
9904 std::uint32_t subtype_to_ignore{};
9905 get_number(input_format_t::cbor, subtype_to_ignore);
9906 break;
9907 }
9908 case 0xDB:
9909 {
9910 std::uint64_t subtype_to_ignore{};
9911 get_number(input_format_t::cbor, subtype_to_ignore);
9912 break;
9913 }
9914 default:
9915 break;
9916 }
9917 return parse_cbor_internal(true, tag_handler);
9918 }
9919
9921 {
9922 binary_t b;
9923 // use binary subtype and store in binary container
9924 switch (current)
9925 {
9926 case 0xD8:
9927 {
9928 std::uint8_t subtype{};
9931 break;
9932 }
9933 case 0xD9:
9934 {
9935 std::uint16_t subtype{};
9938 break;
9939 }
9940 case 0xDA:
9941 {
9942 std::uint32_t subtype{};
9945 break;
9946 }
9947 case 0xDB:
9948 {
9949 std::uint64_t subtype{};
9952 break;
9953 }
9954 default:
9955 return parse_cbor_internal(true, tag_handler);
9956 }
9957 get();
9958 return get_cbor_binary(b) && sax->binary(b);
9959 }
9960
9961 default: // LCOV_EXCL_LINE
9962 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9963 return false; // LCOV_EXCL_LINE
9964 }
9965 }
9966
9967 case 0xF4: // false
9968 return sax->boolean(false);
9969
9970 case 0xF5: // true
9971 return sax->boolean(true);
9972
9973 case 0xF6: // null
9974 return sax->null();
9975
9976 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9977 {
9978 const auto byte1_raw = get();
9980 {
9981 return false;
9982 }
9983 const auto byte2_raw = get();
9985 {
9986 return false;
9987 }
9988
9989 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9990 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9991
9992 // code from RFC 7049, Appendix D, Figure 3:
9993 // As half-precision floating-point numbers were only added
9994 // to IEEE 754 in 2008, today's programming platforms often
9995 // still only have limited support for them. It is very
9996 // easy to include at least decoding support for them even
9997 // without such support. An example of a small decoder for
9998 // half-precision floating-point numbers in the C language
9999 // is shown in Fig. 3.
10000 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
10001 const double val = [&half]
10002 {
10003 const int exp = (half >> 10u) & 0x1Fu;
10004 const unsigned int mant = half & 0x3FFu;
10005 JSON_ASSERT(0 <= exp && exp <= 32);
10006 JSON_ASSERT(mant <= 1024);
10007 switch (exp)
10008 {
10009 case 0:
10010 return std::ldexp(mant, -24);
10011 case 31:
10012 return (mant == 0)
10013 ? std::numeric_limits<double>::infinity()
10014 : std::numeric_limits<double>::quiet_NaN();
10015 default:
10016 return std::ldexp(mant + 1024, exp - 25);
10017 }
10018 }();
10019 return sax->number_float((half & 0x8000u) != 0
10020 ? static_cast<number_float_t>(-val)
10021 : static_cast<number_float_t>(val), "");
10022 }
10023
10024 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
10025 {
10026 float number{};
10027 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10028 }
10029
10030 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
10031 {
10032 double number{};
10033 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
10034 }
10035
10036 default: // anything else (0xFF is handled inside the other types)
10037 {
10038 auto last_token = get_token_string();
10039 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10040 exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
10041 }
10042 }
10043 }
10044
10057 {
10059 {
10060 return false;
10061 }
10062
10063 switch (current)
10064 {
10065 // UTF-8 string (0x00..0x17 bytes follow)
10066 case 0x60:
10067 case 0x61:
10068 case 0x62:
10069 case 0x63:
10070 case 0x64:
10071 case 0x65:
10072 case 0x66:
10073 case 0x67:
10074 case 0x68:
10075 case 0x69:
10076 case 0x6A:
10077 case 0x6B:
10078 case 0x6C:
10079 case 0x6D:
10080 case 0x6E:
10081 case 0x6F:
10082 case 0x70:
10083 case 0x71:
10084 case 0x72:
10085 case 0x73:
10086 case 0x74:
10087 case 0x75:
10088 case 0x76:
10089 case 0x77:
10090 {
10091 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10092 }
10093
10094 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
10095 {
10096 std::uint8_t len{};
10097 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10098 }
10099
10100 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
10101 {
10102 std::uint16_t len{};
10103 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10104 }
10105
10106 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
10107 {
10108 std::uint32_t len{};
10109 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10110 }
10111
10112 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
10113 {
10114 std::uint64_t len{};
10115 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
10116 }
10117
10118 case 0x7F: // UTF-8 string (indefinite length)
10119 {
10120 while (get() != 0xFF)
10121 {
10122 string_t chunk;
10123 if (!get_cbor_string(chunk))
10124 {
10125 return false;
10126 }
10127 result.append(chunk);
10128 }
10129 return true;
10130 }
10131
10132 default:
10133 {
10134 auto last_token = get_token_string();
10135 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10136 exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
10137 }
10138 }
10139 }
10140
10153 {
10155 {
10156 return false;
10157 }
10158
10159 switch (current)
10160 {
10161 // Binary data (0x00..0x17 bytes follow)
10162 case 0x40:
10163 case 0x41:
10164 case 0x42:
10165 case 0x43:
10166 case 0x44:
10167 case 0x45:
10168 case 0x46:
10169 case 0x47:
10170 case 0x48:
10171 case 0x49:
10172 case 0x4A:
10173 case 0x4B:
10174 case 0x4C:
10175 case 0x4D:
10176 case 0x4E:
10177 case 0x4F:
10178 case 0x50:
10179 case 0x51:
10180 case 0x52:
10181 case 0x53:
10182 case 0x54:
10183 case 0x55:
10184 case 0x56:
10185 case 0x57:
10186 {
10187 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
10188 }
10189
10190 case 0x58: // Binary data (one-byte uint8_t for n follows)
10191 {
10192 std::uint8_t len{};
10193 return get_number(input_format_t::cbor, len) &&
10194 get_binary(input_format_t::cbor, len, result);
10195 }
10196
10197 case 0x59: // Binary data (two-byte uint16_t for n follow)
10198 {
10199 std::uint16_t len{};
10200 return get_number(input_format_t::cbor, len) &&
10201 get_binary(input_format_t::cbor, len, result);
10202 }
10203
10204 case 0x5A: // Binary data (four-byte uint32_t for n follow)
10205 {
10206 std::uint32_t len{};
10207 return get_number(input_format_t::cbor, len) &&
10208 get_binary(input_format_t::cbor, len, result);
10209 }
10210
10211 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
10212 {
10213 std::uint64_t len{};
10214 return get_number(input_format_t::cbor, len) &&
10215 get_binary(input_format_t::cbor, len, result);
10216 }
10217
10218 case 0x5F: // Binary data (indefinite length)
10219 {
10220 while (get() != 0xFF)
10221 {
10222 binary_t chunk;
10223 if (!get_cbor_binary(chunk))
10224 {
10225 return false;
10226 }
10227 result.insert(result.end(), chunk.begin(), chunk.end());
10228 }
10229 return true;
10230 }
10231
10232 default:
10233 {
10234 auto last_token = get_token_string();
10235 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10236 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));
10237 }
10238 }
10239 }
10240
10247 bool get_cbor_array(const std::size_t len,
10248 const cbor_tag_handler_t tag_handler)
10249 {
10250 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10251 {
10252 return false;
10253 }
10254
10255 if (len != static_cast<std::size_t>(-1))
10256 {
10257 for (std::size_t i = 0; i < len; ++i)
10258 {
10259 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10260 {
10261 return false;
10262 }
10263 }
10264 }
10265 else
10266 {
10267 while (get() != 0xFF)
10268 {
10269 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
10270 {
10271 return false;
10272 }
10273 }
10274 }
10275
10276 return sax->end_array();
10277 }
10278
10285 bool get_cbor_object(const std::size_t len,
10286 const cbor_tag_handler_t tag_handler)
10287 {
10288 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10289 {
10290 return false;
10291 }
10292
10293 if (len != 0)
10294 {
10295 string_t key;
10296 if (len != static_cast<std::size_t>(-1))
10297 {
10298 for (std::size_t i = 0; i < len; ++i)
10299 {
10300 get();
10302 {
10303 return false;
10304 }
10305
10306 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10307 {
10308 return false;
10309 }
10310 key.clear();
10311 }
10312 }
10313 else
10314 {
10315 while (get() != 0xFF)
10316 {
10318 {
10319 return false;
10320 }
10321
10322 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
10323 {
10324 return false;
10325 }
10326 key.clear();
10327 }
10328 }
10329 }
10330
10331 return sax->end_object();
10332 }
10333
10335 // MsgPack //
10337
10342 {
10343 switch (get())
10344 {
10345 // EOF
10347 return unexpect_eof(input_format_t::msgpack, "value");
10348
10349 // positive fixint
10350 case 0x00:
10351 case 0x01:
10352 case 0x02:
10353 case 0x03:
10354 case 0x04:
10355 case 0x05:
10356 case 0x06:
10357 case 0x07:
10358 case 0x08:
10359 case 0x09:
10360 case 0x0A:
10361 case 0x0B:
10362 case 0x0C:
10363 case 0x0D:
10364 case 0x0E:
10365 case 0x0F:
10366 case 0x10:
10367 case 0x11:
10368 case 0x12:
10369 case 0x13:
10370 case 0x14:
10371 case 0x15:
10372 case 0x16:
10373 case 0x17:
10374 case 0x18:
10375 case 0x19:
10376 case 0x1A:
10377 case 0x1B:
10378 case 0x1C:
10379 case 0x1D:
10380 case 0x1E:
10381 case 0x1F:
10382 case 0x20:
10383 case 0x21:
10384 case 0x22:
10385 case 0x23:
10386 case 0x24:
10387 case 0x25:
10388 case 0x26:
10389 case 0x27:
10390 case 0x28:
10391 case 0x29:
10392 case 0x2A:
10393 case 0x2B:
10394 case 0x2C:
10395 case 0x2D:
10396 case 0x2E:
10397 case 0x2F:
10398 case 0x30:
10399 case 0x31:
10400 case 0x32:
10401 case 0x33:
10402 case 0x34:
10403 case 0x35:
10404 case 0x36:
10405 case 0x37:
10406 case 0x38:
10407 case 0x39:
10408 case 0x3A:
10409 case 0x3B:
10410 case 0x3C:
10411 case 0x3D:
10412 case 0x3E:
10413 case 0x3F:
10414 case 0x40:
10415 case 0x41:
10416 case 0x42:
10417 case 0x43:
10418 case 0x44:
10419 case 0x45:
10420 case 0x46:
10421 case 0x47:
10422 case 0x48:
10423 case 0x49:
10424 case 0x4A:
10425 case 0x4B:
10426 case 0x4C:
10427 case 0x4D:
10428 case 0x4E:
10429 case 0x4F:
10430 case 0x50:
10431 case 0x51:
10432 case 0x52:
10433 case 0x53:
10434 case 0x54:
10435 case 0x55:
10436 case 0x56:
10437 case 0x57:
10438 case 0x58:
10439 case 0x59:
10440 case 0x5A:
10441 case 0x5B:
10442 case 0x5C:
10443 case 0x5D:
10444 case 0x5E:
10445 case 0x5F:
10446 case 0x60:
10447 case 0x61:
10448 case 0x62:
10449 case 0x63:
10450 case 0x64:
10451 case 0x65:
10452 case 0x66:
10453 case 0x67:
10454 case 0x68:
10455 case 0x69:
10456 case 0x6A:
10457 case 0x6B:
10458 case 0x6C:
10459 case 0x6D:
10460 case 0x6E:
10461 case 0x6F:
10462 case 0x70:
10463 case 0x71:
10464 case 0x72:
10465 case 0x73:
10466 case 0x74:
10467 case 0x75:
10468 case 0x76:
10469 case 0x77:
10470 case 0x78:
10471 case 0x79:
10472 case 0x7A:
10473 case 0x7B:
10474 case 0x7C:
10475 case 0x7D:
10476 case 0x7E:
10477 case 0x7F:
10478 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10479
10480 // fixmap
10481 case 0x80:
10482 case 0x81:
10483 case 0x82:
10484 case 0x83:
10485 case 0x84:
10486 case 0x85:
10487 case 0x86:
10488 case 0x87:
10489 case 0x88:
10490 case 0x89:
10491 case 0x8A:
10492 case 0x8B:
10493 case 0x8C:
10494 case 0x8D:
10495 case 0x8E:
10496 case 0x8F:
10497 return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10498
10499 // fixarray
10500 case 0x90:
10501 case 0x91:
10502 case 0x92:
10503 case 0x93:
10504 case 0x94:
10505 case 0x95:
10506 case 0x96:
10507 case 0x97:
10508 case 0x98:
10509 case 0x99:
10510 case 0x9A:
10511 case 0x9B:
10512 case 0x9C:
10513 case 0x9D:
10514 case 0x9E:
10515 case 0x9F:
10516 return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10517
10518 // fixstr
10519 case 0xA0:
10520 case 0xA1:
10521 case 0xA2:
10522 case 0xA3:
10523 case 0xA4:
10524 case 0xA5:
10525 case 0xA6:
10526 case 0xA7:
10527 case 0xA8:
10528 case 0xA9:
10529 case 0xAA:
10530 case 0xAB:
10531 case 0xAC:
10532 case 0xAD:
10533 case 0xAE:
10534 case 0xAF:
10535 case 0xB0:
10536 case 0xB1:
10537 case 0xB2:
10538 case 0xB3:
10539 case 0xB4:
10540 case 0xB5:
10541 case 0xB6:
10542 case 0xB7:
10543 case 0xB8:
10544 case 0xB9:
10545 case 0xBA:
10546 case 0xBB:
10547 case 0xBC:
10548 case 0xBD:
10549 case 0xBE:
10550 case 0xBF:
10551 case 0xD9: // str 8
10552 case 0xDA: // str 16
10553 case 0xDB: // str 32
10554 {
10555 string_t s;
10556 return get_msgpack_string(s) && sax->string(s);
10557 }
10558
10559 case 0xC0: // nil
10560 return sax->null();
10561
10562 case 0xC2: // false
10563 return sax->boolean(false);
10564
10565 case 0xC3: // true
10566 return sax->boolean(true);
10567
10568 case 0xC4: // bin 8
10569 case 0xC5: // bin 16
10570 case 0xC6: // bin 32
10571 case 0xC7: // ext 8
10572 case 0xC8: // ext 16
10573 case 0xC9: // ext 32
10574 case 0xD4: // fixext 1
10575 case 0xD5: // fixext 2
10576 case 0xD6: // fixext 4
10577 case 0xD7: // fixext 8
10578 case 0xD8: // fixext 16
10579 {
10580 binary_t b;
10581 return get_msgpack_binary(b) && sax->binary(b);
10582 }
10583
10584 case 0xCA: // float 32
10585 {
10586 float number{};
10587 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10588 }
10589
10590 case 0xCB: // float 64
10591 {
10592 double number{};
10593 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10594 }
10595
10596 case 0xCC: // uint 8
10597 {
10598 std::uint8_t number{};
10599 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10600 }
10601
10602 case 0xCD: // uint 16
10603 {
10604 std::uint16_t number{};
10605 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10606 }
10607
10608 case 0xCE: // uint 32
10609 {
10610 std::uint32_t number{};
10611 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10612 }
10613
10614 case 0xCF: // uint 64
10615 {
10616 std::uint64_t number{};
10617 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10618 }
10619
10620 case 0xD0: // int 8
10621 {
10622 std::int8_t number{};
10623 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10624 }
10625
10626 case 0xD1: // int 16
10627 {
10628 std::int16_t number{};
10629 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10630 }
10631
10632 case 0xD2: // int 32
10633 {
10634 std::int32_t number{};
10635 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10636 }
10637
10638 case 0xD3: // int 64
10639 {
10640 std::int64_t number{};
10641 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10642 }
10643
10644 case 0xDC: // array 16
10645 {
10646 std::uint16_t len{};
10647 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10648 }
10649
10650 case 0xDD: // array 32
10651 {
10652 std::uint32_t len{};
10654 }
10655
10656 case 0xDE: // map 16
10657 {
10658 std::uint16_t len{};
10659 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10660 }
10661
10662 case 0xDF: // map 32
10663 {
10664 std::uint32_t len{};
10666 }
10667
10668 // negative fixint
10669 case 0xE0:
10670 case 0xE1:
10671 case 0xE2:
10672 case 0xE3:
10673 case 0xE4:
10674 case 0xE5:
10675 case 0xE6:
10676 case 0xE7:
10677 case 0xE8:
10678 case 0xE9:
10679 case 0xEA:
10680 case 0xEB:
10681 case 0xEC:
10682 case 0xED:
10683 case 0xEE:
10684 case 0xEF:
10685 case 0xF0:
10686 case 0xF1:
10687 case 0xF2:
10688 case 0xF3:
10689 case 0xF4:
10690 case 0xF5:
10691 case 0xF6:
10692 case 0xF7:
10693 case 0xF8:
10694 case 0xF9:
10695 case 0xFA:
10696 case 0xFB:
10697 case 0xFC:
10698 case 0xFD:
10699 case 0xFE:
10700 case 0xFF:
10701 return sax->number_integer(static_cast<std::int8_t>(current));
10702
10703 default: // anything else
10704 {
10705 auto last_token = get_token_string();
10706 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10707 exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10708 }
10709 }
10710 }
10711
10723 {
10725 {
10726 return false;
10727 }
10728
10729 switch (current)
10730 {
10731 // fixstr
10732 case 0xA0:
10733 case 0xA1:
10734 case 0xA2:
10735 case 0xA3:
10736 case 0xA4:
10737 case 0xA5:
10738 case 0xA6:
10739 case 0xA7:
10740 case 0xA8:
10741 case 0xA9:
10742 case 0xAA:
10743 case 0xAB:
10744 case 0xAC:
10745 case 0xAD:
10746 case 0xAE:
10747 case 0xAF:
10748 case 0xB0:
10749 case 0xB1:
10750 case 0xB2:
10751 case 0xB3:
10752 case 0xB4:
10753 case 0xB5:
10754 case 0xB6:
10755 case 0xB7:
10756 case 0xB8:
10757 case 0xB9:
10758 case 0xBA:
10759 case 0xBB:
10760 case 0xBC:
10761 case 0xBD:
10762 case 0xBE:
10763 case 0xBF:
10764 {
10765 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10766 }
10767
10768 case 0xD9: // str 8
10769 {
10770 std::uint8_t len{};
10772 }
10773
10774 case 0xDA: // str 16
10775 {
10776 std::uint16_t len{};
10778 }
10779
10780 case 0xDB: // str 32
10781 {
10782 std::uint32_t len{};
10784 }
10785
10786 default:
10787 {
10788 auto last_token = get_token_string();
10789 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10790 exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10791 }
10792 }
10793 }
10794
10806 {
10807 // helper function to set the subtype
10808 auto assign_and_return_true = [&result](std::int8_t subtype)
10809 {
10810 result.set_subtype(static_cast<std::uint8_t>(subtype));
10811 return true;
10812 };
10813
10814 switch (current)
10815 {
10816 case 0xC4: // bin 8
10817 {
10818 std::uint8_t len{};
10819 return get_number(input_format_t::msgpack, len) &&
10820 get_binary(input_format_t::msgpack, len, result);
10821 }
10822
10823 case 0xC5: // bin 16
10824 {
10825 std::uint16_t len{};
10826 return get_number(input_format_t::msgpack, len) &&
10827 get_binary(input_format_t::msgpack, len, result);
10828 }
10829
10830 case 0xC6: // bin 32
10831 {
10832 std::uint32_t len{};
10833 return get_number(input_format_t::msgpack, len) &&
10834 get_binary(input_format_t::msgpack, len, result);
10835 }
10836
10837 case 0xC7: // ext 8
10838 {
10839 std::uint8_t len{};
10840 std::int8_t subtype{};
10841 return get_number(input_format_t::msgpack, len) &&
10843 get_binary(input_format_t::msgpack, len, result) &&
10844 assign_and_return_true(subtype);
10845 }
10846
10847 case 0xC8: // ext 16
10848 {
10849 std::uint16_t len{};
10850 std::int8_t subtype{};
10851 return get_number(input_format_t::msgpack, len) &&
10853 get_binary(input_format_t::msgpack, len, result) &&
10854 assign_and_return_true(subtype);
10855 }
10856
10857 case 0xC9: // ext 32
10858 {
10859 std::uint32_t len{};
10860 std::int8_t subtype{};
10861 return get_number(input_format_t::msgpack, len) &&
10863 get_binary(input_format_t::msgpack, len, result) &&
10864 assign_and_return_true(subtype);
10865 }
10866
10867 case 0xD4: // fixext 1
10868 {
10869 std::int8_t subtype{};
10870 return get_number(input_format_t::msgpack, subtype) &&
10871 get_binary(input_format_t::msgpack, 1, result) &&
10872 assign_and_return_true(subtype);
10873 }
10874
10875 case 0xD5: // fixext 2
10876 {
10877 std::int8_t subtype{};
10878 return get_number(input_format_t::msgpack, subtype) &&
10879 get_binary(input_format_t::msgpack, 2, result) &&
10880 assign_and_return_true(subtype);
10881 }
10882
10883 case 0xD6: // fixext 4
10884 {
10885 std::int8_t subtype{};
10886 return get_number(input_format_t::msgpack, subtype) &&
10887 get_binary(input_format_t::msgpack, 4, result) &&
10888 assign_and_return_true(subtype);
10889 }
10890
10891 case 0xD7: // fixext 8
10892 {
10893 std::int8_t subtype{};
10894 return get_number(input_format_t::msgpack, subtype) &&
10895 get_binary(input_format_t::msgpack, 8, result) &&
10896 assign_and_return_true(subtype);
10897 }
10898
10899 case 0xD8: // fixext 16
10900 {
10901 std::int8_t subtype{};
10902 return get_number(input_format_t::msgpack, subtype) &&
10903 get_binary(input_format_t::msgpack, 16, result) &&
10904 assign_and_return_true(subtype);
10905 }
10906
10907 default: // LCOV_EXCL_LINE
10908 return false; // LCOV_EXCL_LINE
10909 }
10910 }
10911
10916 bool get_msgpack_array(const std::size_t len)
10917 {
10918 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10919 {
10920 return false;
10921 }
10922
10923 for (std::size_t i = 0; i < len; ++i)
10924 {
10926 {
10927 return false;
10928 }
10929 }
10930
10931 return sax->end_array();
10932 }
10933
10938 bool get_msgpack_object(const std::size_t len)
10939 {
10940 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10941 {
10942 return false;
10943 }
10944
10945 string_t key;
10946 for (std::size_t i = 0; i < len; ++i)
10947 {
10948 get();
10950 {
10951 return false;
10952 }
10953
10955 {
10956 return false;
10957 }
10958 key.clear();
10959 }
10960
10961 return sax->end_object();
10962 }
10963
10965 // UBJSON //
10967
10975 bool parse_ubjson_internal(const bool get_char = true)
10976 {
10977 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10978 }
10979
10994 bool get_ubjson_string(string_t& result, const bool get_char = true)
10995 {
10996 if (get_char)
10997 {
10998 get(); // TODO(niels): may we ignore N here?
10999 }
11000
11002 {
11003 return false;
11004 }
11005
11006 switch (current)
11007 {
11008 case 'U':
11009 {
11010 std::uint8_t len{};
11011 return get_number(input_format, len) && get_string(input_format, len, result);
11012 }
11013
11014 case 'i':
11015 {
11016 std::int8_t len{};
11017 return get_number(input_format, len) && get_string(input_format, len, result);
11018 }
11019
11020 case 'I':
11021 {
11022 std::int16_t len{};
11023 return get_number(input_format, len) && get_string(input_format, len, result);
11024 }
11025
11026 case 'l':
11027 {
11028 std::int32_t len{};
11029 return get_number(input_format, len) && get_string(input_format, len, result);
11030 }
11031
11032 case 'L':
11033 {
11034 std::int64_t len{};
11035 return get_number(input_format, len) && get_string(input_format, len, result);
11036 }
11037
11038 case 'u':
11039 {
11041 {
11042 break;
11043 }
11044 std::uint16_t len{};
11045 return get_number(input_format, len) && get_string(input_format, len, result);
11046 }
11047
11048 case 'm':
11049 {
11051 {
11052 break;
11053 }
11054 std::uint32_t len{};
11055 return get_number(input_format, len) && get_string(input_format, len, result);
11056 }
11057
11058 case 'M':
11059 {
11061 {
11062 break;
11063 }
11064 std::uint64_t len{};
11065 return get_number(input_format, len) && get_string(input_format, len, result);
11066 }
11067
11068 default:
11069 break;
11070 }
11071 auto last_token = get_token_string();
11072 std::string message;
11073
11075 {
11076 message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
11077 }
11078 else
11079 {
11080 message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
11081 }
11082 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
11083 }
11084
11089 bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
11090 {
11091 std::pair<std::size_t, char_int_type> size_and_type;
11092 size_t dimlen = 0;
11093 bool no_ndarray = true;
11094
11095 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
11096 {
11097 return false;
11098 }
11099
11100 if (size_and_type.first != npos)
11101 {
11102 if (size_and_type.second != 0)
11103 {
11104 if (size_and_type.second != 'N')
11105 {
11106 for (std::size_t i = 0; i < size_and_type.first; ++i)
11107 {
11108 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
11109 {
11110 return false;
11111 }
11112 dim.push_back(dimlen);
11113 }
11114 }
11115 }
11116 else
11117 {
11118 for (std::size_t i = 0; i < size_and_type.first; ++i)
11119 {
11120 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
11121 {
11122 return false;
11123 }
11124 dim.push_back(dimlen);
11125 }
11126 }
11127 }
11128 else
11129 {
11130 while (current != ']')
11131 {
11132 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
11133 {
11134 return false;
11135 }
11136 dim.push_back(dimlen);
11138 }
11139 }
11140 return true;
11141 }
11142
11154 bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
11155 {
11156 if (prefix == 0)
11157 {
11158 prefix = get_ignore_noop();
11159 }
11160
11161 switch (prefix)
11162 {
11163 case 'U':
11164 {
11165 std::uint8_t number{};
11167 {
11168 return false;
11169 }
11170 result = static_cast<std::size_t>(number);
11171 return true;
11172 }
11173
11174 case 'i':
11175 {
11176 std::int8_t number{};
11178 {
11179 return false;
11180 }
11181 if (number < 0)
11182 {
11183 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11184 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11185 }
11186 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
11187 return true;
11188 }
11189
11190 case 'I':
11191 {
11192 std::int16_t number{};
11194 {
11195 return false;
11196 }
11197 if (number < 0)
11198 {
11199 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11200 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11201 }
11202 result = static_cast<std::size_t>(number);
11203 return true;
11204 }
11205
11206 case 'l':
11207 {
11208 std::int32_t number{};
11210 {
11211 return false;
11212 }
11213 if (number < 0)
11214 {
11215 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11216 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11217 }
11218 result = static_cast<std::size_t>(number);
11219 return true;
11220 }
11221
11222 case 'L':
11223 {
11224 std::int64_t number{};
11226 {
11227 return false;
11228 }
11229 if (number < 0)
11230 {
11231 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
11232 exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
11233 }
11234 if (!value_in_range_of<std::size_t>(number))
11235 {
11236 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11237 exception_message(input_format, "integer value overflow", "size"), nullptr));
11238 }
11239 result = static_cast<std::size_t>(number);
11240 return true;
11241 }
11242
11243 case 'u':
11244 {
11246 {
11247 break;
11248 }
11249 std::uint16_t number{};
11251 {
11252 return false;
11253 }
11254 result = static_cast<std::size_t>(number);
11255 return true;
11256 }
11257
11258 case 'm':
11259 {
11261 {
11262 break;
11263 }
11264 std::uint32_t number{};
11266 {
11267 return false;
11268 }
11269 result = conditional_static_cast<std::size_t>(number);
11270 return true;
11271 }
11272
11273 case 'M':
11274 {
11276 {
11277 break;
11278 }
11279 std::uint64_t number{};
11281 {
11282 return false;
11283 }
11284 if (!value_in_range_of<std::size_t>(number))
11285 {
11286 return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
11287 exception_message(input_format, "integer value overflow", "size"), nullptr));
11288 }
11290 return true;
11291 }
11292
11293 case '[':
11294 {
11296 {
11297 break;
11298 }
11299 if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
11300 {
11301 return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr));
11302 }
11303 std::vector<size_t> dim;
11305 {
11306 return false;
11307 }
11308 if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
11309 {
11310 result = dim.at(dim.size() - 1);
11311 return true;
11312 }
11313 if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
11314 {
11315 for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
11316 {
11317 if (i == 0)
11318 {
11319 result = 0;
11320 return true;
11321 }
11322 }
11323
11324 string_t key = "_ArraySize_";
11325 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
11326 {
11327 return false;
11328 }
11329 result = 1;
11330 for (auto i : dim)
11331 {
11332 result *= i;
11333 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()
11334 {
11335 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));
11336 }
11337 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
11338 {
11339 return false;
11340 }
11341 }
11342 is_ndarray = true;
11343 return sax->end_array();
11344 }
11345 result = 0;
11346 return true;
11347 }
11348
11349 default:
11350 break;
11351 }
11352 auto last_token = get_token_string();
11353 std::string message;
11354
11356 {
11357 message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
11358 }
11359 else
11360 {
11361 message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
11362 }
11363 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
11364 }
11365
11377 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
11378 {
11379 result.first = npos; // size
11380 result.second = 0; // type
11381 bool is_ndarray = false;
11382
11384
11385 if (current == '$')
11386 {
11387 result.second = get(); // must not ignore 'N', because 'N' maybe the type
11389 && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second)))
11390 {
11391 auto last_token = get_token_string();
11392 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11393 exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
11394 }
11395
11397 {
11398 return false;
11399 }
11400
11402 if (JSON_HEDLEY_UNLIKELY(current != '#'))
11403 {
11405 {
11406 return false;
11407 }
11408 auto last_token = get_token_string();
11409 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11410 exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
11411 }
11412
11413 const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11414 if (input_format == input_format_t::bjdata && is_ndarray)
11415 {
11416 if (inside_ndarray)
11417 {
11418 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11419 exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
11420 }
11421 result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
11422 }
11423 return is_error;
11424 }
11425
11426 if (current == '#')
11427 {
11428 const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
11429 if (input_format == input_format_t::bjdata && is_ndarray)
11430 {
11431 return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
11432 exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
11433 }
11434 return is_error;
11435 }
11436
11437 return true;
11438 }
11439
11445 {
11446 switch (prefix)
11447 {
11448 case char_traits<char_type>::eof(): // EOF
11449 return unexpect_eof(input_format, "value");
11450
11451 case 'T': // true
11452 return sax->boolean(true);
11453 case 'F': // false
11454 return sax->boolean(false);
11455
11456 case 'Z': // null
11457 return sax->null();
11458
11459 case 'U':
11460 {
11461 std::uint8_t number{};
11462 return get_number(input_format, number) && sax->number_unsigned(number);
11463 }
11464
11465 case 'i':
11466 {
11467 std::int8_t number{};
11468 return get_number(input_format, number) && sax->number_integer(number);
11469 }
11470
11471 case 'I':
11472 {
11473 std::int16_t number{};
11474 return get_number(input_format, number) && sax->number_integer(number);
11475 }
11476
11477 case 'l':
11478 {
11479 std::int32_t number{};
11480 return get_number(input_format, number) && sax->number_integer(number);
11481 }
11482
11483 case 'L':
11484 {
11485 std::int64_t number{};
11486 return get_number(input_format, number) && sax->number_integer(number);
11487 }
11488
11489 case 'u':
11490 {
11492 {
11493 break;
11494 }
11495 std::uint16_t number{};
11496 return get_number(input_format, number) && sax->number_unsigned(number);
11497 }
11498
11499 case 'm':
11500 {
11502 {
11503 break;
11504 }
11505 std::uint32_t number{};
11506 return get_number(input_format, number) && sax->number_unsigned(number);
11507 }
11508
11509 case 'M':
11510 {
11512 {
11513 break;
11514 }
11515 std::uint64_t number{};
11516 return get_number(input_format, number) && sax->number_unsigned(number);
11517 }
11518
11519 case 'h':
11520 {
11522 {
11523 break;
11524 }
11525 const auto byte1_raw = get();
11527 {
11528 return false;
11529 }
11530 const auto byte2_raw = get();
11532 {
11533 return false;
11534 }
11535
11536 const auto byte1 = static_cast<unsigned char>(byte1_raw);
11537 const auto byte2 = static_cast<unsigned char>(byte2_raw);
11538
11539 // code from RFC 7049, Appendix D, Figure 3:
11540 // As half-precision floating-point numbers were only added
11541 // to IEEE 754 in 2008, today's programming platforms often
11542 // still only have limited support for them. It is very
11543 // easy to include at least decoding support for them even
11544 // without such support. An example of a small decoder for
11545 // half-precision floating-point numbers in the C language
11546 // is shown in Fig. 3.
11547 const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11548 const double val = [&half]
11549 {
11550 const int exp = (half >> 10u) & 0x1Fu;
11551 const unsigned int mant = half & 0x3FFu;
11552 JSON_ASSERT(0 <= exp && exp <= 32);
11553 JSON_ASSERT(mant <= 1024);
11554 switch (exp)
11555 {
11556 case 0:
11557 return std::ldexp(mant, -24);
11558 case 31:
11559 return (mant == 0)
11560 ? std::numeric_limits<double>::infinity()
11561 : std::numeric_limits<double>::quiet_NaN();
11562 default:
11563 return std::ldexp(mant + 1024, exp - 25);
11564 }
11565 }();
11566 return sax->number_float((half & 0x8000u) != 0
11567 ? static_cast<number_float_t>(-val)
11568 : static_cast<number_float_t>(val), "");
11569 }
11570
11571 case 'd':
11572 {
11573 float number{};
11574 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11575 }
11576
11577 case 'D':
11578 {
11579 double number{};
11580 return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11581 }
11582
11583 case 'H':
11584 {
11586 }
11587
11588 case 'C': // char
11589 {
11590 get();
11592 {
11593 return false;
11594 }
11595 if (JSON_HEDLEY_UNLIKELY(current > 127))
11596 {
11597 auto last_token = get_token_string();
11598 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11599 exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11600 }
11601 string_t s(1, static_cast<typename string_t::value_type>(current));
11602 return sax->string(s);
11603 }
11604
11605 case 'S': // string
11606 {
11607 string_t s;
11608 return get_ubjson_string(s) && sax->string(s);
11609 }
11610
11611 case '[': // array
11612 return get_ubjson_array();
11613
11614 case '{': // object
11615 return get_ubjson_object();
11616
11617 default: // anything else
11618 break;
11619 }
11620 auto last_token = get_token_string();
11621 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));
11622 }
11623
11628 {
11629 std::pair<std::size_t, char_int_type> size_and_type;
11630 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11631 {
11632 return false;
11633 }
11634
11635 // 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):
11636 // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11637
11638 if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11639 {
11640 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
11641 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)
11642 {
11643 return p.first < t;
11644 });
11645 string_t key = "_ArrayType_";
11646 if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second))
11647 {
11648 auto last_token = get_token_string();
11649 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11650 exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11651 }
11652
11653 string_t type = it->second; // sax->string() takes a reference
11654 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type)))
11655 {
11656 return false;
11657 }
11658
11659 if (size_and_type.second == 'C')
11660 {
11661 size_and_type.second = 'U';
11662 }
11663
11664 key = "_ArrayData_";
11665 if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first)))
11666 {
11667 return false;
11668 }
11669
11670 for (std::size_t i = 0; i < size_and_type.first; ++i)
11671 {
11672 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11673 {
11674 return false;
11675 }
11676 }
11677
11678 return (sax->end_array() && sax->end_object());
11679 }
11680
11681 if (size_and_type.first != npos)
11682 {
11683 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11684 {
11685 return false;
11686 }
11687
11688 if (size_and_type.second != 0)
11689 {
11690 if (size_and_type.second != 'N')
11691 {
11692 for (std::size_t i = 0; i < size_and_type.first; ++i)
11693 {
11694 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11695 {
11696 return false;
11697 }
11698 }
11699 }
11700 }
11701 else
11702 {
11703 for (std::size_t i = 0; i < size_and_type.first; ++i)
11704 {
11706 {
11707 return false;
11708 }
11709 }
11710 }
11711 }
11712 else
11713 {
11714 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11715 {
11716 return false;
11717 }
11718
11719 while (current != ']')
11720 {
11722 {
11723 return false;
11724 }
11726 }
11727 }
11728
11729 return sax->end_array();
11730 }
11731
11736 {
11737 std::pair<std::size_t, char_int_type> size_and_type;
11738 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11739 {
11740 return false;
11741 }
11742
11743 // do not accept ND-array size in objects in BJData
11744 if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
11745 {
11746 auto last_token = get_token_string();
11747 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11748 exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11749 }
11750
11751 string_t key;
11752 if (size_and_type.first != npos)
11753 {
11754 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11755 {
11756 return false;
11757 }
11758
11759 if (size_and_type.second != 0)
11760 {
11761 for (std::size_t i = 0; i < size_and_type.first; ++i)
11762 {
11764 {
11765 return false;
11766 }
11767 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11768 {
11769 return false;
11770 }
11771 key.clear();
11772 }
11773 }
11774 else
11775 {
11776 for (std::size_t i = 0; i < size_and_type.first; ++i)
11777 {
11779 {
11780 return false;
11781 }
11783 {
11784 return false;
11785 }
11786 key.clear();
11787 }
11788 }
11789 }
11790 else
11791 {
11792 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11793 {
11794 return false;
11795 }
11796
11797 while (current != '}')
11798 {
11799 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11800 {
11801 return false;
11802 }
11804 {
11805 return false;
11806 }
11808 key.clear();
11809 }
11810 }
11811
11812 return sax->end_object();
11813 }
11814
11815 // Note, no reader for UBJSON binary types is implemented because they do
11816 // not exist
11817
11819 {
11820 // get size of following number string
11821 std::size_t size{};
11822 bool no_ndarray = true;
11823 auto res = get_ubjson_size_value(size, no_ndarray);
11824 if (JSON_HEDLEY_UNLIKELY(!res))
11825 {
11826 return res;
11827 }
11828
11829 // get number string
11830 std::vector<char> number_vector;
11831 for (std::size_t i = 0; i < size; ++i)
11832 {
11833 get();
11835 {
11836 return false;
11837 }
11838 number_vector.push_back(static_cast<char>(current));
11839 }
11840
11841 // parse number string
11842 using ia_type = decltype(detail::input_adapter(number_vector));
11843 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11844 const auto result_number = number_lexer.scan();
11845 const auto number_string = number_lexer.get_token_string();
11846 const auto result_remainder = number_lexer.scan();
11847
11848 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11849
11850 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11851 {
11852 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11853 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11854 }
11855
11856 switch (result_number)
11857 {
11858 case token_type::value_integer:
11859 return sax->number_integer(number_lexer.get_number_integer());
11860 case token_type::value_unsigned:
11861 return sax->number_unsigned(number_lexer.get_number_unsigned());
11862 case token_type::value_float:
11863 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11864 case token_type::uninitialized:
11865 case token_type::literal_true:
11866 case token_type::literal_false:
11867 case token_type::literal_null:
11868 case token_type::value_string:
11869 case token_type::begin_array:
11870 case token_type::begin_object:
11871 case token_type::end_array:
11872 case token_type::end_object:
11873 case token_type::name_separator:
11874 case token_type::value_separator:
11875 case token_type::parse_error:
11876 case token_type::end_of_input:
11877 case token_type::literal_or_value:
11878 default:
11879 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11880 exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11881 }
11882 }
11883
11885 // Utility functions //
11887
11898 {
11899 ++chars_read;
11900 return current = ia.get_character();
11901 }
11902
11907 {
11908 do
11909 {
11910 get();
11911 } while (current == 'N');
11912
11913 return current;
11914 }
11915
11916 /*
11917 @brief read a number from the input
11918
11919 @tparam NumberType the type of the number
11920 @param[in] format the current format (for diagnostics)
11921 @param[out] result number of type @a NumberType
11922
11923 @return whether conversion completed
11924
11925 @note This function needs to respect the system's endianness, because
11926 bytes in CBOR, MessagePack, and UBJSON are stored in network order
11927 (big endian) and therefore need reordering on little endian systems.
11928 On the other hand, BSON and BJData use little endian and should reorder
11929 on big endian systems.
11930 */
11931 template<typename NumberType, bool InputIsLittleEndian = false>
11932 bool get_number(const input_format_t format, NumberType& result)
11933 {
11934 // step 1: read input into array with system's byte order
11935 std::array<std::uint8_t, sizeof(NumberType)> vec{};
11936 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11937 {
11938 get();
11939 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11940 {
11941 return false;
11942 }
11943
11944 // reverse byte order prior to conversion if necessary
11945 if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11946 {
11947 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11948 }
11949 else
11950 {
11951 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11952 }
11953 }
11954
11955 // step 2: convert array into number of type T and return
11956 std::memcpy(&result, vec.data(), sizeof(NumberType));
11957 return true;
11958 }
11959
11974 template<typename NumberType>
11975 bool get_string(const input_format_t format,
11976 const NumberType len,
11977 string_t& result)
11978 {
11979 bool success = true;
11980 for (NumberType i = 0; i < len; i++)
11981 {
11982 get();
11983 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11984 {
11985 success = false;
11986 break;
11987 }
11988 result.push_back(static_cast<typename string_t::value_type>(current));
11989 }
11990 return success;
11991 }
11992
12007 template<typename NumberType>
12008 bool get_binary(const input_format_t format,
12009 const NumberType len,
12010 binary_t& result)
12011 {
12012 bool success = true;
12013 for (NumberType i = 0; i < len; i++)
12014 {
12015 get();
12016 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
12017 {
12018 success = false;
12019 break;
12020 }
12021 result.push_back(static_cast<std::uint8_t>(current));
12022 }
12023 return success;
12024 }
12025
12032 bool unexpect_eof(const input_format_t format, const char* context) const
12033 {
12035 {
12036 return sax->parse_error(chars_read, "<end of file>",
12037 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
12038 }
12039 return true;
12040 }
12041
12045 std::string get_token_string() const
12046 {
12047 std::array<char, 3> cr{ {} };
12048 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
12049 return std::string{ cr.data() };
12050 }
12051
12058 std::string exception_message(const input_format_t format,
12059 const std::string& detail,
12060 const std::string& context) const
12061 {
12062 std::string error_msg = "syntax error while parsing ";
12063
12064 switch (format)
12065 {
12067 error_msg += "CBOR";
12068 break;
12069
12071 error_msg += "MessagePack";
12072 break;
12073
12075 error_msg += "UBJSON";
12076 break;
12077
12079 error_msg += "BSON";
12080 break;
12081
12083 error_msg += "BJData";
12084 break;
12085
12086 case input_format_t::json: // LCOV_EXCL_LINE
12087 default: // LCOV_EXCL_LINE
12088 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
12089 }
12090
12091 return concat(error_msg, ' ', context, ": ", detail);
12092 }
12093
12094 private:
12095 static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast<std::size_t>(-1);
12096
12098 InputAdapterType ia;
12099
12102
12104 std::size_t chars_read = 0;
12105
12108
12111
12113 json_sax_t* sax = nullptr;
12114
12115 // excluded markers in bjdata optimized type
12116#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \
12117 make_array<char_int_type>('F', 'H', 'N', 'S', 'T', 'Z', '[', '{')
12118
12119#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \
12120 make_array<bjd_type>( \
12121 bjd_type{'C', "char"}, \
12122 bjd_type{'D', "double"}, \
12123 bjd_type{'I', "int16"}, \
12124 bjd_type{'L', "int64"}, \
12125 bjd_type{'M', "uint64"}, \
12126 bjd_type{'U', "uint8"}, \
12127 bjd_type{'d', "single"}, \
12128 bjd_type{'i', "int8"}, \
12129 bjd_type{'l', "int32"}, \
12130 bjd_type{'m', "uint32"}, \
12131 bjd_type{'u', "uint16"})
12132
12134 // lookup tables
12135 // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12136 const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers =
12138
12139 using bjd_type = std::pair<char_int_type, string_t>;
12140 // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
12143
12144#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
12145#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
12146 };
12147
12148#ifndef JSON_HAS_CPP_17
12149 template<typename BasicJsonType, typename InputAdapterType, typename SAX>
12151#endif
12152
12153} // namespace detail
12155
12156// #include <nlohmann/detail/input/input_adapters.hpp>
12157
12158// #include <nlohmann/detail/input/lexer.hpp>
12159
12160// #include <nlohmann/detail/input/parser.hpp>
12161// __ _____ _____ _____
12162// __| | __| | | | JSON for Modern C++
12163// | | |__ | | | | | | version 3.11.3
12164// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12165//
12166// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12167// SPDX-License-Identifier: MIT
12168
12169
12170
12171#include <cmath> // isfinite
12172#include <cstdint> // uint8_t
12173#include <functional> // function
12174#include <string> // string
12175#include <utility> // move
12176#include <vector> // vector
12177
12178// #include <nlohmann/detail/exceptions.hpp>
12179
12180// #include <nlohmann/detail/input/input_adapters.hpp>
12181
12182// #include <nlohmann/detail/input/json_sax.hpp>
12183
12184// #include <nlohmann/detail/input/lexer.hpp>
12185
12186// #include <nlohmann/detail/macro_scope.hpp>
12187
12188// #include <nlohmann/detail/meta/is_sax.hpp>
12189
12190// #include <nlohmann/detail/string_concat.hpp>
12191
12192// #include <nlohmann/detail/value_t.hpp>
12193
12194
12196namespace detail
12197{
12199 // parser //
12201
12217
12218 template<typename BasicJsonType>
12220 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
12221
12227 template<typename BasicJsonType, typename InputAdapterType>
12229 {
12230 using number_integer_t = typename BasicJsonType::number_integer_t;
12231 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12232 using number_float_t = typename BasicJsonType::number_float_t;
12233 using string_t = typename BasicJsonType::string_t;
12236
12237 public:
12239 explicit parser(InputAdapterType&& adapter,
12240 const parser_callback_t<BasicJsonType> cb = nullptr,
12241 const bool allow_exceptions_ = true,
12242 const bool skip_comments = false)
12243 : callback(cb)
12244 , m_lexer(std::move(adapter), skip_comments)
12245 , allow_exceptions(allow_exceptions_)
12246 {
12247 // read first token
12248 get_token();
12249 }
12250
12261 void parse(const bool strict, BasicJsonType& result)
12262 {
12263 if (callback)
12264 {
12266 sax_parse_internal(&sdp);
12267
12268 // in strict mode, input must be completely read
12269 if (strict && (get_token() != token_type::end_of_input))
12270 {
12271 sdp.parse_error(m_lexer.get_position(),
12272 m_lexer.get_token_string(),
12273 parse_error::create(101, m_lexer.get_position(),
12274 exception_message(token_type::end_of_input, "value"), nullptr));
12275 }
12276
12277 // in case of an error, return discarded value
12278 if (sdp.is_errored())
12279 {
12280 result = value_t::discarded;
12281 return;
12282 }
12283
12284 // set top-level value to null if it was discarded by the callback
12285 // function
12286 if (result.is_discarded())
12287 {
12288 result = nullptr;
12289 }
12290 }
12291 else
12292 {
12294 sax_parse_internal(&sdp);
12295
12296 // in strict mode, input must be completely read
12297 if (strict && (get_token() != token_type::end_of_input))
12298 {
12299 sdp.parse_error(m_lexer.get_position(),
12300 m_lexer.get_token_string(),
12301 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12302 }
12303
12304 // in case of an error, return discarded value
12305 if (sdp.is_errored())
12306 {
12307 result = value_t::discarded;
12308 return;
12309 }
12310 }
12311
12312 result.assert_invariant();
12313 }
12314
12321 bool accept(const bool strict = true)
12322 {
12324 return sax_parse(&sax_acceptor, strict);
12325 }
12326
12327 template<typename SAX>
12329 bool sax_parse(SAX* sax, const bool strict = true)
12330 {
12332 const bool result = sax_parse_internal(sax);
12333
12334 // strict mode: next byte must be EOF
12335 if (result && strict && (get_token() != token_type::end_of_input))
12336 {
12337 return sax->parse_error(m_lexer.get_position(),
12338 m_lexer.get_token_string(),
12339 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
12340 }
12341
12342 return result;
12343 }
12344
12345 private:
12346 template<typename SAX>
12348 bool sax_parse_internal(SAX* sax)
12349 {
12350 // stack to remember the hierarchy of structured values we are parsing
12351 // true = array; false = object
12352 std::vector<bool> states;
12353 // value to avoid a goto (see comment where set to true)
12354 bool skip_to_state_evaluation = false;
12355
12356 while (true)
12357 {
12358 if (!skip_to_state_evaluation)
12359 {
12360 // invariant: get_token() was called before each iteration
12361 switch (last_token)
12362 {
12363 case token_type::begin_object:
12364 {
12365 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
12366 {
12367 return false;
12368 }
12369
12370 // closing } -> we are done
12371 if (get_token() == token_type::end_object)
12372 {
12373 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12374 {
12375 return false;
12376 }
12377 break;
12378 }
12379
12380 // parse key
12381 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
12382 {
12383 return sax->parse_error(m_lexer.get_position(),
12384 m_lexer.get_token_string(),
12385 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12386 }
12387 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12388 {
12389 return false;
12390 }
12391
12392 // parse separator (:)
12393 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12394 {
12395 return sax->parse_error(m_lexer.get_position(),
12396 m_lexer.get_token_string(),
12397 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12398 }
12399
12400 // remember we are now inside an object
12401 states.push_back(false);
12402
12403 // parse values
12404 get_token();
12405 continue;
12406 }
12407
12408 case token_type::begin_array:
12409 {
12410 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
12411 {
12412 return false;
12413 }
12414
12415 // closing ] -> we are done
12416 if (get_token() == token_type::end_array)
12417 {
12418 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12419 {
12420 return false;
12421 }
12422 break;
12423 }
12424
12425 // remember we are now inside an array
12426 states.push_back(true);
12427
12428 // parse values (no need to call get_token)
12429 continue;
12430 }
12431
12432 case token_type::value_float:
12433 {
12434 const auto res = m_lexer.get_number_float();
12435
12436 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
12437 {
12438 return sax->parse_error(m_lexer.get_position(),
12439 m_lexer.get_token_string(),
12440 out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
12441 }
12442
12443 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
12444 {
12445 return false;
12446 }
12447
12448 break;
12449 }
12450
12451 case token_type::literal_false:
12452 {
12453 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
12454 {
12455 return false;
12456 }
12457 break;
12458 }
12459
12460 case token_type::literal_null:
12461 {
12462 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
12463 {
12464 return false;
12465 }
12466 break;
12467 }
12468
12469 case token_type::literal_true:
12470 {
12471 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
12472 {
12473 return false;
12474 }
12475 break;
12476 }
12477
12478 case token_type::value_integer:
12479 {
12480 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
12481 {
12482 return false;
12483 }
12484 break;
12485 }
12486
12487 case token_type::value_string:
12488 {
12489 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
12490 {
12491 return false;
12492 }
12493 break;
12494 }
12495
12496 case token_type::value_unsigned:
12497 {
12498 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12499 {
12500 return false;
12501 }
12502 break;
12503 }
12504
12505 case token_type::parse_error:
12506 {
12507 // using "uninitialized" to avoid "expected" message
12508 return sax->parse_error(m_lexer.get_position(),
12509 m_lexer.get_token_string(),
12510 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12511 }
12512 case token_type::end_of_input:
12513 {
12514 if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))
12515 {
12516 return sax->parse_error(m_lexer.get_position(),
12517 m_lexer.get_token_string(),
12518 parse_error::create(101, m_lexer.get_position(),
12519 "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
12520 }
12521
12522 return sax->parse_error(m_lexer.get_position(),
12523 m_lexer.get_token_string(),
12524 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12525 }
12526 case token_type::uninitialized:
12527 case token_type::end_array:
12528 case token_type::end_object:
12529 case token_type::name_separator:
12530 case token_type::value_separator:
12531 case token_type::literal_or_value:
12532 default: // the last token was unexpected
12533 {
12534 return sax->parse_error(m_lexer.get_position(),
12535 m_lexer.get_token_string(),
12536 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12537 }
12538 }
12539 }
12540 else
12541 {
12542 skip_to_state_evaluation = false;
12543 }
12544
12545 // we reached this line after we successfully parsed a value
12546 if (states.empty())
12547 {
12548 // empty stack: we reached the end of the hierarchy: done
12549 return true;
12550 }
12551
12552 if (states.back()) // array
12553 {
12554 // comma -> next value
12555 if (get_token() == token_type::value_separator)
12556 {
12557 // parse a new value
12558 get_token();
12559 continue;
12560 }
12561
12562 // closing ]
12563 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12564 {
12565 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12566 {
12567 return false;
12568 }
12569
12570 // We are done with this array. Before we can parse a
12571 // new value, we need to evaluate the new state first.
12572 // By setting skip_to_state_evaluation to false, we
12573 // are effectively jumping to the beginning of this if.
12574 JSON_ASSERT(!states.empty());
12575 states.pop_back();
12576 skip_to_state_evaluation = true;
12577 continue;
12578 }
12579
12580 return sax->parse_error(m_lexer.get_position(),
12581 m_lexer.get_token_string(),
12582 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12583 }
12584
12585 // states.back() is false -> object
12586
12587 // comma -> next value
12588 if (get_token() == token_type::value_separator)
12589 {
12590 // parse key
12591 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
12592 {
12593 return sax->parse_error(m_lexer.get_position(),
12594 m_lexer.get_token_string(),
12595 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12596 }
12597
12598 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12599 {
12600 return false;
12601 }
12602
12603 // parse separator (:)
12604 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12605 {
12606 return sax->parse_error(m_lexer.get_position(),
12607 m_lexer.get_token_string(),
12608 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12609 }
12610
12611 // parse values
12612 get_token();
12613 continue;
12614 }
12615
12616 // closing }
12617 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12618 {
12619 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12620 {
12621 return false;
12622 }
12623
12624 // We are done with this object. Before we can parse a
12625 // new value, we need to evaluate the new state first.
12626 // By setting skip_to_state_evaluation to false, we
12627 // are effectively jumping to the beginning of this if.
12628 JSON_ASSERT(!states.empty());
12629 states.pop_back();
12630 skip_to_state_evaluation = true;
12631 continue;
12632 }
12633
12634 return sax->parse_error(m_lexer.get_position(),
12635 m_lexer.get_token_string(),
12636 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12637 }
12638 }
12639
12642 {
12643 return last_token = m_lexer.scan();
12644 }
12645
12646 std::string exception_message(const token_type expected, const std::string& context)
12647 {
12648 std::string error_msg = "syntax error ";
12649
12650 if (!context.empty())
12651 {
12652 error_msg += concat("while parsing ", context, ' ');
12653 }
12654
12655 error_msg += "- ";
12656
12657 if (last_token == token_type::parse_error)
12658 {
12659 error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12660 m_lexer.get_token_string(), '\'');
12661 }
12662 else
12663 {
12664 error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12665 }
12666
12667 if (expected != token_type::uninitialized)
12668 {
12669 error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12670 }
12671
12672 return error_msg;
12673 }
12674
12675 private:
12679 token_type last_token = token_type::uninitialized;
12683 const bool allow_exceptions = true;
12684 };
12685
12686} // namespace detail
12688
12689// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12690// __ _____ _____ _____
12691// __| | __| | | | JSON for Modern C++
12692// | | |__ | | | | | | version 3.11.3
12693// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12694//
12695// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12696// SPDX-License-Identifier: MIT
12697
12698
12699
12700// #include <nlohmann/detail/abi_macros.hpp>
12701
12702// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12703// __ _____ _____ _____
12704// __| | __| | | | JSON for Modern C++
12705// | | |__ | | | | | | version 3.11.3
12706// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12707//
12708// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12709// SPDX-License-Identifier: MIT
12710
12711
12712
12713#include <cstddef> // ptrdiff_t
12714#include <limits> // numeric_limits
12715
12716// #include <nlohmann/detail/macro_scope.hpp>
12717
12718
12720namespace detail
12721{
12722
12723 /*
12724 @brief an iterator for primitive JSON types
12725
12726 This class models an iterator for primitive JSON types (boolean, number,
12727 string). It's only purpose is to allow the iterator/const_iterator classes
12728 to "iterate" over primitive values. Internally, the iterator is modeled by
12729 a `difference_type` variable. Value begin_value (`0`) models the begin,
12730 end_value (`1`) models past the end.
12731 */
12733 {
12734 private:
12735 using difference_type = std::ptrdiff_t;
12736 static constexpr difference_type begin_value = 0;
12737 static constexpr difference_type end_value = begin_value + 1;
12738
12741 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12742
12743 public:
12744 constexpr difference_type get_value() const noexcept
12745 {
12746 return m_it;
12747 }
12748
12750 void set_begin() noexcept
12751 {
12752 m_it = begin_value;
12753 }
12754
12756 void set_end() noexcept
12757 {
12758 m_it = end_value;
12759 }
12760
12762 constexpr bool is_begin() const noexcept
12763 {
12764 return m_it == begin_value;
12765 }
12766
12768 constexpr bool is_end() const noexcept
12769 {
12770 return m_it == end_value;
12771 }
12772
12773 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12774 {
12775 return lhs.m_it == rhs.m_it;
12776 }
12777
12778 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12779 {
12780 return lhs.m_it < rhs.m_it;
12781 }
12782
12784 {
12785 auto result = *this;
12786 result += n;
12787 return result;
12788 }
12789
12791 {
12792 return lhs.m_it - rhs.m_it;
12793 }
12794
12796 {
12797 ++m_it;
12798 return *this;
12799 }
12800
12801 primitive_iterator_t operator++(int)&noexcept // NOLINT(cert-dcl21-cpp)
12802 {
12803 auto result = *this;
12804 ++m_it;
12805 return result;
12806 }
12807
12809 {
12810 --m_it;
12811 return *this;
12812 }
12813
12814 primitive_iterator_t operator--(int)&noexcept // NOLINT(cert-dcl21-cpp)
12815 {
12816 auto result = *this;
12817 --m_it;
12818 return result;
12819 }
12820
12822 {
12823 m_it += n;
12824 return *this;
12825 }
12826
12828 {
12829 m_it -= n;
12830 return *this;
12831 }
12832 };
12833
12834} // namespace detail
12836
12837
12839namespace detail
12840{
12841
12848 template<typename BasicJsonType> struct internal_iterator
12849 {
12851 typename BasicJsonType::object_t::iterator object_iterator{};
12853 typename BasicJsonType::array_t::iterator array_iterator{};
12856 };
12857
12858} // namespace detail
12860
12861// #include <nlohmann/detail/iterators/iter_impl.hpp>
12862// __ _____ _____ _____
12863// __| | __| | | | JSON for Modern C++
12864// | | |__ | | | | | | version 3.11.3
12865// |_____|_____|_____|_|___| https://github.com/nlohmann/json
12866//
12867// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
12868// SPDX-License-Identifier: MIT
12869
12870
12871
12872#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12873#include <type_traits> // conditional, is_const, remove_const
12874
12875// #include <nlohmann/detail/exceptions.hpp>
12876
12877// #include <nlohmann/detail/iterators/internal_iterator.hpp>
12878
12879// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12880
12881// #include <nlohmann/detail/macro_scope.hpp>
12882
12883// #include <nlohmann/detail/meta/cpp_future.hpp>
12884
12885// #include <nlohmann/detail/meta/type_traits.hpp>
12886
12887// #include <nlohmann/detail/value_t.hpp>
12888
12889
12891namespace detail
12892{
12893
12894 // forward declare, to be able to friend it later on
12895 template<typename IteratorType> class iteration_proxy;
12896 template<typename IteratorType> class iteration_proxy_value;
12897
12914 template<typename BasicJsonType>
12915 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12916 {
12918 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
12924
12925 using object_t = typename BasicJsonType::object_t;
12926 using array_t = typename BasicJsonType::array_t;
12927 // make sure BasicJsonType is basic_json or const basic_json
12929 "iter_impl only accepts (const) basic_json");
12930 // superficial check for the LegacyBidirectionalIterator named requirement
12931 static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12932 && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12933 "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12934
12935 public:
12941 using iterator_category = std::bidirectional_iterator_tag;
12942
12944 using value_type = typename BasicJsonType::value_type;
12946 using difference_type = typename BasicJsonType::difference_type;
12948 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12949 typename BasicJsonType::const_pointer,
12950 typename BasicJsonType::pointer>::type;
12953 typename std::conditional<std::is_const<BasicJsonType>::value,
12954 typename BasicJsonType::const_reference,
12955 typename BasicJsonType::reference>::type;
12956
12957 iter_impl() = default;
12958 ~iter_impl() = default;
12959 iter_impl(iter_impl&&) noexcept = default;
12960 iter_impl& operator=(iter_impl&&) noexcept = default;
12961
12968 explicit iter_impl(pointer object) noexcept : m_object(object)
12969 {
12970 JSON_ASSERT(m_object != nullptr);
12971
12972 switch (m_object->m_data.m_type)
12973 {
12974 case value_t::object:
12975 {
12976 m_it.object_iterator = typename object_t::iterator();
12977 break;
12978 }
12979
12980 case value_t::array:
12981 {
12982 m_it.array_iterator = typename array_t::iterator();
12983 break;
12984 }
12985
12986 case value_t::null:
12987 case value_t::string:
12988 case value_t::boolean:
12992 case value_t::binary:
12993 case value_t::discarded:
12994 default:
12995 {
12996 m_it.primitive_iterator = primitive_iterator_t();
12997 break;
12998 }
12999 }
13000 }
13001
13010
13019 : m_object(other.m_object), m_it(other.m_it)
13020 {}
13021
13029 {
13030 if (&other != this)
13031 {
13032 m_object = other.m_object;
13033 m_it = other.m_it;
13034 }
13035 return *this;
13036 }
13037
13043 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
13044 : m_object(other.m_object), m_it(other.m_it)
13045 {}
13046
13053 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
13054 {
13055 m_object = other.m_object;
13056 m_it = other.m_it;
13057 return *this;
13058 }
13059
13065 void set_begin() noexcept
13066 {
13067 JSON_ASSERT(m_object != nullptr);
13068
13069 switch (m_object->m_data.m_type)
13070 {
13071 case value_t::object:
13072 {
13073 m_it.object_iterator = m_object->m_data.m_value.object->begin();
13074 break;
13075 }
13076
13077 case value_t::array:
13078 {
13079 m_it.array_iterator = m_object->m_data.m_value.array->begin();
13080 break;
13081 }
13082
13083 case value_t::null:
13084 {
13085 // set to end so begin()==end() is true: null is empty
13086 m_it.primitive_iterator.set_end();
13087 break;
13088 }
13089
13090 case value_t::string:
13091 case value_t::boolean:
13095 case value_t::binary:
13096 case value_t::discarded:
13097 default:
13098 {
13099 m_it.primitive_iterator.set_begin();
13100 break;
13101 }
13102 }
13103 }
13104
13109 void set_end() noexcept
13110 {
13111 JSON_ASSERT(m_object != nullptr);
13112
13113 switch (m_object->m_data.m_type)
13114 {
13115 case value_t::object:
13116 {
13117 m_it.object_iterator = m_object->m_data.m_value.object->end();
13118 break;
13119 }
13120
13121 case value_t::array:
13122 {
13123 m_it.array_iterator = m_object->m_data.m_value.array->end();
13124 break;
13125 }
13126
13127 case value_t::null:
13128 case value_t::string:
13129 case value_t::boolean:
13133 case value_t::binary:
13134 case value_t::discarded:
13135 default:
13136 {
13137 m_it.primitive_iterator.set_end();
13138 break;
13139 }
13140 }
13141 }
13142
13143 public:
13149 {
13150 JSON_ASSERT(m_object != nullptr);
13151
13152 switch (m_object->m_data.m_type)
13153 {
13154 case value_t::object:
13155 {
13156 JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13157 return m_it.object_iterator->second;
13158 }
13159
13160 case value_t::array:
13161 {
13162 JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13163 return *m_it.array_iterator;
13164 }
13165
13166 case value_t::null:
13167 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13168
13169 case value_t::string:
13170 case value_t::boolean:
13174 case value_t::binary:
13175 case value_t::discarded:
13176 default:
13177 {
13178 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13179 {
13180 return *m_object;
13181 }
13182
13183 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13184 }
13185 }
13186 }
13187
13193 {
13194 JSON_ASSERT(m_object != nullptr);
13195
13196 switch (m_object->m_data.m_type)
13197 {
13198 case value_t::object:
13199 {
13200 JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end());
13201 return &(m_it.object_iterator->second);
13202 }
13203
13204 case value_t::array:
13205 {
13206 JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end());
13207 return &*m_it.array_iterator;
13208 }
13209
13210 case value_t::null:
13211 case value_t::string:
13212 case value_t::boolean:
13216 case value_t::binary:
13217 case value_t::discarded:
13218 default:
13219 {
13220 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
13221 {
13222 return m_object;
13223 }
13224
13225 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13226 }
13227 }
13228 }
13229
13234 iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
13235 {
13236 auto result = *this;
13237 ++(*this);
13238 return result;
13239 }
13240
13246 {
13247 JSON_ASSERT(m_object != nullptr);
13248
13249 switch (m_object->m_data.m_type)
13250 {
13251 case value_t::object:
13252 {
13253 std::advance(m_it.object_iterator, 1);
13254 break;
13255 }
13256
13257 case value_t::array:
13258 {
13259 std::advance(m_it.array_iterator, 1);
13260 break;
13261 }
13262
13263 case value_t::null:
13264 case value_t::string:
13265 case value_t::boolean:
13269 case value_t::binary:
13270 case value_t::discarded:
13271 default:
13272 {
13273 ++m_it.primitive_iterator;
13274 break;
13275 }
13276 }
13277
13278 return *this;
13279 }
13280
13285 iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
13286 {
13287 auto result = *this;
13288 --(*this);
13289 return result;
13290 }
13291
13297 {
13298 JSON_ASSERT(m_object != nullptr);
13299
13300 switch (m_object->m_data.m_type)
13301 {
13302 case value_t::object:
13303 {
13304 std::advance(m_it.object_iterator, -1);
13305 break;
13306 }
13307
13308 case value_t::array:
13309 {
13310 std::advance(m_it.array_iterator, -1);
13311 break;
13312 }
13313
13314 case value_t::null:
13315 case value_t::string:
13316 case value_t::boolean:
13320 case value_t::binary:
13321 case value_t::discarded:
13322 default:
13323 {
13324 --m_it.primitive_iterator;
13325 break;
13326 }
13327 }
13328
13329 return *this;
13330 }
13331
13336 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 >
13337 bool operator==(const IterImpl& other) const
13338 {
13339 // if objects are not the same, the comparison is undefined
13340 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13341 {
13342 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13343 }
13344
13345 JSON_ASSERT(m_object != nullptr);
13346
13347 switch (m_object->m_data.m_type)
13348 {
13349 case value_t::object:
13350 return (m_it.object_iterator == other.m_it.object_iterator);
13351
13352 case value_t::array:
13353 return (m_it.array_iterator == other.m_it.array_iterator);
13354
13355 case value_t::null:
13356 case value_t::string:
13357 case value_t::boolean:
13361 case value_t::binary:
13362 case value_t::discarded:
13363 default:
13364 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
13365 }
13366 }
13367
13372 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 >
13373 bool operator!=(const IterImpl& other) const
13374 {
13375 return !operator==(other);
13376 }
13377
13382 bool operator<(const iter_impl& other) const
13383 {
13384 // if objects are not the same, the comparison is undefined
13385 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
13386 {
13387 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
13388 }
13389
13390 JSON_ASSERT(m_object != nullptr);
13391
13392 switch (m_object->m_data.m_type)
13393 {
13394 case value_t::object:
13395 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
13396
13397 case value_t::array:
13398 return (m_it.array_iterator < other.m_it.array_iterator);
13399
13400 case value_t::null:
13401 case value_t::string:
13402 case value_t::boolean:
13406 case value_t::binary:
13407 case value_t::discarded:
13408 default:
13409 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
13410 }
13411 }
13412
13417 bool operator<=(const iter_impl& other) const
13418 {
13419 return !other.operator < (*this);
13420 }
13421
13426 bool operator>(const iter_impl& other) const
13427 {
13428 return !operator<=(other);
13429 }
13430
13435 bool operator>=(const iter_impl& other) const
13436 {
13437 return !operator<(other);
13438 }
13439
13445 {
13446 JSON_ASSERT(m_object != nullptr);
13447
13448 switch (m_object->m_data.m_type)
13449 {
13450 case value_t::object:
13451 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13452
13453 case value_t::array:
13454 {
13455 std::advance(m_it.array_iterator, i);
13456 break;
13457 }
13458
13459 case value_t::null:
13460 case value_t::string:
13461 case value_t::boolean:
13465 case value_t::binary:
13466 case value_t::discarded:
13467 default:
13468 {
13469 m_it.primitive_iterator += i;
13470 break;
13471 }
13472 }
13473
13474 return *this;
13475 }
13476
13482 {
13483 return operator+=(-i);
13484 }
13485
13491 {
13492 auto result = *this;
13493 result += i;
13494 return result;
13495 }
13496
13502 {
13503 auto result = it;
13504 result += i;
13505 return result;
13506 }
13507
13513 {
13514 auto result = *this;
13515 result -= i;
13516 return result;
13517 }
13518
13524 {
13525 JSON_ASSERT(m_object != nullptr);
13526
13527 switch (m_object->m_data.m_type)
13528 {
13529 case value_t::object:
13530 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
13531
13532 case value_t::array:
13533 return m_it.array_iterator - other.m_it.array_iterator;
13534
13535 case value_t::null:
13536 case value_t::string:
13537 case value_t::boolean:
13541 case value_t::binary:
13542 case value_t::discarded:
13543 default:
13544 return m_it.primitive_iterator - other.m_it.primitive_iterator;
13545 }
13546 }
13547
13553 {
13554 JSON_ASSERT(m_object != nullptr);
13555
13556 switch (m_object->m_data.m_type)
13557 {
13558 case value_t::object:
13559 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13560
13561 case value_t::array:
13562 return *std::next(m_it.array_iterator, n);
13563
13564 case value_t::null:
13565 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13566
13567 case value_t::string:
13568 case value_t::boolean:
13572 case value_t::binary:
13573 case value_t::discarded:
13574 default:
13575 {
13576 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
13577 {
13578 return *m_object;
13579 }
13580
13581 JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13582 }
13583 }
13584 }
13585
13590 const typename object_t::key_type& key() const
13591 {
13592 JSON_ASSERT(m_object != nullptr);
13593
13594 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13595 {
13596 return m_it.object_iterator->first;
13597 }
13598
13599 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13600 }
13601
13607 {
13608 return operator*();
13609 }
13610
13613 pointer m_object = nullptr;
13616 };
13617
13618} // namespace detail
13620
13621// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13622
13623// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13624// __ _____ _____ _____
13625// __| | __| | | | JSON for Modern C++
13626// | | |__ | | | | | | version 3.11.3
13627// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13628//
13629// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13630// SPDX-License-Identifier: MIT
13631
13632
13633
13634#include <cstddef> // ptrdiff_t
13635#include <iterator> // reverse_iterator
13636#include <utility> // declval
13637
13638// #include <nlohmann/detail/abi_macros.hpp>
13639
13640
13642namespace detail
13643{
13644
13646 // reverse_iterator //
13648
13667 template<typename Base>
13668 class json_reverse_iterator : public std::reverse_iterator<Base>
13669 {
13670 public:
13671 using difference_type = std::ptrdiff_t;
13673 using base_iterator = std::reverse_iterator<Base>;
13675 using reference = typename Base::reference;
13676
13678 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13679 : base_iterator(it) {}
13680
13682 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13683
13685 json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13686 {
13687 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13688 }
13689
13692 {
13693 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13694 }
13695
13697 json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13698 {
13699 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13700 }
13701
13704 {
13705 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13706 }
13707
13710 {
13711 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13712 }
13713
13716 {
13717 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13718 }
13719
13722 {
13723 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13724 }
13725
13728 {
13729 return base_iterator(*this) - base_iterator(other);
13730 }
13731
13734 {
13735 return *(this->operator+(n));
13736 }
13737
13739 auto key() const -> decltype(std::declval<Base>().key())
13740 {
13741 auto it = --this->base();
13742 return it.key();
13743 }
13744
13747 {
13748 auto it = --this->base();
13749 return it.operator * ();
13750 }
13751 };
13752
13753} // namespace detail
13755
13756// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13757
13758// #include <nlohmann/detail/json_custom_base_class.hpp>
13759// __ _____ _____ _____
13760// __| | __| | | | JSON for Modern C++
13761// | | |__ | | | | | | version 3.11.3
13762// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13763//
13764// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13765// SPDX-License-Identifier: MIT
13766
13767
13768
13769#include <type_traits> // conditional, is_same
13770
13771// #include <nlohmann/detail/abi_macros.hpp>
13772
13773
13775namespace detail
13776{
13777
13789
13790 template<class T>
13791 using json_base_class = typename std::conditional <
13792 std::is_same<T, void>::value,
13794 T
13795 >::type;
13796
13797} // namespace detail
13799
13800// #include <nlohmann/detail/json_pointer.hpp>
13801// __ _____ _____ _____
13802// __| | __| | | | JSON for Modern C++
13803// | | |__ | | | | | | version 3.11.3
13804// |_____|_____|_____|_|___| https://github.com/nlohmann/json
13805//
13806// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
13807// SPDX-License-Identifier: MIT
13808
13809
13810
13811#include <algorithm> // all_of
13812#include <cctype> // isdigit
13813#include <cerrno> // errno, ERANGE
13814#include <cstdlib> // strtoull
13815#ifndef JSON_NO_IO
13816#include <iosfwd> // ostream
13817#endif // JSON_NO_IO
13818#include <limits> // max
13819#include <numeric> // accumulate
13820#include <string> // string
13821#include <utility> // move
13822#include <vector> // vector
13823
13824// #include <nlohmann/detail/exceptions.hpp>
13825
13826// #include <nlohmann/detail/macro_scope.hpp>
13827
13828// #include <nlohmann/detail/string_concat.hpp>
13829
13830// #include <nlohmann/detail/string_escape.hpp>
13831
13832// #include <nlohmann/detail/value_t.hpp>
13833
13834
13836
13839template<typename RefStringType>
13841{
13842 // allow basic_json to access private members
13844 friend class basic_json;
13845
13846 template<typename>
13847 friend class json_pointer;
13848
13849 template<typename T>
13851 {
13852 using type = T;
13853 };
13854
13857 {
13858 using type = StringType;
13859 };
13860
13861public:
13862 // for backwards compatibility accept BasicJsonType
13864
13867 explicit json_pointer(const string_t& s = "")
13869 {}
13870
13874 {
13875 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13876 string_t{},
13877 [](const string_t& a, const string_t& b)
13878 {
13879 return detail::concat(a, '/', detail::escape(b));
13880 });
13881 }
13882
13886 operator string_t() const
13887 {
13888 return to_string();
13889 }
13890
13891#ifndef JSON_NO_IO
13894 friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
13895 {
13896 o << ptr.to_string();
13897 return o;
13898 }
13899#endif
13900
13904 {
13906 ptr.reference_tokens.begin(),
13907 ptr.reference_tokens.end());
13908 return *this;
13909 }
13910
13914 {
13915 push_back(std::move(token));
13916 return *this;
13917 }
13918
13921 json_pointer& operator/=(std::size_t array_idx)
13922 {
13923 return *this /= std::to_string(array_idx);
13924 }
13925
13929 const json_pointer& rhs)
13930 {
13931 return json_pointer(lhs) /= rhs;
13932 }
13933
13936 friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13937 {
13938 return json_pointer(lhs) /= std::move(token);
13939 }
13940
13943 friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13944 {
13945 return json_pointer(lhs) /= array_idx;
13946 }
13947
13951 {
13952 if (empty())
13953 {
13954 return *this;
13955 }
13956
13957 json_pointer res = *this;
13958 res.pop_back();
13959 return res;
13960 }
13961
13965 {
13967 {
13968 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13969 }
13970
13971 reference_tokens.pop_back();
13972 }
13973
13976 const string_t& back() const
13977 {
13979 {
13980 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13981 }
13982
13983 return reference_tokens.back();
13984 }
13985
13988 void push_back(const string_t& token)
13989 {
13990 reference_tokens.push_back(token);
13991 }
13992
13995 void push_back(string_t&& token)
13996 {
13997 reference_tokens.push_back(std::move(token));
13998 }
13999
14002 bool empty() const noexcept
14003 {
14004 return reference_tokens.empty();
14005 }
14006
14007private:
14018 template<typename BasicJsonType>
14019 static typename BasicJsonType::size_type array_index(const string_t& s)
14020 {
14021 using size_type = typename BasicJsonType::size_type;
14022
14023 // error condition (cf. RFC 6901, Sect. 4)
14024 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
14025 {
14026 JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
14027 }
14028
14029 // error condition (cf. RFC 6901, Sect. 4)
14030 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
14031 {
14032 JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
14033 }
14034
14035 const char* p = s.c_str();
14036 char* p_end = nullptr;
14037 errno = 0; // strtoull doesn't reset errno
14038 const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
14039 if (p == p_end // invalid input or empty string
14040 || errno == ERANGE // out of range
14041 || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
14042 {
14043 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
14044 }
14045
14046 // only triggered on special platforms (like 32bit), see also
14047 // https://github.com/nlohmann/json/pull/2203
14048 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
14049 {
14050 JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
14051 }
14052
14053 return static_cast<size_type>(res);
14054 }
14055
14057 json_pointer top() const
14058 {
14060 {
14061 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
14062 }
14063
14065 result.reference_tokens = { reference_tokens[0] };
14066 return result;
14067 }
14068
14069private:
14078 template<typename BasicJsonType>
14079 BasicJsonType& get_and_create(BasicJsonType& j) const
14080 {
14081 auto* result = &j;
14082
14083 // in case no reference tokens exist, return a reference to the JSON value
14084 // j which will be overwritten by a primitive value
14085 for (const auto& reference_token : reference_tokens)
14086 {
14087 switch (result->type())
14088 {
14090 {
14091 if (reference_token == "0")
14092 {
14093 // start a new array if reference token is 0
14094 result = &result->operator[](0);
14095 }
14096 else
14097 {
14098 // start a new object otherwise
14099 result = &result->operator[](reference_token);
14100 }
14101 break;
14102 }
14103
14105 {
14106 // create an entry in the object
14107 result = &result->operator[](reference_token);
14108 break;
14109 }
14110
14112 {
14113 // create an entry in the array
14114 result = &result->operator[](array_index<BasicJsonType>(reference_token));
14115 break;
14116 }
14117
14118 /*
14119 The following code is only reached if there exists a reference
14120 token _and_ the current value is primitive. In this case, we have
14121 an error situation, because primitive values may only occur as
14122 single value; that is, with an empty list of reference tokens.
14123 */
14131 default:
14132 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
14133 }
14134 }
14135
14136 return *result;
14137 }
14138
14158 template<typename BasicJsonType>
14159 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
14160 {
14161 for (const auto& reference_token : reference_tokens)
14162 {
14163 // convert null values to arrays or objects before continuing
14164 if (ptr->is_null())
14165 {
14166 // check if reference token is a number
14167 const bool nums =
14168 std::all_of(reference_token.begin(), reference_token.end(),
14169 [](const unsigned char x)
14170 {
14171 return std::isdigit(x);
14172 });
14173
14174 // change value to array for numbers or "-" or to object otherwise
14175 *ptr = (nums || reference_token == "-")
14178 }
14179
14180 switch (ptr->type())
14181 {
14183 {
14184 // use unchecked object access
14185 ptr = &ptr->operator[](reference_token);
14186 break;
14187 }
14188
14190 {
14191 if (reference_token == "-")
14192 {
14193 // explicitly treat "-" as index beyond the end
14194 ptr = &ptr->operator[](ptr->m_data.m_value.array->size());
14195 }
14196 else
14197 {
14198 // convert array index to number; unchecked access
14199 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14200 }
14201 break;
14202 }
14203
14212 default:
14213 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14214 }
14215 }
14216
14217 return *ptr;
14218 }
14219
14226 template<typename BasicJsonType>
14227 BasicJsonType& get_checked(BasicJsonType* ptr) const
14228 {
14229 for (const auto& reference_token : reference_tokens)
14230 {
14231 switch (ptr->type())
14232 {
14234 {
14235 // note: at performs range check
14236 ptr = &ptr->at(reference_token);
14237 break;
14238 }
14239
14241 {
14242 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14243 {
14244 // "-" always fails the range check
14246 "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14247 ") is out of range"), ptr));
14248 }
14249
14250 // note: at performs range check
14251 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14252 break;
14253 }
14254
14263 default:
14264 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14265 }
14266 }
14267
14268 return *ptr;
14269 }
14270
14284 template<typename BasicJsonType>
14285 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
14286 {
14287 for (const auto& reference_token : reference_tokens)
14288 {
14289 switch (ptr->type())
14290 {
14292 {
14293 // use unchecked object access
14294 ptr = &ptr->operator[](reference_token);
14295 break;
14296 }
14297
14299 {
14300 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14301 {
14302 // "-" cannot be used for const access
14303 JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
14304 }
14305
14306 // use unchecked array access
14307 ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
14308 break;
14309 }
14310
14319 default:
14320 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14321 }
14322 }
14323
14324 return *ptr;
14325 }
14326
14333 template<typename BasicJsonType>
14334 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
14335 {
14336 for (const auto& reference_token : reference_tokens)
14337 {
14338 switch (ptr->type())
14339 {
14341 {
14342 // note: at performs range check
14343 ptr = &ptr->at(reference_token);
14344 break;
14345 }
14346
14348 {
14349 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14350 {
14351 // "-" always fails the range check
14353 "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
14354 ") is out of range"), ptr));
14355 }
14356
14357 // note: at performs range check
14358 ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
14359 break;
14360 }
14361
14370 default:
14371 JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
14372 }
14373 }
14374
14375 return *ptr;
14376 }
14377
14382 template<typename BasicJsonType>
14383 bool contains(const BasicJsonType* ptr) const
14384 {
14385 for (const auto& reference_token : reference_tokens)
14386 {
14387 switch (ptr->type())
14388 {
14390 {
14391 if (!ptr->contains(reference_token))
14392 {
14393 // we did not find the key in the object
14394 return false;
14395 }
14396
14397 ptr = &ptr->operator[](reference_token);
14398 break;
14399 }
14400
14402 {
14403 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
14404 {
14405 // "-" always fails the range check
14406 return false;
14407 }
14408 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
14409 {
14410 // invalid char
14411 return false;
14412 }
14413 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
14414 {
14415 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
14416 {
14417 // first char should be between '1' and '9'
14418 return false;
14419 }
14420 for (std::size_t i = 1; i < reference_token.size(); i++)
14421 {
14422 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
14423 {
14424 // other char should be between '0' and '9'
14425 return false;
14426 }
14427 }
14428 }
14429
14430 const auto idx = array_index<BasicJsonType>(reference_token);
14431 if (idx >= ptr->size())
14432 {
14433 // index out of range
14434 return false;
14435 }
14436
14437 ptr = &ptr->operator[](idx);
14438 break;
14439 }
14440
14449 default:
14450 {
14451 // we do not expect primitive values if there is still a
14452 // reference token to process
14453 return false;
14454 }
14455 }
14456 }
14457
14458 // no reference token left means we found a primitive value
14459 return true;
14460 }
14461
14471 static std::vector<string_t> split(const string_t& reference_string)
14472 {
14473 std::vector<string_t> result;
14474
14475 // special case: empty reference string -> no reference tokens
14476 if (reference_string.empty())
14477 {
14478 return result;
14479 }
14480
14481 // check if nonempty reference string begins with slash
14482 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
14483 {
14484 JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
14485 }
14486
14487 // extract the reference tokens:
14488 // - slash: position of the last read slash (or end of string)
14489 // - start: position after the previous slash
14490 for (
14491 // search for the first slash after the first character
14492 std::size_t slash = reference_string.find_first_of('/', 1),
14493 // set the beginning of the first reference token
14494 start = 1;
14495 // we can stop if start == 0 (if slash == string_t::npos)
14496 start != 0;
14497 // set the beginning of the next reference token
14498 // (will eventually be 0 if slash == string_t::npos)
14499 start = (slash == string_t::npos) ? 0 : slash + 1,
14500 // find next slash
14501 slash = reference_string.find_first_of('/', start))
14502 {
14503 // use the text between the beginning of the reference token
14504 // (start) and the last slash (slash).
14505 auto reference_token = reference_string.substr(start, slash - start);
14506
14507 // check reference tokens are properly escaped
14508 for (std::size_t pos = reference_token.find_first_of('~');
14509 pos != string_t::npos;
14510 pos = reference_token.find_first_of('~', pos + 1))
14511 {
14512 JSON_ASSERT(reference_token[pos] == '~');
14513
14514 // ~ must be followed by 0 or 1
14515 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
14516 (reference_token[pos + 1] != '0' &&
14517 reference_token[pos + 1] != '1')))
14518 {
14519 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
14520 }
14521 }
14522
14523 // finally, store the reference token
14524 detail::unescape(reference_token);
14525 result.push_back(reference_token);
14526 }
14527
14528 return result;
14529 }
14530
14531private:
14539 template<typename BasicJsonType>
14540 static void flatten(const string_t& reference_string,
14541 const BasicJsonType& value,
14542 BasicJsonType& result)
14543 {
14544 switch (value.type())
14545 {
14547 {
14548 if (value.m_data.m_value.array->empty())
14549 {
14550 // flatten empty array as null
14551 result[reference_string] = nullptr;
14552 }
14553 else
14554 {
14555 // iterate array and use index as reference string
14556 for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i)
14557 {
14558 flatten(detail::concat(reference_string, '/', std::to_string(i)),
14559 value.m_data.m_value.array->operator[](i), result);
14560 }
14561 }
14562 break;
14563 }
14564
14566 {
14567 if (value.m_data.m_value.object->empty())
14568 {
14569 // flatten empty object as null
14570 result[reference_string] = nullptr;
14571 }
14572 else
14573 {
14574 // iterate object and use keys as reference string
14575 for (const auto& element : *value.m_data.m_value.object)
14576 {
14577 flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
14578 }
14579 }
14580 break;
14581 }
14582
14591 default:
14592 {
14593 // add primitive value with its reference string
14594 result[reference_string] = value;
14595 break;
14596 }
14597 }
14598 }
14599
14610 template<typename BasicJsonType>
14611 static BasicJsonType
14612 unflatten(const BasicJsonType& value)
14613 {
14614 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14615 {
14616 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14617 }
14618
14619 BasicJsonType result;
14620
14621 // iterate the JSON object values
14622 for (const auto& element : *value.m_data.m_value.object)
14623 {
14624 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14625 {
14626 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14627 }
14628
14629 // assign value to reference pointed to by JSON pointer; Note that if
14630 // the JSON pointer is "" (i.e., points to the whole value), function
14631 // get_and_create returns a reference to result itself. An assignment
14632 // will then create a primitive value.
14633 json_pointer(element.first).get_and_create(result) = element.second;
14634 }
14635
14636 return result;
14637 }
14638
14639 // can't use conversion operator because of ambiguity
14641 {
14643 result.reference_tokens = reference_tokens;
14644 return result;
14645 }
14646
14648 {
14650 result.reference_tokens = std::move(reference_tokens);
14651 return result;
14652 }
14653
14654public:
14655#if JSON_HAS_THREE_WAY_COMPARISON
14658 template<typename RefStringTypeRhs>
14659 bool operator==(const json_pointer<RefStringTypeRhs>& rhs) const noexcept
14660 {
14661 return reference_tokens == rhs.reference_tokens;
14662 }
14663
14666 JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer))
14667 bool operator==(const string_t& rhs) const
14668 {
14669 return *this == json_pointer(rhs);
14670 }
14671
14673 template<typename RefStringTypeRhs>
14674 std::strong_ordering operator<=>(const json_pointer<RefStringTypeRhs>& rhs) const noexcept // *NOPAD*
14675 {
14676 return reference_tokens <=> rhs.reference_tokens; // *NOPAD*
14677 }
14678#else
14681 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14682 // NOLINTNEXTLINE(readability-redundant-declaration)
14683 friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14684 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14685
14688 template<typename RefStringTypeLhs, typename StringType>
14689 // NOLINTNEXTLINE(readability-redundant-declaration)
14690 friend bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14691 const StringType& rhs);
14692
14695 template<typename RefStringTypeRhs, typename StringType>
14696 // NOLINTNEXTLINE(readability-redundant-declaration)
14697 friend bool operator==(const StringType& lhs,
14698 const json_pointer<RefStringTypeRhs>& rhs);
14699
14702 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14703 // NOLINTNEXTLINE(readability-redundant-declaration)
14704 friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14705 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14706
14709 template<typename RefStringTypeLhs, typename StringType>
14710 // NOLINTNEXTLINE(readability-redundant-declaration)
14711 friend bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14712 const StringType& rhs);
14713
14716 template<typename RefStringTypeRhs, typename StringType>
14717 // NOLINTNEXTLINE(readability-redundant-declaration)
14718 friend bool operator!=(const StringType& lhs,
14719 const json_pointer<RefStringTypeRhs>& rhs);
14720
14722 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14723 // NOLINTNEXTLINE(readability-redundant-declaration)
14724 friend bool operator<(const json_pointer<RefStringTypeLhs>& lhs,
14725 const json_pointer<RefStringTypeRhs>& rhs) noexcept;
14726#endif
14727
14728private:
14730 std::vector<string_t> reference_tokens;
14731};
14732
14733#if !JSON_HAS_THREE_WAY_COMPARISON
14734// functions cannot be defined inside class due to ODR violations
14735template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14737 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14738{
14739 return lhs.reference_tokens == rhs.reference_tokens;
14740}
14741
14742template<typename RefStringTypeLhs,
14743 typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14745inline bool operator==(const json_pointer<RefStringTypeLhs>& lhs,
14746 const StringType& rhs)
14747{
14748 return lhs == json_pointer<RefStringTypeLhs>(rhs);
14749}
14750
14751template<typename RefStringTypeRhs,
14752 typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14754inline bool operator==(const StringType& lhs,
14755 const json_pointer<RefStringTypeRhs>& rhs)
14756{
14757 return json_pointer<RefStringTypeRhs>(lhs) == rhs;
14758}
14759
14760template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14762 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14763{
14764 return !(lhs == rhs);
14765}
14766
14767template<typename RefStringTypeLhs,
14768 typename StringType = typename json_pointer<RefStringTypeLhs>::string_t>
14770inline bool operator!=(const json_pointer<RefStringTypeLhs>& lhs,
14771 const StringType& rhs)
14772{
14773 return !(lhs == rhs);
14774}
14775
14776template<typename RefStringTypeRhs,
14777 typename StringType = typename json_pointer<RefStringTypeRhs>::string_t>
14779inline bool operator!=(const StringType& lhs,
14780 const json_pointer<RefStringTypeRhs>& rhs)
14781{
14782 return !(lhs == rhs);
14783}
14784
14785template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14787 const json_pointer<RefStringTypeRhs>& rhs) noexcept
14788{
14789 return lhs.reference_tokens < rhs.reference_tokens;
14790}
14791#endif
14792
14794
14795// #include <nlohmann/detail/json_ref.hpp>
14796// __ _____ _____ _____
14797// __| | __| | | | JSON for Modern C++
14798// | | |__ | | | | | | version 3.11.3
14799// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14800//
14801// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14802// SPDX-License-Identifier: MIT
14803
14804
14805
14806#include <initializer_list>
14807#include <utility>
14808
14809// #include <nlohmann/detail/abi_macros.hpp>
14810
14811// #include <nlohmann/detail/meta/type_traits.hpp>
14812
14813
14815namespace detail
14816{
14817
14818 template<typename BasicJsonType>
14820 {
14821 public:
14822 using value_type = BasicJsonType;
14823
14825 : owned_value(std::move(value))
14826 {}
14827
14829 : value_ref(&value)
14830 {}
14831
14832 json_ref(std::initializer_list<json_ref> init)
14833 : owned_value(init)
14834 {}
14835
14836 template <
14837 class... Args,
14838 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14839 json_ref(Args && ... args)
14840 : owned_value(std::forward<Args>(args)...)
14841 {}
14842
14843 // class should be movable only
14844 json_ref(json_ref&&) noexcept = default;
14845 json_ref(const json_ref&) = delete;
14846 json_ref& operator=(const json_ref&) = delete;
14847 json_ref& operator=(json_ref&&) = delete;
14848 ~json_ref() = default;
14849
14851 {
14852 if (value_ref == nullptr)
14853 {
14854 return std::move(owned_value);
14855 }
14856 return *value_ref;
14857 }
14858
14859 value_type const& operator*() const
14860 {
14861 return value_ref ? *value_ref : owned_value;
14862 }
14863
14864 value_type const* operator->() const
14865 {
14866 return &**this;
14867 }
14868
14869 private:
14870 mutable value_type owned_value = nullptr;
14871 value_type const* value_ref = nullptr;
14872 };
14873
14874} // namespace detail
14876
14877// #include <nlohmann/detail/macro_scope.hpp>
14878
14879// #include <nlohmann/detail/string_concat.hpp>
14880
14881// #include <nlohmann/detail/string_escape.hpp>
14882
14883// #include <nlohmann/detail/meta/cpp_future.hpp>
14884
14885// #include <nlohmann/detail/meta/type_traits.hpp>
14886
14887// #include <nlohmann/detail/output/binary_writer.hpp>
14888// __ _____ _____ _____
14889// __| | __| | | | JSON for Modern C++
14890// | | |__ | | | | | | version 3.11.3
14891// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14892//
14893// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14894// SPDX-License-Identifier: MIT
14895
14896
14897
14898#include <algorithm> // reverse
14899#include <array> // array
14900#include <map> // map
14901#include <cmath> // isnan, isinf
14902#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14903#include <cstring> // memcpy
14904#include <limits> // numeric_limits
14905#include <string> // string
14906#include <utility> // move
14907#include <vector> // vector
14908
14909// #include <nlohmann/detail/input/binary_reader.hpp>
14910
14911// #include <nlohmann/detail/macro_scope.hpp>
14912
14913// #include <nlohmann/detail/output/output_adapters.hpp>
14914// __ _____ _____ _____
14915// __| | __| | | | JSON for Modern C++
14916// | | |__ | | | | | | version 3.11.3
14917// |_____|_____|_____|_|___| https://github.com/nlohmann/json
14918//
14919// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
14920// SPDX-License-Identifier: MIT
14921
14922
14923
14924#include <algorithm> // copy
14925#include <cstddef> // size_t
14926#include <iterator> // back_inserter
14927#include <memory> // shared_ptr, make_shared
14928#include <string> // basic_string
14929#include <vector> // vector
14930
14931#ifndef JSON_NO_IO
14932#include <ios> // streamsize
14933#include <ostream> // basic_ostream
14934#endif // JSON_NO_IO
14935
14936// #include <nlohmann/detail/macro_scope.hpp>
14937
14938
14940namespace detail
14941{
14942
14944 template<typename CharType> struct output_adapter_protocol
14945 {
14946 virtual void write_character(CharType c) = 0;
14947 virtual void write_characters(const CharType* s, std::size_t length) = 0;
14948 virtual ~output_adapter_protocol() = default;
14949
14954 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
14955 };
14956
14958 template<typename CharType>
14959 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14960
14962 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14964 {
14965 public:
14966 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14967 : v(vec)
14968 {}
14969
14970 void write_character(CharType c) override
14971 {
14972 v.push_back(c);
14973 }
14974
14976 void write_characters(const CharType* s, std::size_t length) override
14977 {
14978 v.insert(v.end(), s, s + length);
14979 }
14980
14981 private:
14982 std::vector<CharType, AllocatorType>& v;
14983 };
14984
14985#ifndef JSON_NO_IO
14987 template<typename CharType>
14989 {
14990 public:
14991 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14992 : stream(s)
14993 {}
14994
14995 void write_character(CharType c) override
14996 {
14997 stream.put(c);
14998 }
14999
15001 void write_characters(const CharType* s, std::size_t length) override
15002 {
15003 stream.write(s, static_cast<std::streamsize>(length));
15004 }
15005
15006 private:
15007 std::basic_ostream<CharType>& stream;
15008 };
15009#endif // JSON_NO_IO
15010
15012 template<typename CharType, typename StringType = std::basic_string<CharType>>
15014 {
15015 public:
15016 explicit output_string_adapter(StringType& s) noexcept
15017 : str(s)
15018 {}
15019
15020 void write_character(CharType c) override
15021 {
15022 str.push_back(c);
15023 }
15024
15026 void write_characters(const CharType* s, std::size_t length) override
15027 {
15028 str.append(s, length);
15029 }
15030
15031 private:
15032 StringType& str;
15033 };
15034
15035 template<typename CharType, typename StringType = std::basic_string<CharType>>
15037 {
15038 public:
15039 template<typename AllocatorType = std::allocator<CharType>>
15040 output_adapter(std::vector<CharType, AllocatorType>& vec)
15041 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
15042
15043#ifndef JSON_NO_IO
15044 output_adapter(std::basic_ostream<CharType>& s)
15045 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
15046#endif // JSON_NO_IO
15047
15048 output_adapter(StringType& s)
15049 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
15050
15052 {
15053 return oa;
15054 }
15055
15056 private:
15058 };
15059
15060} // namespace detail
15062
15063// #include <nlohmann/detail/string_concat.hpp>
15064
15065
15067namespace detail
15068{
15069
15071 // binary writer //
15073
15077 template<typename BasicJsonType, typename CharType>
15079 {
15080 using string_t = typename BasicJsonType::string_t;
15081 using binary_t = typename BasicJsonType::binary_t;
15082 using number_float_t = typename BasicJsonType::number_float_t;
15083
15084 public:
15090 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
15091 {
15092 JSON_ASSERT(oa);
15093 }
15094
15099 void write_bson(const BasicJsonType& j)
15100 {
15101 switch (j.type())
15102 {
15103 case value_t::object:
15104 {
15105 write_bson_object(*j.m_data.m_value.object);
15106 break;
15107 }
15108
15109 case value_t::null:
15110 case value_t::array:
15111 case value_t::string:
15112 case value_t::boolean:
15116 case value_t::binary:
15117 case value_t::discarded:
15118 default:
15119 {
15120 JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
15121 }
15122 }
15123 }
15124
15128 void write_cbor(const BasicJsonType& j)
15129 {
15130 switch (j.type())
15131 {
15132 case value_t::null:
15133 {
15134 oa->write_character(to_char_type(0xF6));
15135 break;
15136 }
15137
15138 case value_t::boolean:
15139 {
15140 oa->write_character(j.m_data.m_value.boolean
15141 ? to_char_type(0xF5)
15142 : to_char_type(0xF4));
15143 break;
15144 }
15145
15147 {
15148 if (j.m_data.m_value.number_integer >= 0)
15149 {
15150 // CBOR does not differentiate between positive signed
15151 // integers and unsigned integers. Therefore, we used the
15152 // code from the value_t::number_unsigned case here.
15153 if (j.m_data.m_value.number_integer <= 0x17)
15154 {
15155 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15156 }
15157 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15158 {
15159 oa->write_character(to_char_type(0x18));
15160 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15161 }
15162 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
15163 {
15164 oa->write_character(to_char_type(0x19));
15165 write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15166 }
15167 else if (j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
15168 {
15169 oa->write_character(to_char_type(0x1A));
15170 write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15171 }
15172 else
15173 {
15174 oa->write_character(to_char_type(0x1B));
15175 write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15176 }
15177 }
15178 else
15179 {
15180 // The conversions below encode the sign in the first
15181 // byte, and the value is converted to a positive number.
15182 const auto positive_number = -1 - j.m_data.m_value.number_integer;
15183 if (j.m_data.m_value.number_integer >= -24)
15184 {
15185 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
15186 }
15187 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
15188 {
15189 oa->write_character(to_char_type(0x38));
15190 write_number(static_cast<std::uint8_t>(positive_number));
15191 }
15192 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
15193 {
15194 oa->write_character(to_char_type(0x39));
15195 write_number(static_cast<std::uint16_t>(positive_number));
15196 }
15197 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
15198 {
15199 oa->write_character(to_char_type(0x3A));
15200 write_number(static_cast<std::uint32_t>(positive_number));
15201 }
15202 else
15203 {
15204 oa->write_character(to_char_type(0x3B));
15205 write_number(static_cast<std::uint64_t>(positive_number));
15206 }
15207 }
15208 break;
15209 }
15210
15212 {
15213 if (j.m_data.m_value.number_unsigned <= 0x17)
15214 {
15215 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15216 }
15217 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15218 {
15219 oa->write_character(to_char_type(0x18));
15220 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_unsigned));
15221 }
15222 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15223 {
15224 oa->write_character(to_char_type(0x19));
15225 write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_unsigned));
15226 }
15227 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15228 {
15229 oa->write_character(to_char_type(0x1A));
15230 write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_unsigned));
15231 }
15232 else
15233 {
15234 oa->write_character(to_char_type(0x1B));
15235 write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
15236 }
15237 break;
15238 }
15239
15241 {
15242 if (std::isnan(j.m_data.m_value.number_float))
15243 {
15244 // NaN is 0xf97e00 in CBOR
15245 oa->write_character(to_char_type(0xF9));
15246 oa->write_character(to_char_type(0x7E));
15247 oa->write_character(to_char_type(0x00));
15248 }
15249 else if (std::isinf(j.m_data.m_value.number_float))
15250 {
15251 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
15252 oa->write_character(to_char_type(0xf9));
15253 oa->write_character(j.m_data.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
15254 oa->write_character(to_char_type(0x00));
15255 }
15256 else
15257 {
15258 write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::cbor);
15259 }
15260 break;
15261 }
15262
15263 case value_t::string:
15264 {
15265 // step 1: write control byte and the string length
15266 const auto N = j.m_data.m_value.string->size();
15267 if (N <= 0x17)
15268 {
15269 write_number(static_cast<std::uint8_t>(0x60 + N));
15270 }
15271 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15272 {
15273 oa->write_character(to_char_type(0x78));
15274 write_number(static_cast<std::uint8_t>(N));
15275 }
15276 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15277 {
15278 oa->write_character(to_char_type(0x79));
15279 write_number(static_cast<std::uint16_t>(N));
15280 }
15281 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15282 {
15283 oa->write_character(to_char_type(0x7A));
15284 write_number(static_cast<std::uint32_t>(N));
15285 }
15286 // LCOV_EXCL_START
15287 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15288 {
15289 oa->write_character(to_char_type(0x7B));
15290 write_number(static_cast<std::uint64_t>(N));
15291 }
15292 // LCOV_EXCL_STOP
15293
15294 // step 2: write the string
15295 oa->write_characters(
15296 reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15297 j.m_data.m_value.string->size());
15298 break;
15299 }
15300
15301 case value_t::array:
15302 {
15303 // step 1: write control byte and the array size
15304 const auto N = j.m_data.m_value.array->size();
15305 if (N <= 0x17)
15306 {
15307 write_number(static_cast<std::uint8_t>(0x80 + N));
15308 }
15309 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15310 {
15311 oa->write_character(to_char_type(0x98));
15312 write_number(static_cast<std::uint8_t>(N));
15313 }
15314 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15315 {
15316 oa->write_character(to_char_type(0x99));
15317 write_number(static_cast<std::uint16_t>(N));
15318 }
15319 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15320 {
15321 oa->write_character(to_char_type(0x9A));
15322 write_number(static_cast<std::uint32_t>(N));
15323 }
15324 // LCOV_EXCL_START
15325 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15326 {
15327 oa->write_character(to_char_type(0x9B));
15328 write_number(static_cast<std::uint64_t>(N));
15329 }
15330 // LCOV_EXCL_STOP
15331
15332 // step 2: write each element
15333 for (const auto& el : *j.m_data.m_value.array)
15334 {
15335 write_cbor(el);
15336 }
15337 break;
15338 }
15339
15340 case value_t::binary:
15341 {
15342 if (j.m_data.m_value.binary->has_subtype())
15343 {
15344 if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
15345 {
15346 write_number(static_cast<std::uint8_t>(0xd8));
15347 write_number(static_cast<std::uint8_t>(j.m_data.m_value.binary->subtype()));
15348 }
15349 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
15350 {
15351 write_number(static_cast<std::uint8_t>(0xd9));
15352 write_number(static_cast<std::uint16_t>(j.m_data.m_value.binary->subtype()));
15353 }
15354 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
15355 {
15356 write_number(static_cast<std::uint8_t>(0xda));
15357 write_number(static_cast<std::uint32_t>(j.m_data.m_value.binary->subtype()));
15358 }
15359 else if (j.m_data.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
15360 {
15361 write_number(static_cast<std::uint8_t>(0xdb));
15362 write_number(static_cast<std::uint64_t>(j.m_data.m_value.binary->subtype()));
15363 }
15364 }
15365
15366 // step 1: write control byte and the binary array size
15367 const auto N = j.m_data.m_value.binary->size();
15368 if (N <= 0x17)
15369 {
15370 write_number(static_cast<std::uint8_t>(0x40 + N));
15371 }
15372 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15373 {
15374 oa->write_character(to_char_type(0x58));
15375 write_number(static_cast<std::uint8_t>(N));
15376 }
15377 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15378 {
15379 oa->write_character(to_char_type(0x59));
15380 write_number(static_cast<std::uint16_t>(N));
15381 }
15382 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15383 {
15384 oa->write_character(to_char_type(0x5A));
15385 write_number(static_cast<std::uint32_t>(N));
15386 }
15387 // LCOV_EXCL_START
15388 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15389 {
15390 oa->write_character(to_char_type(0x5B));
15391 write_number(static_cast<std::uint64_t>(N));
15392 }
15393 // LCOV_EXCL_STOP
15394
15395 // step 2: write each element
15396 oa->write_characters(
15397 reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15398 N);
15399
15400 break;
15401 }
15402
15403 case value_t::object:
15404 {
15405 // step 1: write control byte and the object size
15406 const auto N = j.m_data.m_value.object->size();
15407 if (N <= 0x17)
15408 {
15409 write_number(static_cast<std::uint8_t>(0xA0 + N));
15410 }
15411 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15412 {
15413 oa->write_character(to_char_type(0xB8));
15414 write_number(static_cast<std::uint8_t>(N));
15415 }
15416 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15417 {
15418 oa->write_character(to_char_type(0xB9));
15419 write_number(static_cast<std::uint16_t>(N));
15420 }
15421 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15422 {
15423 oa->write_character(to_char_type(0xBA));
15424 write_number(static_cast<std::uint32_t>(N));
15425 }
15426 // LCOV_EXCL_START
15427 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
15428 {
15429 oa->write_character(to_char_type(0xBB));
15430 write_number(static_cast<std::uint64_t>(N));
15431 }
15432 // LCOV_EXCL_STOP
15433
15434 // step 2: write each element
15435 for (const auto& el : *j.m_data.m_value.object)
15436 {
15437 write_cbor(el.first);
15438 write_cbor(el.second);
15439 }
15440 break;
15441 }
15442
15443 case value_t::discarded:
15444 default:
15445 break;
15446 }
15447 }
15448
15452 void write_msgpack(const BasicJsonType& j)
15453 {
15454 switch (j.type())
15455 {
15456 case value_t::null: // nil
15457 {
15458 oa->write_character(to_char_type(0xC0));
15459 break;
15460 }
15461
15462 case value_t::boolean: // true and false
15463 {
15464 oa->write_character(j.m_data.m_value.boolean
15465 ? to_char_type(0xC3)
15466 : to_char_type(0xC2));
15467 break;
15468 }
15469
15471 {
15472 if (j.m_data.m_value.number_integer >= 0)
15473 {
15474 // MessagePack does not differentiate between positive
15475 // signed integers and unsigned integers. Therefore, we used
15476 // the code from the value_t::number_unsigned case here.
15477 if (j.m_data.m_value.number_unsigned < 128)
15478 {
15479 // positive fixnum
15480 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15481 }
15482 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15483 {
15484 // uint 8
15485 oa->write_character(to_char_type(0xCC));
15486 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15487 }
15488 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15489 {
15490 // uint 16
15491 oa->write_character(to_char_type(0xCD));
15492 write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15493 }
15494 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15495 {
15496 // uint 32
15497 oa->write_character(to_char_type(0xCE));
15498 write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15499 }
15500 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15501 {
15502 // uint 64
15503 oa->write_character(to_char_type(0xCF));
15504 write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15505 }
15506 }
15507 else
15508 {
15509 if (j.m_data.m_value.number_integer >= -32)
15510 {
15511 // negative fixnum
15512 write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15513 }
15514 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
15515 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15516 {
15517 // int 8
15518 oa->write_character(to_char_type(0xD0));
15519 write_number(static_cast<std::int8_t>(j.m_data.m_value.number_integer));
15520 }
15521 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
15522 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15523 {
15524 // int 16
15525 oa->write_character(to_char_type(0xD1));
15526 write_number(static_cast<std::int16_t>(j.m_data.m_value.number_integer));
15527 }
15528 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
15529 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15530 {
15531 // int 32
15532 oa->write_character(to_char_type(0xD2));
15533 write_number(static_cast<std::int32_t>(j.m_data.m_value.number_integer));
15534 }
15535 else if (j.m_data.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
15536 j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15537 {
15538 // int 64
15539 oa->write_character(to_char_type(0xD3));
15540 write_number(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
15541 }
15542 }
15543 break;
15544 }
15545
15547 {
15548 if (j.m_data.m_value.number_unsigned < 128)
15549 {
15550 // positive fixnum
15551 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15552 }
15553 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
15554 {
15555 // uint 8
15556 oa->write_character(to_char_type(0xCC));
15557 write_number(static_cast<std::uint8_t>(j.m_data.m_value.number_integer));
15558 }
15559 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
15560 {
15561 // uint 16
15562 oa->write_character(to_char_type(0xCD));
15563 write_number(static_cast<std::uint16_t>(j.m_data.m_value.number_integer));
15564 }
15565 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
15566 {
15567 // uint 32
15568 oa->write_character(to_char_type(0xCE));
15569 write_number(static_cast<std::uint32_t>(j.m_data.m_value.number_integer));
15570 }
15571 else if (j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15572 {
15573 // uint 64
15574 oa->write_character(to_char_type(0xCF));
15575 write_number(static_cast<std::uint64_t>(j.m_data.m_value.number_integer));
15576 }
15577 break;
15578 }
15579
15581 {
15582 write_compact_float(j.m_data.m_value.number_float, detail::input_format_t::msgpack);
15583 break;
15584 }
15585
15586 case value_t::string:
15587 {
15588 // step 1: write control byte and the string length
15589 const auto N = j.m_data.m_value.string->size();
15590 if (N <= 31)
15591 {
15592 // fixstr
15593 write_number(static_cast<std::uint8_t>(0xA0 | N));
15594 }
15595 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
15596 {
15597 // str 8
15598 oa->write_character(to_char_type(0xD9));
15599 write_number(static_cast<std::uint8_t>(N));
15600 }
15601 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15602 {
15603 // str 16
15604 oa->write_character(to_char_type(0xDA));
15605 write_number(static_cast<std::uint16_t>(N));
15606 }
15607 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15608 {
15609 // str 32
15610 oa->write_character(to_char_type(0xDB));
15611 write_number(static_cast<std::uint32_t>(N));
15612 }
15613
15614 // step 2: write the string
15615 oa->write_characters(
15616 reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15617 j.m_data.m_value.string->size());
15618 break;
15619 }
15620
15621 case value_t::array:
15622 {
15623 // step 1: write control byte and the array size
15624 const auto N = j.m_data.m_value.array->size();
15625 if (N <= 15)
15626 {
15627 // fixarray
15628 write_number(static_cast<std::uint8_t>(0x90 | N));
15629 }
15630 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15631 {
15632 // array 16
15633 oa->write_character(to_char_type(0xDC));
15634 write_number(static_cast<std::uint16_t>(N));
15635 }
15636 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15637 {
15638 // array 32
15639 oa->write_character(to_char_type(0xDD));
15640 write_number(static_cast<std::uint32_t>(N));
15641 }
15642
15643 // step 2: write each element
15644 for (const auto& el : *j.m_data.m_value.array)
15645 {
15646 write_msgpack(el);
15647 }
15648 break;
15649 }
15650
15651 case value_t::binary:
15652 {
15653 // step 0: determine if the binary type has a set subtype to
15654 // determine whether or not to use the ext or fixext types
15655 const bool use_ext = j.m_data.m_value.binary->has_subtype();
15656
15657 // step 1: write control byte and the byte string length
15658 const auto N = j.m_data.m_value.binary->size();
15659 if (N <= (std::numeric_limits<std::uint8_t>::max)())
15660 {
15661 std::uint8_t output_type{};
15662 bool fixed = true;
15663 if (use_ext)
15664 {
15665 switch (N)
15666 {
15667 case 1:
15668 output_type = 0xD4; // fixext 1
15669 break;
15670 case 2:
15671 output_type = 0xD5; // fixext 2
15672 break;
15673 case 4:
15674 output_type = 0xD6; // fixext 4
15675 break;
15676 case 8:
15677 output_type = 0xD7; // fixext 8
15678 break;
15679 case 16:
15680 output_type = 0xD8; // fixext 16
15681 break;
15682 default:
15683 output_type = 0xC7; // ext 8
15684 fixed = false;
15685 break;
15686 }
15687
15688 }
15689 else
15690 {
15691 output_type = 0xC4; // bin 8
15692 fixed = false;
15693 }
15694
15695 oa->write_character(to_char_type(output_type));
15696 if (!fixed)
15697 {
15698 write_number(static_cast<std::uint8_t>(N));
15699 }
15700 }
15701 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15702 {
15703 const std::uint8_t output_type = use_ext
15704 ? 0xC8 // ext 16
15705 : 0xC5; // bin 16
15706
15707 oa->write_character(to_char_type(output_type));
15708 write_number(static_cast<std::uint16_t>(N));
15709 }
15710 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15711 {
15712 const std::uint8_t output_type = use_ext
15713 ? 0xC9 // ext 32
15714 : 0xC6; // bin 32
15715
15716 oa->write_character(to_char_type(output_type));
15717 write_number(static_cast<std::uint32_t>(N));
15718 }
15719
15720 // step 1.5: if this is an ext type, write the subtype
15721 if (use_ext)
15722 {
15723 write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
15724 }
15725
15726 // step 2: write the byte string
15727 oa->write_characters(
15728 reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15729 N);
15730
15731 break;
15732 }
15733
15734 case value_t::object:
15735 {
15736 // step 1: write control byte and the object size
15737 const auto N = j.m_data.m_value.object->size();
15738 if (N <= 15)
15739 {
15740 // fixmap
15741 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15742 }
15743 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15744 {
15745 // map 16
15746 oa->write_character(to_char_type(0xDE));
15747 write_number(static_cast<std::uint16_t>(N));
15748 }
15749 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15750 {
15751 // map 32
15752 oa->write_character(to_char_type(0xDF));
15753 write_number(static_cast<std::uint32_t>(N));
15754 }
15755
15756 // step 2: write each element
15757 for (const auto& el : *j.m_data.m_value.object)
15758 {
15759 write_msgpack(el.first);
15760 write_msgpack(el.second);
15761 }
15762 break;
15763 }
15764
15765 case value_t::discarded:
15766 default:
15767 break;
15768 }
15769 }
15770
15778 void write_ubjson(const BasicJsonType& j, const bool use_count,
15779 const bool use_type, const bool add_prefix = true,
15780 const bool use_bjdata = false)
15781 {
15782 switch (j.type())
15783 {
15784 case value_t::null:
15785 {
15786 if (add_prefix)
15787 {
15788 oa->write_character(to_char_type('Z'));
15789 }
15790 break;
15791 }
15792
15793 case value_t::boolean:
15794 {
15795 if (add_prefix)
15796 {
15797 oa->write_character(j.m_data.m_value.boolean
15798 ? to_char_type('T')
15799 : to_char_type('F'));
15800 }
15801 break;
15802 }
15803
15805 {
15806 write_number_with_ubjson_prefix(j.m_data.m_value.number_integer, add_prefix, use_bjdata);
15807 break;
15808 }
15809
15811 {
15812 write_number_with_ubjson_prefix(j.m_data.m_value.number_unsigned, add_prefix, use_bjdata);
15813 break;
15814 }
15815
15817 {
15818 write_number_with_ubjson_prefix(j.m_data.m_value.number_float, add_prefix, use_bjdata);
15819 break;
15820 }
15821
15822 case value_t::string:
15823 {
15824 if (add_prefix)
15825 {
15826 oa->write_character(to_char_type('S'));
15827 }
15828 write_number_with_ubjson_prefix(j.m_data.m_value.string->size(), true, use_bjdata);
15829 oa->write_characters(
15830 reinterpret_cast<const CharType*>(j.m_data.m_value.string->c_str()),
15831 j.m_data.m_value.string->size());
15832 break;
15833 }
15834
15835 case value_t::array:
15836 {
15837 if (add_prefix)
15838 {
15839 oa->write_character(to_char_type('['));
15840 }
15841
15842 bool prefix_required = true;
15843 if (use_type && !j.m_data.m_value.array->empty())
15844 {
15845 JSON_ASSERT(use_count);
15846 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15847 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15848 [this, first_prefix, use_bjdata](const BasicJsonType& v)
15849 {
15850 return ubjson_prefix(v, use_bjdata) == first_prefix;
15851 });
15852
15853 std::vector<CharType> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
15854
15855 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15856 {
15857 prefix_required = false;
15858 oa->write_character(to_char_type('$'));
15859 oa->write_character(first_prefix);
15860 }
15861 }
15862
15863 if (use_count)
15864 {
15865 oa->write_character(to_char_type('#'));
15866 write_number_with_ubjson_prefix(j.m_data.m_value.array->size(), true, use_bjdata);
15867 }
15868
15869 for (const auto& el : *j.m_data.m_value.array)
15870 {
15871 write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15872 }
15873
15874 if (!use_count)
15875 {
15876 oa->write_character(to_char_type(']'));
15877 }
15878
15879 break;
15880 }
15881
15882 case value_t::binary:
15883 {
15884 if (add_prefix)
15885 {
15886 oa->write_character(to_char_type('['));
15887 }
15888
15889 if (use_type && !j.m_data.m_value.binary->empty())
15890 {
15891 JSON_ASSERT(use_count);
15892 oa->write_character(to_char_type('$'));
15893 oa->write_character('U');
15894 }
15895
15896 if (use_count)
15897 {
15898 oa->write_character(to_char_type('#'));
15899 write_number_with_ubjson_prefix(j.m_data.m_value.binary->size(), true, use_bjdata);
15900 }
15901
15902 if (use_type)
15903 {
15904 oa->write_characters(
15905 reinterpret_cast<const CharType*>(j.m_data.m_value.binary->data()),
15906 j.m_data.m_value.binary->size());
15907 }
15908 else
15909 {
15910 for (size_t i = 0; i < j.m_data.m_value.binary->size(); ++i)
15911 {
15912 oa->write_character(to_char_type('U'));
15913 oa->write_character(j.m_data.m_value.binary->data()[i]);
15914 }
15915 }
15916
15917 if (!use_count)
15918 {
15919 oa->write_character(to_char_type(']'));
15920 }
15921
15922 break;
15923 }
15924
15925 case value_t::object:
15926 {
15927 if (use_bjdata && j.m_data.m_value.object->size() == 3 && j.m_data.m_value.object->find("_ArrayType_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArraySize_") != j.m_data.m_value.object->end() && j.m_data.m_value.object->find("_ArrayData_") != j.m_data.m_value.object->end())
15928 {
15929 if (!write_bjdata_ndarray(*j.m_data.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15930 {
15931 break;
15932 }
15933 }
15934
15935 if (add_prefix)
15936 {
15937 oa->write_character(to_char_type('{'));
15938 }
15939
15940 bool prefix_required = true;
15941 if (use_type && !j.m_data.m_value.object->empty())
15942 {
15943 JSON_ASSERT(use_count);
15944 const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15945 const bool same_prefix = std::all_of(j.begin(), j.end(),
15946 [this, first_prefix, use_bjdata](const BasicJsonType& v)
15947 {
15948 return ubjson_prefix(v, use_bjdata) == first_prefix;
15949 });
15950
15951 std::vector<CharType> bjdx = { '[', '{', 'S', 'H', 'T', 'F', 'N', 'Z' }; // excluded markers in bjdata optimized type
15952
15953 if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15954 {
15955 prefix_required = false;
15956 oa->write_character(to_char_type('$'));
15957 oa->write_character(first_prefix);
15958 }
15959 }
15960
15961 if (use_count)
15962 {
15963 oa->write_character(to_char_type('#'));
15964 write_number_with_ubjson_prefix(j.m_data.m_value.object->size(), true, use_bjdata);
15965 }
15966
15967 for (const auto& el : *j.m_data.m_value.object)
15968 {
15969 write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15970 oa->write_characters(
15971 reinterpret_cast<const CharType*>(el.first.c_str()),
15972 el.first.size());
15973 write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15974 }
15975
15976 if (!use_count)
15977 {
15978 oa->write_character(to_char_type('}'));
15979 }
15980
15981 break;
15982 }
15983
15984 case value_t::discarded:
15985 default:
15986 break;
15987 }
15988 }
15989
15990 private:
15992 // BSON //
15994
15999 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
16000 {
16001 const auto it = name.find(static_cast<typename string_t::value_type>(0));
16002 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
16003 {
16004 JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
16005 static_cast<void>(j);
16006 }
16007
16008 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
16009 }
16010
16015 const std::uint8_t element_type)
16016 {
16017 oa->write_character(to_char_type(element_type)); // boolean
16018 oa->write_characters(
16019 reinterpret_cast<const CharType*>(name.c_str()),
16020 name.size() + 1u);
16021 }
16022
16027 const bool value)
16028 {
16029 write_bson_entry_header(name, 0x08);
16030 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
16031 }
16032
16036 void write_bson_double(const string_t& name,
16037 const double value)
16038 {
16039 write_bson_entry_header(name, 0x01);
16041 }
16042
16046 static std::size_t calc_bson_string_size(const string_t& value)
16047 {
16048 return sizeof(std::int32_t) + value.size() + 1ul;
16049 }
16050
16054 void write_bson_string(const string_t& name,
16055 const string_t& value)
16056 {
16057 write_bson_entry_header(name, 0x02);
16058
16059 write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
16060 oa->write_characters(
16061 reinterpret_cast<const CharType*>(value.c_str()),
16062 value.size() + 1);
16063 }
16064
16068 void write_bson_null(const string_t& name)
16069 {
16070 write_bson_entry_header(name, 0x0A);
16071 }
16072
16076 static std::size_t calc_bson_integer_size(const std::int64_t value)
16077 {
16078 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
16079 ? sizeof(std::int32_t)
16080 : sizeof(std::int64_t);
16081 }
16082
16087 const std::int64_t value)
16088 {
16089 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
16090 {
16091 write_bson_entry_header(name, 0x10); // int32
16092 write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
16093 }
16094 else
16095 {
16096 write_bson_entry_header(name, 0x12); // int64
16097 write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
16098 }
16099 }
16100
16104 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
16105 {
16106 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16107 ? sizeof(std::int32_t)
16108 : sizeof(std::int64_t);
16109 }
16110
16115 const BasicJsonType& j)
16116 {
16117 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16118 {
16119 write_bson_entry_header(name, 0x10 /* int32 */);
16120 write_number<std::int32_t>(static_cast<std::int32_t>(j.m_data.m_value.number_unsigned), true);
16121 }
16122 else if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16123 {
16124 write_bson_entry_header(name, 0x12 /* int64 */);
16125 write_number<std::int64_t>(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned), true);
16126 }
16127 else
16128 {
16129 JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
16130 }
16131 }
16132
16137 const typename BasicJsonType::object_t& value)
16138 {
16139 write_bson_entry_header(name, 0x03); // object
16141 }
16142
16146 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
16147 {
16148 std::size_t array_index = 0ul;
16149
16150 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)
16151 {
16152 return result + calc_bson_element_size(std::to_string(array_index++), el);
16153 });
16154
16155 return sizeof(std::int32_t) + embedded_document_size + 1ul;
16156 }
16157
16161 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
16162 {
16163 return sizeof(std::int32_t) + value.size() + 1ul;
16164 }
16165
16169 void write_bson_array(const string_t& name,
16170 const typename BasicJsonType::array_t& value)
16171 {
16172 write_bson_entry_header(name, 0x04); // array
16173 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
16174
16175 std::size_t array_index = 0ul;
16176
16177 for (const auto& el : value)
16178 {
16179 write_bson_element(std::to_string(array_index++), el);
16180 }
16181
16182 oa->write_character(to_char_type(0x00));
16183 }
16184
16188 void write_bson_binary(const string_t& name,
16189 const binary_t& value)
16190 {
16191 write_bson_entry_header(name, 0x05);
16192
16193 write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
16194 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
16195
16196 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
16197 }
16198
16203 static std::size_t calc_bson_element_size(const string_t& name,
16204 const BasicJsonType& j)
16205 {
16206 const auto header_size = calc_bson_entry_header_size(name, j);
16207 switch (j.type())
16208 {
16209 case value_t::object:
16210 return header_size + calc_bson_object_size(*j.m_data.m_value.object);
16211
16212 case value_t::array:
16213 return header_size + calc_bson_array_size(*j.m_data.m_value.array);
16214
16215 case value_t::binary:
16216 return header_size + calc_bson_binary_size(*j.m_data.m_value.binary);
16217
16218 case value_t::boolean:
16219 return header_size + 1ul;
16220
16222 return header_size + 8ul;
16223
16225 return header_size + calc_bson_integer_size(j.m_data.m_value.number_integer);
16226
16228 return header_size + calc_bson_unsigned_size(j.m_data.m_value.number_unsigned);
16229
16230 case value_t::string:
16231 return header_size + calc_bson_string_size(*j.m_data.m_value.string);
16232
16233 case value_t::null:
16234 return header_size + 0ul;
16235
16236 // LCOV_EXCL_START
16237 case value_t::discarded:
16238 default:
16239 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16240 return 0ul;
16241 // LCOV_EXCL_STOP
16242 }
16243 }
16244
16252 const BasicJsonType& j)
16253 {
16254 switch (j.type())
16255 {
16256 case value_t::object:
16257 return write_bson_object_entry(name, *j.m_data.m_value.object);
16258
16259 case value_t::array:
16260 return write_bson_array(name, *j.m_data.m_value.array);
16261
16262 case value_t::binary:
16263 return write_bson_binary(name, *j.m_data.m_value.binary);
16264
16265 case value_t::boolean:
16266 return write_bson_boolean(name, j.m_data.m_value.boolean);
16267
16269 return write_bson_double(name, j.m_data.m_value.number_float);
16270
16272 return write_bson_integer(name, j.m_data.m_value.number_integer);
16273
16275 return write_bson_unsigned(name, j);
16276
16277 case value_t::string:
16278 return write_bson_string(name, *j.m_data.m_value.string);
16279
16280 case value_t::null:
16281 return write_bson_null(name);
16282
16283 // LCOV_EXCL_START
16284 case value_t::discarded:
16285 default:
16286 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
16287 return;
16288 // LCOV_EXCL_STOP
16289 }
16290 }
16291
16298 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
16299 {
16300 const std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
16301 [](size_t result, const typename BasicJsonType::object_t::value_type& el)
16302 {
16303 return result += calc_bson_element_size(el.first, el.second);
16304 });
16305
16306 return sizeof(std::int32_t) + document_size + 1ul;
16307 }
16308
16313 void write_bson_object(const typename BasicJsonType::object_t& value)
16314 {
16315 write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
16316
16317 for (const auto& el : value)
16318 {
16319 write_bson_element(el.first, el.second);
16320 }
16321
16322 oa->write_character(to_char_type(0x00));
16323 }
16324
16326 // CBOR //
16328
16329 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
16330 {
16331 return to_char_type(0xFA); // Single-Precision Float
16332 }
16333
16334 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
16335 {
16336 return to_char_type(0xFB); // Double-Precision Float
16337 }
16338
16340 // MsgPack //
16342
16343 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
16344 {
16345 return to_char_type(0xCA); // float 32
16346 }
16347
16348 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
16349 {
16350 return to_char_type(0xCB); // float 64
16351 }
16352
16354 // UBJSON //
16356
16357 // UBJSON: write number (floating point)
16358 template<typename NumberType, typename std::enable_if<
16359 std::is_floating_point<NumberType>::value, int>::type = 0>
16360 void write_number_with_ubjson_prefix(const NumberType n,
16361 const bool add_prefix,
16362 const bool use_bjdata)
16363 {
16364 if (add_prefix)
16365 {
16366 oa->write_character(get_ubjson_float_prefix(n));
16367 }
16368 write_number(n, use_bjdata);
16369 }
16370
16371 // UBJSON: write number (unsigned integer)
16372 template<typename NumberType, typename std::enable_if<
16373 std::is_unsigned<NumberType>::value, int>::type = 0>
16374 void write_number_with_ubjson_prefix(const NumberType n,
16375 const bool add_prefix,
16376 const bool use_bjdata)
16377 {
16378 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16379 {
16380 if (add_prefix)
16381 {
16382 oa->write_character(to_char_type('i')); // int8
16383 }
16384 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16385 }
16386 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
16387 {
16388 if (add_prefix)
16389 {
16390 oa->write_character(to_char_type('U')); // uint8
16391 }
16392 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16393 }
16394 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16395 {
16396 if (add_prefix)
16397 {
16398 oa->write_character(to_char_type('I')); // int16
16399 }
16400 write_number(static_cast<std::int16_t>(n), use_bjdata);
16401 }
16402 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
16403 {
16404 if (add_prefix)
16405 {
16406 oa->write_character(to_char_type('u')); // uint16 - bjdata only
16407 }
16408 write_number(static_cast<std::uint16_t>(n), use_bjdata);
16409 }
16410 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16411 {
16412 if (add_prefix)
16413 {
16414 oa->write_character(to_char_type('l')); // int32
16415 }
16416 write_number(static_cast<std::int32_t>(n), use_bjdata);
16417 }
16418 else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
16419 {
16420 if (add_prefix)
16421 {
16422 oa->write_character(to_char_type('m')); // uint32 - bjdata only
16423 }
16424 write_number(static_cast<std::uint32_t>(n), use_bjdata);
16425 }
16426 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16427 {
16428 if (add_prefix)
16429 {
16430 oa->write_character(to_char_type('L')); // int64
16431 }
16432 write_number(static_cast<std::int64_t>(n), use_bjdata);
16433 }
16434 else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
16435 {
16436 if (add_prefix)
16437 {
16438 oa->write_character(to_char_type('M')); // uint64 - bjdata only
16439 }
16440 write_number(static_cast<std::uint64_t>(n), use_bjdata);
16441 }
16442 else
16443 {
16444 if (add_prefix)
16445 {
16446 oa->write_character(to_char_type('H')); // high-precision number
16447 }
16448
16449 const auto number = BasicJsonType(n).dump();
16450 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16451 for (std::size_t i = 0; i < number.size(); ++i)
16452 {
16453 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16454 }
16455 }
16456 }
16457
16458 // UBJSON: write number (signed integer)
16459 template < typename NumberType, typename std::enable_if <
16460 std::is_signed<NumberType>::value &&
16461 !std::is_floating_point<NumberType>::value, int >::type = 0 >
16462 void write_number_with_ubjson_prefix(const NumberType n,
16463 const bool add_prefix,
16464 const bool use_bjdata)
16465 {
16466 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
16467 {
16468 if (add_prefix)
16469 {
16470 oa->write_character(to_char_type('i')); // int8
16471 }
16472 write_number(static_cast<std::int8_t>(n), use_bjdata);
16473 }
16474 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)()))
16475 {
16476 if (add_prefix)
16477 {
16478 oa->write_character(to_char_type('U')); // uint8
16479 }
16480 write_number(static_cast<std::uint8_t>(n), use_bjdata);
16481 }
16482 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
16483 {
16484 if (add_prefix)
16485 {
16486 oa->write_character(to_char_type('I')); // int16
16487 }
16488 write_number(static_cast<std::int16_t>(n), use_bjdata);
16489 }
16490 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)())))
16491 {
16492 if (add_prefix)
16493 {
16494 oa->write_character(to_char_type('u')); // uint16 - bjdata only
16495 }
16496 write_number(static_cast<uint16_t>(n), use_bjdata);
16497 }
16498 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
16499 {
16500 if (add_prefix)
16501 {
16502 oa->write_character(to_char_type('l')); // int32
16503 }
16504 write_number(static_cast<std::int32_t>(n), use_bjdata);
16505 }
16506 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)())))
16507 {
16508 if (add_prefix)
16509 {
16510 oa->write_character(to_char_type('m')); // uint32 - bjdata only
16511 }
16512 write_number(static_cast<uint32_t>(n), use_bjdata);
16513 }
16514 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
16515 {
16516 if (add_prefix)
16517 {
16518 oa->write_character(to_char_type('L')); // int64
16519 }
16520 write_number(static_cast<std::int64_t>(n), use_bjdata);
16521 }
16522 // LCOV_EXCL_START
16523 else
16524 {
16525 if (add_prefix)
16526 {
16527 oa->write_character(to_char_type('H')); // high-precision number
16528 }
16529
16530 const auto number = BasicJsonType(n).dump();
16531 write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
16532 for (std::size_t i = 0; i < number.size(); ++i)
16533 {
16534 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
16535 }
16536 }
16537 // LCOV_EXCL_STOP
16538 }
16539
16543 CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
16544 {
16545 switch (j.type())
16546 {
16547 case value_t::null:
16548 return 'Z';
16549
16550 case value_t::boolean:
16551 return j.m_data.m_value.boolean ? 'T' : 'F';
16552
16554 {
16555 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
16556 {
16557 return 'i';
16558 }
16559 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
16560 {
16561 return 'U';
16562 }
16563 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
16564 {
16565 return 'I';
16566 }
16567 if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
16568 {
16569 return 'u';
16570 }
16571 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
16572 {
16573 return 'l';
16574 }
16575 if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
16576 {
16577 return 'm';
16578 }
16579 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_data.m_value.number_integer && j.m_data.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
16580 {
16581 return 'L';
16582 }
16583 // anything else is treated as high-precision number
16584 return 'H'; // LCOV_EXCL_LINE
16585 }
16586
16588 {
16589 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
16590 {
16591 return 'i';
16592 }
16593 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
16594 {
16595 return 'U';
16596 }
16597 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
16598 {
16599 return 'I';
16600 }
16601 if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
16602 {
16603 return 'u';
16604 }
16605 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
16606 {
16607 return 'l';
16608 }
16609 if (use_bjdata && j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
16610 {
16611 return 'm';
16612 }
16613 if (j.m_data.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
16614 {
16615 return 'L';
16616 }
16617 if (use_bjdata && j.m_data.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
16618 {
16619 return 'M';
16620 }
16621 // anything else is treated as high-precision number
16622 return 'H'; // LCOV_EXCL_LINE
16623 }
16624
16626 return get_ubjson_float_prefix(j.m_data.m_value.number_float);
16627
16628 case value_t::string:
16629 return 'S';
16630
16631 case value_t::array: // fallthrough
16632 case value_t::binary:
16633 return '[';
16634
16635 case value_t::object:
16636 return '{';
16637
16638 case value_t::discarded:
16639 default: // discarded values
16640 return 'N';
16641 }
16642 }
16643
16644 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
16645 {
16646 return 'd'; // float 32
16647 }
16648
16649 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
16650 {
16651 return 'D'; // float 64
16652 }
16653
16657 bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
16658 {
16659 std::map<string_t, CharType> bjdtype = { {"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
16660 {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
16661 };
16662
16663 string_t key = "_ArrayType_";
16664 auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
16665 if (it == bjdtype.end())
16666 {
16667 return true;
16668 }
16669 CharType dtype = it->second;
16670
16671 key = "_ArraySize_";
16672 std::size_t len = (value.at(key).empty() ? 0 : 1);
16673 for (const auto& el : value.at(key))
16674 {
16675 len *= static_cast<std::size_t>(el.m_data.m_value.number_unsigned);
16676 }
16677
16678 key = "_ArrayData_";
16679 if (value.at(key).size() != len)
16680 {
16681 return true;
16682 }
16683
16684 oa->write_character('[');
16685 oa->write_character('$');
16686 oa->write_character(dtype);
16687 oa->write_character('#');
16688
16689 key = "_ArraySize_";
16690 write_ubjson(value.at(key), use_count, use_type, true, true);
16691
16692 key = "_ArrayData_";
16693 if (dtype == 'U' || dtype == 'C')
16694 {
16695 for (const auto& el : value.at(key))
16696 {
16697 write_number(static_cast<std::uint8_t>(el.m_data.m_value.number_unsigned), true);
16698 }
16699 }
16700 else if (dtype == 'i')
16701 {
16702 for (const auto& el : value.at(key))
16703 {
16704 write_number(static_cast<std::int8_t>(el.m_data.m_value.number_integer), true);
16705 }
16706 }
16707 else if (dtype == 'u')
16708 {
16709 for (const auto& el : value.at(key))
16710 {
16711 write_number(static_cast<std::uint16_t>(el.m_data.m_value.number_unsigned), true);
16712 }
16713 }
16714 else if (dtype == 'I')
16715 {
16716 for (const auto& el : value.at(key))
16717 {
16718 write_number(static_cast<std::int16_t>(el.m_data.m_value.number_integer), true);
16719 }
16720 }
16721 else if (dtype == 'm')
16722 {
16723 for (const auto& el : value.at(key))
16724 {
16725 write_number(static_cast<std::uint32_t>(el.m_data.m_value.number_unsigned), true);
16726 }
16727 }
16728 else if (dtype == 'l')
16729 {
16730 for (const auto& el : value.at(key))
16731 {
16732 write_number(static_cast<std::int32_t>(el.m_data.m_value.number_integer), true);
16733 }
16734 }
16735 else if (dtype == 'M')
16736 {
16737 for (const auto& el : value.at(key))
16738 {
16739 write_number(static_cast<std::uint64_t>(el.m_data.m_value.number_unsigned), true);
16740 }
16741 }
16742 else if (dtype == 'L')
16743 {
16744 for (const auto& el : value.at(key))
16745 {
16746 write_number(static_cast<std::int64_t>(el.m_data.m_value.number_integer), true);
16747 }
16748 }
16749 else if (dtype == 'd')
16750 {
16751 for (const auto& el : value.at(key))
16752 {
16753 write_number(static_cast<float>(el.m_data.m_value.number_float), true);
16754 }
16755 }
16756 else if (dtype == 'D')
16757 {
16758 for (const auto& el : value.at(key))
16759 {
16760 write_number(static_cast<double>(el.m_data.m_value.number_float), true);
16761 }
16762 }
16763 return false;
16764 }
16765
16767 // Utility functions //
16769
16770 /*
16771 @brief write a number to output input
16772 @param[in] n number of type @a NumberType
16773 @param[in] OutputIsLittleEndian Set to true if output data is
16774 required to be little endian
16775 @tparam NumberType the type of the number
16776
16777 @note This function needs to respect the system's endianness, because bytes
16778 in CBOR, MessagePack, and UBJSON are stored in network order (big
16779 endian) and therefore need reordering on little endian systems.
16780 On the other hand, BSON and BJData use little endian and should reorder
16781 on big endian systems.
16782 */
16783 template<typename NumberType>
16784 void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16785 {
16786 // step 1: write number to array of length NumberType
16787 std::array<CharType, sizeof(NumberType)> vec{};
16788 std::memcpy(vec.data(), &n, sizeof(NumberType));
16789
16790 // step 2: write array to output (with possible reordering)
16791 if (is_little_endian != OutputIsLittleEndian)
16792 {
16793 // reverse byte order prior to conversion if necessary
16794 std::reverse(vec.begin(), vec.end());
16795 }
16796
16797 oa->write_characters(vec.data(), sizeof(NumberType));
16798 }
16799
16801 {
16802#ifdef __GNUC__
16803#pragma GCC diagnostic push
16804#pragma GCC diagnostic ignored "-Wfloat-equal"
16805#endif
16806 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16807 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16808 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16809 {
16810 oa->write_character(format == detail::input_format_t::cbor
16811 ? get_cbor_float_prefix(static_cast<float>(n))
16812 : get_msgpack_float_prefix(static_cast<float>(n)));
16813 write_number(static_cast<float>(n));
16814 }
16815 else
16816 {
16817 oa->write_character(format == detail::input_format_t::cbor
16820 write_number(n);
16821 }
16822#ifdef __GNUC__
16823#pragma GCC diagnostic pop
16824#endif
16825 }
16826
16827 public:
16828 // The following to_char_type functions are implement the conversion
16829 // between uint8_t and CharType. In case CharType is not unsigned,
16830 // such a conversion is required to allow values greater than 128.
16831 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16832 template < typename C = CharType,
16833 enable_if_t < std::is_signed<C>::value&& std::is_signed<char>::value >* = nullptr >
16834 static constexpr CharType to_char_type(std::uint8_t x) noexcept
16835 {
16836 return *reinterpret_cast<char*>(&x);
16837 }
16838
16839 template < typename C = CharType,
16840 enable_if_t < std::is_signed<C>::value&& std::is_unsigned<char>::value >* = nullptr >
16841 static CharType to_char_type(std::uint8_t x) noexcept
16842 {
16843 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16844 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16845 CharType result;
16846 std::memcpy(&result, &x, sizeof(x));
16847 return result;
16848 }
16849
16850 template<typename C = CharType,
16852 static constexpr CharType to_char_type(std::uint8_t x) noexcept
16853 {
16854 return x;
16855 }
16856
16857 template < typename InputCharType, typename C = CharType,
16858 enable_if_t <
16859 std::is_signed<C>::value&&
16860 std::is_signed<char>::value&&
16861 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
16862 >* = nullptr >
16863 static constexpr CharType to_char_type(InputCharType x) noexcept
16864 {
16865 return x;
16866 }
16867
16868 private:
16871
16874 };
16875
16876} // namespace detail
16878
16879// #include <nlohmann/detail/output/output_adapters.hpp>
16880
16881// #include <nlohmann/detail/output/serializer.hpp>
16882// __ _____ _____ _____
16883// __| | __| | | | JSON for Modern C++
16884// | | |__ | | | | | | version 3.11.3
16885// |_____|_____|_____|_|___| https://github.com/nlohmann/json
16886//
16887// SPDX-FileCopyrightText: 2008-2009 Björn Hoehrmann <bjoern@hoehrmann.de>
16888// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
16889// SPDX-License-Identifier: MIT
16890
16891
16892
16893#include <algorithm> // reverse, remove, fill, find, none_of
16894#include <array> // array
16895#include <clocale> // localeconv, lconv
16896#include <cmath> // labs, isfinite, isnan, signbit
16897#include <cstddef> // size_t, ptrdiff_t
16898#include <cstdint> // uint8_t
16899#include <cstdio> // snprintf
16900#include <limits> // numeric_limits
16901#include <string> // string, char_traits
16902#include <iomanip> // setfill, setw
16903#include <type_traits> // is_same
16904#include <utility> // move
16905
16906// #include <nlohmann/detail/conversions/to_chars.hpp>
16907// __ _____ _____ _____
16908// __| | __| | | | JSON for Modern C++
16909// | | |__ | | | | | | version 3.11.3
16910// |_____|_____|_____|_|___| https://github.com/nlohmann/json
16911//
16912// SPDX-FileCopyrightText: 2009 Florian Loitsch <https://florian.loitsch.com/>
16913// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
16914// SPDX-License-Identifier: MIT
16915
16916
16917
16918#include <array> // array
16919#include <cmath> // signbit, isfinite
16920#include <cstdint> // intN_t, uintN_t
16921#include <cstring> // memcpy, memmove
16922#include <limits> // numeric_limits
16923#include <type_traits> // conditional
16924
16925// #include <nlohmann/detail/macro_scope.hpp>
16926
16927
16929namespace detail
16930{
16931
16951 namespace dtoa_impl
16952 {
16953
16954 template<typename Target, typename Source>
16955 Target reinterpret_bits(const Source source)
16956 {
16957 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16958
16959 Target target;
16960 std::memcpy(&target, &source, sizeof(Source));
16961 return target;
16962 }
16963
16964 struct diyfp // f * 2^e
16965 {
16966 static constexpr int kPrecision = 64; // = q
16967
16968 std::uint64_t f = 0;
16969 int e = 0;
16970
16971 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16972
16977 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16978 {
16979 JSON_ASSERT(x.e == y.e);
16980 JSON_ASSERT(x.f >= y.f);
16981
16982 return { x.f - y.f, x.e };
16983 }
16984
16989 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16990 {
16991 static_assert(kPrecision == 64, "internal error");
16992
16993 // Computes:
16994 // f = round((x.f * y.f) / 2^q)
16995 // e = x.e + y.e + q
16996
16997 // Emulate the 64-bit * 64-bit multiplication:
16998 //
16999 // p = u * v
17000 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
17001 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
17002 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
17003 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
17004 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
17005 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
17006 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
17007 //
17008 // (Since Q might be larger than 2^32 - 1)
17009 //
17010 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
17011 //
17012 // (Q_hi + H does not overflow a 64-bit int)
17013 //
17014 // = p_lo + 2^64 p_hi
17015
17016 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
17017 const std::uint64_t u_hi = x.f >> 32u;
17018 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
17019 const std::uint64_t v_hi = y.f >> 32u;
17020
17021 const std::uint64_t p0 = u_lo * v_lo;
17022 const std::uint64_t p1 = u_lo * v_hi;
17023 const std::uint64_t p2 = u_hi * v_lo;
17024 const std::uint64_t p3 = u_hi * v_hi;
17025
17026 const std::uint64_t p0_hi = p0 >> 32u;
17027 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
17028 const std::uint64_t p1_hi = p1 >> 32u;
17029 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
17030 const std::uint64_t p2_hi = p2 >> 32u;
17031
17032 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
17033
17034 // The full product might now be computed as
17035 //
17036 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
17037 // p_lo = p0_lo + (Q << 32)
17038 //
17039 // But in this particular case here, the full p_lo is not required.
17040 // Effectively we only need to add the highest bit in p_lo to p_hi (and
17041 // Q_hi + 1 does not overflow).
17042
17043 Q += std::uint64_t{ 1 } << (64u - 32u - 1u); // round, ties up
17044
17045 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
17046
17047 return { h, x.e + y.e + 64 };
17048 }
17049
17054 static diyfp normalize(diyfp x) noexcept
17055 {
17056 JSON_ASSERT(x.f != 0);
17057
17058 while ((x.f >> 63u) == 0)
17059 {
17060 x.f <<= 1u;
17061 x.e--;
17062 }
17063
17064 return x;
17065 }
17066
17071 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
17072 {
17073 const int delta = x.e - target_exponent;
17074
17075 JSON_ASSERT(delta >= 0);
17076 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
17077
17078 return { x.f << delta, target_exponent };
17079 }
17080 };
17081
17083 {
17087 };
17088
17095 template<typename FloatType>
17097 {
17098 JSON_ASSERT(std::isfinite(value));
17099 JSON_ASSERT(value > 0);
17100
17101 // Convert the IEEE representation into a diyfp.
17102 //
17103 // If v is denormal:
17104 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
17105 // If v is normalized:
17106 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
17107
17108 static_assert(std::numeric_limits<FloatType>::is_iec559,
17109 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
17110
17111 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
17112 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
17113 constexpr int kMinExp = 1 - kBias;
17114 constexpr std::uint64_t kHiddenBit = std::uint64_t{ 1 } << (kPrecision - 1); // = 2^(p-1)
17115
17116 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
17117
17118 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
17119 const std::uint64_t E = bits >> (kPrecision - 1);
17120 const std::uint64_t F = bits & (kHiddenBit - 1);
17121
17122 const bool is_denormal = E == 0;
17123 const diyfp v = is_denormal
17124 ? diyfp(F, kMinExp)
17125 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
17126
17127 // Compute the boundaries m- and m+ of the floating-point value
17128 // v = f * 2^e.
17129 //
17130 // Determine v- and v+, the floating-point predecessor and successor if v,
17131 // respectively.
17132 //
17133 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
17134 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
17135 //
17136 // v+ = v + 2^e
17137 //
17138 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
17139 // between m- and m+ round to v, regardless of how the input rounding
17140 // algorithm breaks ties.
17141 //
17142 // ---+-------------+-------------+-------------+-------------+--- (A)
17143 // v- m- v m+ v+
17144 //
17145 // -----------------+------+------+-------------+-------------+--- (B)
17146 // v- m- v m+ v+
17147
17148 const bool lower_boundary_is_closer = F == 0 && E > 1;
17149 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
17150 const diyfp m_minus = lower_boundary_is_closer
17151 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
17152 : diyfp(2 * v.f - 1, v.e - 1); // (A)
17153
17154 // Determine the normalized w+ = m+.
17155 const diyfp w_plus = diyfp::normalize(m_plus);
17156
17157 // Determine w- = m- such that e_(w-) = e_(w+).
17158 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
17159
17160 return { diyfp::normalize(v), w_minus, w_plus };
17161 }
17162
17163 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
17164 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
17165 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
17166 //
17167 // alpha <= e = e_c + e_w + q <= gamma
17168 //
17169 // or
17170 //
17171 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
17172 // <= f_c * f_w * 2^gamma
17173 //
17174 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
17175 //
17176 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
17177 //
17178 // or
17179 //
17180 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
17181 //
17182 // The choice of (alpha,gamma) determines the size of the table and the form of
17183 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
17184 // in practice:
17185 //
17186 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
17187 // processed independently: An integral part p1, and a fractional part p2:
17188 //
17189 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
17190 // = (f div 2^-e) + (f mod 2^-e) * 2^e
17191 // = p1 + p2 * 2^e
17192 //
17193 // The conversion of p1 into decimal form requires a series of divisions and
17194 // modulos by (a power of) 10. These operations are faster for 32-bit than for
17195 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
17196 // achieved by choosing
17197 //
17198 // -e >= 32 or e <= -32 := gamma
17199 //
17200 // In order to convert the fractional part
17201 //
17202 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
17203 //
17204 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
17205 // d[-i] are extracted in order:
17206 //
17207 // (10 * p2) div 2^-e = d[-1]
17208 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
17209 //
17210 // The multiplication by 10 must not overflow. It is sufficient to choose
17211 //
17212 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
17213 //
17214 // Since p2 = f mod 2^-e < 2^-e,
17215 //
17216 // -e <= 60 or e >= -60 := alpha
17217
17218 constexpr int kAlpha = -60;
17219 constexpr int kGamma = -32;
17220
17221 struct cached_power // c = f * 2^e ~= 10^k
17222 {
17223 std::uint64_t f;
17224 int e;
17225 int k;
17226 };
17227
17236 {
17237 // Now
17238 //
17239 // alpha <= e_c + e + q <= gamma (1)
17240 // ==> f_c * 2^alpha <= c * 2^e * 2^q
17241 //
17242 // and since the c's are normalized, 2^(q-1) <= f_c,
17243 //
17244 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
17245 // ==> 2^(alpha - e - 1) <= c
17246 //
17247 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
17248 //
17249 // k = ceil( log_10( 2^(alpha - e - 1) ) )
17250 // = ceil( (alpha - e - 1) * log_10(2) )
17251 //
17252 // From the paper:
17253 // "In theory the result of the procedure could be wrong since c is rounded,
17254 // and the computation itself is approximated [...]. In practice, however,
17255 // this simple function is sufficient."
17256 //
17257 // For IEEE double precision floating-point numbers converted into
17258 // normalized diyfp's w = f * 2^e, with q = 64,
17259 //
17260 // e >= -1022 (min IEEE exponent)
17261 // -52 (p - 1)
17262 // -52 (p - 1, possibly normalize denormal IEEE numbers)
17263 // -11 (normalize the diyfp)
17264 // = -1137
17265 //
17266 // and
17267 //
17268 // e <= +1023 (max IEEE exponent)
17269 // -52 (p - 1)
17270 // -11 (normalize the diyfp)
17271 // = 960
17272 //
17273 // This binary exponent range [-1137,960] results in a decimal exponent
17274 // range [-307,324]. One does not need to store a cached power for each
17275 // k in this range. For each such k it suffices to find a cached power
17276 // such that the exponent of the product lies in [alpha,gamma].
17277 // This implies that the difference of the decimal exponents of adjacent
17278 // table entries must be less than or equal to
17279 //
17280 // floor( (gamma - alpha) * log_10(2) ) = 8.
17281 //
17282 // (A smaller distance gamma-alpha would require a larger table.)
17283
17284 // NB:
17285 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
17286
17287 constexpr int kCachedPowersMinDecExp = -300;
17288 constexpr int kCachedPowersDecStep = 8;
17289
17290 static constexpr std::array<cached_power, 79> kCachedPowers =
17291 {
17292 {
17293 { 0xAB70FE17C79AC6CA, -1060, -300 },
17294 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
17295 { 0xBE5691EF416BD60C, -1007, -284 },
17296 { 0x8DD01FAD907FFC3C, -980, -276 },
17297 { 0xD3515C2831559A83, -954, -268 },
17298 { 0x9D71AC8FADA6C9B5, -927, -260 },
17299 { 0xEA9C227723EE8BCB, -901, -252 },
17300 { 0xAECC49914078536D, -874, -244 },
17301 { 0x823C12795DB6CE57, -847, -236 },
17302 { 0xC21094364DFB5637, -821, -228 },
17303 { 0x9096EA6F3848984F, -794, -220 },
17304 { 0xD77485CB25823AC7, -768, -212 },
17305 { 0xA086CFCD97BF97F4, -741, -204 },
17306 { 0xEF340A98172AACE5, -715, -196 },
17307 { 0xB23867FB2A35B28E, -688, -188 },
17308 { 0x84C8D4DFD2C63F3B, -661, -180 },
17309 { 0xC5DD44271AD3CDBA, -635, -172 },
17310 { 0x936B9FCEBB25C996, -608, -164 },
17311 { 0xDBAC6C247D62A584, -582, -156 },
17312 { 0xA3AB66580D5FDAF6, -555, -148 },
17313 { 0xF3E2F893DEC3F126, -529, -140 },
17314 { 0xB5B5ADA8AAFF80B8, -502, -132 },
17315 { 0x87625F056C7C4A8B, -475, -124 },
17316 { 0xC9BCFF6034C13053, -449, -116 },
17317 { 0x964E858C91BA2655, -422, -108 },
17318 { 0xDFF9772470297EBD, -396, -100 },
17319 { 0xA6DFBD9FB8E5B88F, -369, -92 },
17320 { 0xF8A95FCF88747D94, -343, -84 },
17321 { 0xB94470938FA89BCF, -316, -76 },
17322 { 0x8A08F0F8BF0F156B, -289, -68 },
17323 { 0xCDB02555653131B6, -263, -60 },
17324 { 0x993FE2C6D07B7FAC, -236, -52 },
17325 { 0xE45C10C42A2B3B06, -210, -44 },
17326 { 0xAA242499697392D3, -183, -36 },
17327 { 0xFD87B5F28300CA0E, -157, -28 },
17328 { 0xBCE5086492111AEB, -130, -20 },
17329 { 0x8CBCCC096F5088CC, -103, -12 },
17330 { 0xD1B71758E219652C, -77, -4 },
17331 { 0x9C40000000000000, -50, 4 },
17332 { 0xE8D4A51000000000, -24, 12 },
17333 { 0xAD78EBC5AC620000, 3, 20 },
17334 { 0x813F3978F8940984, 30, 28 },
17335 { 0xC097CE7BC90715B3, 56, 36 },
17336 { 0x8F7E32CE7BEA5C70, 83, 44 },
17337 { 0xD5D238A4ABE98068, 109, 52 },
17338 { 0x9F4F2726179A2245, 136, 60 },
17339 { 0xED63A231D4C4FB27, 162, 68 },
17340 { 0xB0DE65388CC8ADA8, 189, 76 },
17341 { 0x83C7088E1AAB65DB, 216, 84 },
17342 { 0xC45D1DF942711D9A, 242, 92 },
17343 { 0x924D692CA61BE758, 269, 100 },
17344 { 0xDA01EE641A708DEA, 295, 108 },
17345 { 0xA26DA3999AEF774A, 322, 116 },
17346 { 0xF209787BB47D6B85, 348, 124 },
17347 { 0xB454E4A179DD1877, 375, 132 },
17348 { 0x865B86925B9BC5C2, 402, 140 },
17349 { 0xC83553C5C8965D3D, 428, 148 },
17350 { 0x952AB45CFA97A0B3, 455, 156 },
17351 { 0xDE469FBD99A05FE3, 481, 164 },
17352 { 0xA59BC234DB398C25, 508, 172 },
17353 { 0xF6C69A72A3989F5C, 534, 180 },
17354 { 0xB7DCBF5354E9BECE, 561, 188 },
17355 { 0x88FCF317F22241E2, 588, 196 },
17356 { 0xCC20CE9BD35C78A5, 614, 204 },
17357 { 0x98165AF37B2153DF, 641, 212 },
17358 { 0xE2A0B5DC971F303A, 667, 220 },
17359 { 0xA8D9D1535CE3B396, 694, 228 },
17360 { 0xFB9B7CD9A4A7443C, 720, 236 },
17361 { 0xBB764C4CA7A44410, 747, 244 },
17362 { 0x8BAB8EEFB6409C1A, 774, 252 },
17363 { 0xD01FEF10A657842C, 800, 260 },
17364 { 0x9B10A4E5E9913129, 827, 268 },
17365 { 0xE7109BFBA19C0C9D, 853, 276 },
17366 { 0xAC2820D9623BF429, 880, 284 },
17367 { 0x80444B5E7AA7CF85, 907, 292 },
17368 { 0xBF21E44003ACDD2D, 933, 300 },
17369 { 0x8E679C2F5E44FF8F, 960, 308 },
17370 { 0xD433179D9C8CB841, 986, 316 },
17371 { 0x9E19DB92B4E31BA9, 1013, 324 },
17372 }
17373 };
17374
17375 // This computation gives exactly the same results for k as
17376 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
17377 // for |e| <= 1500, but doesn't require floating-point operations.
17378 // NB: log_10(2) ~= 78913 / 2^18
17379 JSON_ASSERT(e >= -1500);
17380 JSON_ASSERT(e <= 1500);
17381 const int f = kAlpha - e - 1;
17382 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
17383
17384 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
17385 JSON_ASSERT(index >= 0);
17386 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
17387
17388 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
17389 JSON_ASSERT(kAlpha <= cached.e + e + 64);
17390 JSON_ASSERT(kGamma >= cached.e + e + 64);
17391
17392 return cached;
17393 }
17394
17399 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
17400 {
17401 // LCOV_EXCL_START
17402 if (n >= 1000000000)
17403 {
17404 pow10 = 1000000000;
17405 return 10;
17406 }
17407 // LCOV_EXCL_STOP
17408 if (n >= 100000000)
17409 {
17410 pow10 = 100000000;
17411 return 9;
17412 }
17413 if (n >= 10000000)
17414 {
17415 pow10 = 10000000;
17416 return 8;
17417 }
17418 if (n >= 1000000)
17419 {
17420 pow10 = 1000000;
17421 return 7;
17422 }
17423 if (n >= 100000)
17424 {
17425 pow10 = 100000;
17426 return 6;
17427 }
17428 if (n >= 10000)
17429 {
17430 pow10 = 10000;
17431 return 5;
17432 }
17433 if (n >= 1000)
17434 {
17435 pow10 = 1000;
17436 return 4;
17437 }
17438 if (n >= 100)
17439 {
17440 pow10 = 100;
17441 return 3;
17442 }
17443 if (n >= 10)
17444 {
17445 pow10 = 10;
17446 return 2;
17447 }
17448
17449 pow10 = 1;
17450 return 1;
17451 }
17452
17453 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
17454 std::uint64_t rest, std::uint64_t ten_k)
17455 {
17456 JSON_ASSERT(len >= 1);
17457 JSON_ASSERT(dist <= delta);
17458 JSON_ASSERT(rest <= delta);
17459 JSON_ASSERT(ten_k > 0);
17460
17461 // <--------------------------- delta ---->
17462 // <---- dist --------->
17463 // --------------[------------------+-------------------]--------------
17464 // M- w M+
17465 //
17466 // ten_k
17467 // <------>
17468 // <---- rest ---->
17469 // --------------[------------------+----+--------------]--------------
17470 // w V
17471 // = buf * 10^k
17472 //
17473 // ten_k represents a unit-in-the-last-place in the decimal representation
17474 // stored in buf.
17475 // Decrement buf by ten_k while this takes buf closer to w.
17476
17477 // The tests are written in this order to avoid overflow in unsigned
17478 // integer arithmetic.
17479
17480 while (rest < dist
17481 && delta - rest >= ten_k
17482 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
17483 {
17484 JSON_ASSERT(buf[len - 1] != '0');
17485 buf[len - 1]--;
17486 rest += ten_k;
17487 }
17488 }
17489
17494 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
17495 diyfp M_minus, diyfp w, diyfp M_plus)
17496 {
17497 static_assert(kAlpha >= -60, "internal error");
17498 static_assert(kGamma <= -32, "internal error");
17499
17500 // Generates the digits (and the exponent) of a decimal floating-point
17501 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
17502 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
17503 //
17504 // <--------------------------- delta ---->
17505 // <---- dist --------->
17506 // --------------[------------------+-------------------]--------------
17507 // M- w M+
17508 //
17509 // Grisu2 generates the digits of M+ from left to right and stops as soon as
17510 // V is in [M-,M+].
17511
17512 JSON_ASSERT(M_plus.e >= kAlpha);
17513 JSON_ASSERT(M_plus.e <= kGamma);
17514
17515 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
17516 std::uint64_t dist = diyfp::sub(M_plus, w).f; // (significand of (M+ - w ), implicit exponent is e)
17517
17518 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
17519 //
17520 // M+ = f * 2^e
17521 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
17522 // = ((p1 ) * 2^-e + (p2 )) * 2^e
17523 // = p1 + p2 * 2^e
17524
17525 const diyfp one(std::uint64_t{ 1 } << -M_plus.e, M_plus.e);
17526
17527 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.)
17528 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
17529
17530 // 1)
17531 //
17532 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
17533
17534 JSON_ASSERT(p1 > 0);
17535
17536 std::uint32_t pow10{};
17537 const int k = find_largest_pow10(p1, pow10);
17538
17539 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
17540 //
17541 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
17542 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
17543 //
17544 // M+ = p1 + p2 * 2^e
17545 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
17546 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
17547 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
17548 //
17549 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
17550 //
17551 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
17552 //
17553 // but stop as soon as
17554 //
17555 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
17556
17557 int n = k;
17558 while (n > 0)
17559 {
17560 // Invariants:
17561 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
17562 // pow10 = 10^(n-1) <= p1 < 10^n
17563 //
17564 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
17565 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
17566 //
17567 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
17568 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
17569 //
17570 JSON_ASSERT(d <= 9);
17571 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17572 //
17573 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
17574 //
17575 p1 = r;
17576 n--;
17577 //
17578 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
17579 // pow10 = 10^n
17580 //
17581
17582 // Now check if enough digits have been generated.
17583 // Compute
17584 //
17585 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
17586 //
17587 // Note:
17588 // Since rest and delta share the same exponent e, it suffices to
17589 // compare the significands.
17590 const std::uint64_t rest = (std::uint64_t{ p1 } << -one.e) + p2;
17591 if (rest <= delta)
17592 {
17593 // V = buffer * 10^n, with M- <= V <= M+.
17594
17595 decimal_exponent += n;
17596
17597 // We may now just stop. But instead look if the buffer could be
17598 // decremented to bring V closer to w.
17599 //
17600 // pow10 = 10^n is now 1 ulp in the decimal representation V.
17601 // The rounding procedure works with diyfp's with an implicit
17602 // exponent of e.
17603 //
17604 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
17605 //
17606 const std::uint64_t ten_n = std::uint64_t{ pow10 } << -one.e;
17607 grisu2_round(buffer, length, dist, delta, rest, ten_n);
17608
17609 return;
17610 }
17611
17612 pow10 /= 10;
17613 //
17614 // pow10 = 10^(n-1) <= p1 < 10^n
17615 // Invariants restored.
17616 }
17617
17618 // 2)
17619 //
17620 // The digits of the integral part have been generated:
17621 //
17622 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
17623 // = buffer + p2 * 2^e
17624 //
17625 // Now generate the digits of the fractional part p2 * 2^e.
17626 //
17627 // Note:
17628 // No decimal point is generated: the exponent is adjusted instead.
17629 //
17630 // p2 actually represents the fraction
17631 //
17632 // p2 * 2^e
17633 // = p2 / 2^-e
17634 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
17635 //
17636 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
17637 //
17638 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
17639 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
17640 //
17641 // using
17642 //
17643 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
17644 // = ( d) * 2^-e + ( r)
17645 //
17646 // or
17647 // 10^m * p2 * 2^e = d + r * 2^e
17648 //
17649 // i.e.
17650 //
17651 // M+ = buffer + p2 * 2^e
17652 // = buffer + 10^-m * (d + r * 2^e)
17653 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
17654 //
17655 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
17656
17657 JSON_ASSERT(p2 > delta);
17658
17659 int m = 0;
17660 for (;;)
17661 {
17662 // Invariant:
17663 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
17664 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
17665 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
17666 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
17667 //
17668 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
17669 p2 *= 10;
17670 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
17671 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
17672 //
17673 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
17674 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
17675 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
17676 //
17677 JSON_ASSERT(d <= 9);
17678 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
17679 //
17680 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
17681 //
17682 p2 = r;
17683 m++;
17684 //
17685 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
17686 // Invariant restored.
17687
17688 // Check if enough digits have been generated.
17689 //
17690 // 10^-m * p2 * 2^e <= delta * 2^e
17691 // p2 * 2^e <= 10^m * delta * 2^e
17692 // p2 <= 10^m * delta
17693 delta *= 10;
17694 dist *= 10;
17695 if (p2 <= delta)
17696 {
17697 break;
17698 }
17699 }
17700
17701 // V = buffer * 10^-m, with M- <= V <= M+.
17702
17703 decimal_exponent -= m;
17704
17705 // 1 ulp in the decimal representation is now 10^-m.
17706 // Since delta and dist are now scaled by 10^m, we need to do the
17707 // same with ulp in order to keep the units in sync.
17708 //
17709 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
17710 //
17711 const std::uint64_t ten_m = one.f;
17712 grisu2_round(buffer, length, dist, delta, p2, ten_m);
17713
17714 // By construction this algorithm generates the shortest possible decimal
17715 // number (Loitsch, Theorem 6.2) which rounds back to w.
17716 // For an input number of precision p, at least
17717 //
17718 // N = 1 + ceil(p * log_10(2))
17719 //
17720 // decimal digits are sufficient to identify all binary floating-point
17721 // numbers (Matula, "In-and-Out conversions").
17722 // This implies that the algorithm does not produce more than N decimal
17723 // digits.
17724 //
17725 // N = 17 for p = 53 (IEEE double precision)
17726 // N = 9 for p = 24 (IEEE single precision)
17727 }
17728
17735 inline void grisu2(char* buf, int& len, int& decimal_exponent,
17736 diyfp m_minus, diyfp v, diyfp m_plus)
17737 {
17738 JSON_ASSERT(m_plus.e == m_minus.e);
17739 JSON_ASSERT(m_plus.e == v.e);
17740
17741 // --------(-----------------------+-----------------------)-------- (A)
17742 // m- v m+
17743 //
17744 // --------------------(-----------+-----------------------)-------- (B)
17745 // m- v m+
17746 //
17747 // First scale v (and m- and m+) such that the exponent is in the range
17748 // [alpha, gamma].
17749
17750 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17751
17752 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17753
17754 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17755 const diyfp w = diyfp::mul(v, c_minus_k);
17756 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17757 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17758
17759 // ----(---+---)---------------(---+---)---------------(---+---)----
17760 // w- w w+
17761 // = c*m- = c*v = c*m+
17762 //
17763 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17764 // w+ are now off by a small amount.
17765 // In fact:
17766 //
17767 // w - v * 10^k < 1 ulp
17768 //
17769 // To account for this inaccuracy, add resp. subtract 1 ulp.
17770 //
17771 // --------+---[---------------(---+---)---------------]---+--------
17772 // w- M- w M+ w+
17773 //
17774 // Now any number in [M-, M+] (bounds included) will round to w when input,
17775 // regardless of how the input rounding algorithm breaks ties.
17776 //
17777 // And digit_gen generates the shortest possible such number in [M-, M+].
17778 // Note that this does not mean that Grisu2 always generates the shortest
17779 // possible number in the interval (m-, m+).
17780 const diyfp M_minus(w_minus.f + 1, w_minus.e);
17781 const diyfp M_plus(w_plus.f - 1, w_plus.e);
17782
17783 decimal_exponent = -cached.k; // = -(-k) = k
17784
17785 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17786 }
17787
17793 template<typename FloatType>
17795 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17796 {
17797 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17798 "internal error: not enough precision");
17799
17800 JSON_ASSERT(std::isfinite(value));
17801 JSON_ASSERT(value > 0);
17802
17803 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17804 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17805 // decimal representations are not exactly "short".
17806 //
17807 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17808 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17809 // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17810 // does.
17811 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17812 // representation using the corresponding std::from_chars function recovers value exactly". That
17813 // indicates that single precision floating-point numbers should be recovered using
17814 // 'std::strtof'.
17815 //
17816 // NB: If the neighbors are computed for single-precision numbers, there is a single float
17817 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17818 // value is off by 1 ulp.
17819#if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if)
17820 const boundaries w = compute_boundaries(static_cast<double>(value));
17821#else
17823#endif
17824
17825 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17826 }
17827
17835 inline char* append_exponent(char* buf, int e)
17836 {
17837 JSON_ASSERT(e > -1000);
17838 JSON_ASSERT(e < 1000);
17839
17840 if (e < 0)
17841 {
17842 e = -e;
17843 *buf++ = '-';
17844 }
17845 else
17846 {
17847 *buf++ = '+';
17848 }
17849
17850 auto k = static_cast<std::uint32_t>(e);
17851 if (k < 10)
17852 {
17853 // Always print at least two digits in the exponent.
17854 // This is for compatibility with printf("%g").
17855 *buf++ = '0';
17856 *buf++ = static_cast<char>('0' + k);
17857 }
17858 else if (k < 100)
17859 {
17860 *buf++ = static_cast<char>('0' + k / 10);
17861 k %= 10;
17862 *buf++ = static_cast<char>('0' + k);
17863 }
17864 else
17865 {
17866 *buf++ = static_cast<char>('0' + k / 100);
17867 k %= 100;
17868 *buf++ = static_cast<char>('0' + k / 10);
17869 k %= 10;
17870 *buf++ = static_cast<char>('0' + k);
17871 }
17872
17873 return buf;
17874 }
17875
17887 inline char* format_buffer(char* buf, int len, int decimal_exponent,
17888 int min_exp, int max_exp)
17889 {
17890 JSON_ASSERT(min_exp < 0);
17891 JSON_ASSERT(max_exp > 0);
17892
17893 const int k = len;
17894 const int n = len + decimal_exponent;
17895
17896 // v = buf * 10^(n-k)
17897 // k is the length of the buffer (number of decimal digits)
17898 // n is the position of the decimal point relative to the start of the buffer.
17899
17900 if (k <= n && n <= max_exp)
17901 {
17902 // digits[000]
17903 // len <= max_exp + 2
17904
17905 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17906 // Make it look like a floating-point number (#362, #378)
17907 buf[n + 0] = '.';
17908 buf[n + 1] = '0';
17909 return buf + (static_cast<size_t>(n) + 2);
17910 }
17911
17912 if (0 < n && n <= max_exp)
17913 {
17914 // dig.its
17915 // len <= max_digits10 + 1
17916
17917 JSON_ASSERT(k > n);
17918
17919 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17920 buf[n] = '.';
17921 return buf + (static_cast<size_t>(k) + 1U);
17922 }
17923
17924 if (min_exp < n && n <= 0)
17925 {
17926 // 0.[000]digits
17927 // len <= 2 + (-min_exp - 1) + max_digits10
17928
17929 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17930 buf[0] = '0';
17931 buf[1] = '.';
17932 std::memset(buf + 2, '0', static_cast<size_t>(-n));
17933 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17934 }
17935
17936 if (k == 1)
17937 {
17938 // dE+123
17939 // len <= 1 + 5
17940
17941 buf += 1;
17942 }
17943 else
17944 {
17945 // d.igitsE+123
17946 // len <= max_digits10 + 1 + 5
17947
17948 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17949 buf[1] = '.';
17950 buf += 1 + static_cast<size_t>(k);
17951 }
17952
17953 *buf++ = 'e';
17954 return append_exponent(buf, n - 1);
17955 }
17956
17957 } // namespace dtoa_impl
17958
17969 template<typename FloatType>
17972 char* to_chars(char* first, const char* last, FloatType value)
17973 {
17974 static_cast<void>(last); // maybe unused - fix warning
17975 JSON_ASSERT(std::isfinite(value));
17976
17977 // Use signbit(value) instead of (value < 0) since signbit works for -0.
17978 if (std::signbit(value))
17979 {
17980 value = -value;
17981 *first++ = '-';
17982 }
17983
17984#ifdef __GNUC__
17985#pragma GCC diagnostic push
17986#pragma GCC diagnostic ignored "-Wfloat-equal"
17987#endif
17988 if (value == 0) // +-0
17989 {
17990 *first++ = '0';
17991 // Make it look like a floating-point number (#362, #378)
17992 *first++ = '.';
17993 *first++ = '0';
17994 return first;
17995 }
17996#ifdef __GNUC__
17997#pragma GCC diagnostic pop
17998#endif
17999
18000 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
18001
18002 // Compute v = buffer * 10^decimal_exponent.
18003 // The decimal digits are stored in the buffer, which needs to be interpreted
18004 // as an unsigned decimal integer.
18005 // len is the length of the buffer, i.e. the number of decimal digits.
18006 int len = 0;
18007 int decimal_exponent = 0;
18008 dtoa_impl::grisu2(first, len, decimal_exponent, value);
18009
18010 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
18011
18012 // Format the buffer like printf("%.*g", prec, value)
18013 constexpr int kMinExp = -4;
18014 // Use digits10 here to increase compatibility with version 2.
18015 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
18016
18017 JSON_ASSERT(last - first >= kMaxExp + 2);
18018 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
18019 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
18020
18021 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
18022 }
18023
18024} // namespace detail
18026
18027// #include <nlohmann/detail/exceptions.hpp>
18028
18029// #include <nlohmann/detail/macro_scope.hpp>
18030
18031// #include <nlohmann/detail/meta/cpp_future.hpp>
18032
18033// #include <nlohmann/detail/output/binary_writer.hpp>
18034
18035// #include <nlohmann/detail/output/output_adapters.hpp>
18036
18037// #include <nlohmann/detail/string_concat.hpp>
18038
18039// #include <nlohmann/detail/value_t.hpp>
18040
18041
18043namespace detail
18044{
18045
18047 // serialization //
18049
18052 {
18056 };
18057
18058 template<typename BasicJsonType>
18060 {
18061 using string_t = typename BasicJsonType::string_t;
18062 using number_float_t = typename BasicJsonType::number_float_t;
18063 using number_integer_t = typename BasicJsonType::number_integer_t;
18064 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18065 using binary_char_t = typename BasicJsonType::binary_t::value_type;
18066 static constexpr std::uint8_t UTF8_ACCEPT = 0;
18067 static constexpr std::uint8_t UTF8_REJECT = 1;
18068
18069 public:
18077 : o(std::move(s))
18078 , loc(std::localeconv())
18079 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->thousands_sep)))
18080 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->decimal_point)))
18081 , indent_char(ichar)
18083 , error_handler(error_handler_)
18084 {}
18085
18086 // delete because of pointer members
18087 serializer(const serializer&) = delete;
18091 ~serializer() = default;
18092
18115 void dump(const BasicJsonType& val,
18116 const bool pretty_print,
18117 const bool ensure_ascii,
18118 const unsigned int indent_step,
18119 const unsigned int current_indent = 0)
18120 {
18121 switch (val.m_data.m_type)
18122 {
18123 case value_t::object:
18124 {
18125 if (val.m_data.m_value.object->empty())
18126 {
18127 o->write_characters("{}", 2);
18128 return;
18129 }
18130
18131 if (pretty_print)
18132 {
18133 o->write_characters("{\n", 2);
18134
18135 // variable to hold indentation for recursive calls
18136 const auto new_indent = current_indent + indent_step;
18137 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18138 {
18139 indent_string.resize(indent_string.size() * 2, ' ');
18140 }
18141
18142 // first n-1 elements
18143 auto i = val.m_data.m_value.object->cbegin();
18144 for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18145 {
18146 o->write_characters(indent_string.c_str(), new_indent);
18147 o->write_character('\"');
18148 dump_escaped(i->first, ensure_ascii);
18149 o->write_characters("\": ", 3);
18150 dump(i->second, true, ensure_ascii, indent_step, new_indent);
18151 o->write_characters(",\n", 2);
18152 }
18153
18154 // last element
18155 JSON_ASSERT(i != val.m_data.m_value.object->cend());
18156 JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18157 o->write_characters(indent_string.c_str(), new_indent);
18158 o->write_character('\"');
18159 dump_escaped(i->first, ensure_ascii);
18160 o->write_characters("\": ", 3);
18161 dump(i->second, true, ensure_ascii, indent_step, new_indent);
18162
18163 o->write_character('\n');
18164 o->write_characters(indent_string.c_str(), current_indent);
18165 o->write_character('}');
18166 }
18167 else
18168 {
18169 o->write_character('{');
18170
18171 // first n-1 elements
18172 auto i = val.m_data.m_value.object->cbegin();
18173 for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
18174 {
18175 o->write_character('\"');
18176 dump_escaped(i->first, ensure_ascii);
18177 o->write_characters("\":", 2);
18178 dump(i->second, false, ensure_ascii, indent_step, current_indent);
18179 o->write_character(',');
18180 }
18181
18182 // last element
18183 JSON_ASSERT(i != val.m_data.m_value.object->cend());
18184 JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
18185 o->write_character('\"');
18186 dump_escaped(i->first, ensure_ascii);
18187 o->write_characters("\":", 2);
18188 dump(i->second, false, ensure_ascii, indent_step, current_indent);
18189
18190 o->write_character('}');
18191 }
18192
18193 return;
18194 }
18195
18196 case value_t::array:
18197 {
18198 if (val.m_data.m_value.array->empty())
18199 {
18200 o->write_characters("[]", 2);
18201 return;
18202 }
18203
18204 if (pretty_print)
18205 {
18206 o->write_characters("[\n", 2);
18207
18208 // variable to hold indentation for recursive calls
18209 const auto new_indent = current_indent + indent_step;
18210 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18211 {
18212 indent_string.resize(indent_string.size() * 2, ' ');
18213 }
18214
18215 // first n-1 elements
18216 for (auto i = val.m_data.m_value.array->cbegin();
18217 i != val.m_data.m_value.array->cend() - 1; ++i)
18218 {
18219 o->write_characters(indent_string.c_str(), new_indent);
18220 dump(*i, true, ensure_ascii, indent_step, new_indent);
18221 o->write_characters(",\n", 2);
18222 }
18223
18224 // last element
18225 JSON_ASSERT(!val.m_data.m_value.array->empty());
18226 o->write_characters(indent_string.c_str(), new_indent);
18227 dump(val.m_data.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
18228
18229 o->write_character('\n');
18230 o->write_characters(indent_string.c_str(), current_indent);
18231 o->write_character(']');
18232 }
18233 else
18234 {
18235 o->write_character('[');
18236
18237 // first n-1 elements
18238 for (auto i = val.m_data.m_value.array->cbegin();
18239 i != val.m_data.m_value.array->cend() - 1; ++i)
18240 {
18241 dump(*i, false, ensure_ascii, indent_step, current_indent);
18242 o->write_character(',');
18243 }
18244
18245 // last element
18246 JSON_ASSERT(!val.m_data.m_value.array->empty());
18247 dump(val.m_data.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
18248
18249 o->write_character(']');
18250 }
18251
18252 return;
18253 }
18254
18255 case value_t::string:
18256 {
18257 o->write_character('\"');
18258 dump_escaped(*val.m_data.m_value.string, ensure_ascii);
18259 o->write_character('\"');
18260 return;
18261 }
18262
18263 case value_t::binary:
18264 {
18265 if (pretty_print)
18266 {
18267 o->write_characters("{\n", 2);
18268
18269 // variable to hold indentation for recursive calls
18270 const auto new_indent = current_indent + indent_step;
18271 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
18272 {
18273 indent_string.resize(indent_string.size() * 2, ' ');
18274 }
18275
18276 o->write_characters(indent_string.c_str(), new_indent);
18277
18278 o->write_characters("\"bytes\": [", 10);
18279
18280 if (!val.m_data.m_value.binary->empty())
18281 {
18282 for (auto i = val.m_data.m_value.binary->cbegin();
18283 i != val.m_data.m_value.binary->cend() - 1; ++i)
18284 {
18285 dump_integer(*i);
18286 o->write_characters(", ", 2);
18287 }
18288 dump_integer(val.m_data.m_value.binary->back());
18289 }
18290
18291 o->write_characters("],\n", 3);
18292 o->write_characters(indent_string.c_str(), new_indent);
18293
18294 o->write_characters("\"subtype\": ", 11);
18295 if (val.m_data.m_value.binary->has_subtype())
18296 {
18297 dump_integer(val.m_data.m_value.binary->subtype());
18298 }
18299 else
18300 {
18301 o->write_characters("null", 4);
18302 }
18303 o->write_character('\n');
18304 o->write_characters(indent_string.c_str(), current_indent);
18305 o->write_character('}');
18306 }
18307 else
18308 {
18309 o->write_characters("{\"bytes\":[", 10);
18310
18311 if (!val.m_data.m_value.binary->empty())
18312 {
18313 for (auto i = val.m_data.m_value.binary->cbegin();
18314 i != val.m_data.m_value.binary->cend() - 1; ++i)
18315 {
18316 dump_integer(*i);
18317 o->write_character(',');
18318 }
18319 dump_integer(val.m_data.m_value.binary->back());
18320 }
18321
18322 o->write_characters("],\"subtype\":", 12);
18323 if (val.m_data.m_value.binary->has_subtype())
18324 {
18325 dump_integer(val.m_data.m_value.binary->subtype());
18326 o->write_character('}');
18327 }
18328 else
18329 {
18330 o->write_characters("null}", 5);
18331 }
18332 }
18333 return;
18334 }
18335
18336 case value_t::boolean:
18337 {
18338 if (val.m_data.m_value.boolean)
18339 {
18340 o->write_characters("true", 4);
18341 }
18342 else
18343 {
18344 o->write_characters("false", 5);
18345 }
18346 return;
18347 }
18348
18350 {
18351 dump_integer(val.m_data.m_value.number_integer);
18352 return;
18353 }
18354
18356 {
18357 dump_integer(val.m_data.m_value.number_unsigned);
18358 return;
18359 }
18360
18362 {
18363 dump_float(val.m_data.m_value.number_float);
18364 return;
18365 }
18366
18367 case value_t::discarded:
18368 {
18369 o->write_characters("<discarded>", 11);
18370 return;
18371 }
18372
18373 case value_t::null:
18374 {
18375 o->write_characters("null", 4);
18376 return;
18377 }
18378
18379 default: // LCOV_EXCL_LINE
18380 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18381 }
18382 }
18383
18399 void dump_escaped(const string_t& s, const bool ensure_ascii)
18400 {
18401 std::uint32_t codepoint{};
18402 std::uint8_t state = UTF8_ACCEPT;
18403 std::size_t bytes = 0; // number of bytes written to string_buffer
18404
18405 // number of bytes written at the point of the last valid byte
18407 std::size_t undumped_chars = 0;
18408
18409 for (std::size_t i = 0; i < s.size(); ++i)
18410 {
18411 const auto byte = static_cast<std::uint8_t>(s[i]);
18412
18413 switch (decode(state, codepoint, byte))
18414 {
18415 case UTF8_ACCEPT: // decode found a new code point
18416 {
18417 switch (codepoint)
18418 {
18419 case 0x08: // backspace
18420 {
18421 string_buffer[bytes++] = '\\';
18422 string_buffer[bytes++] = 'b';
18423 break;
18424 }
18425
18426 case 0x09: // horizontal tab
18427 {
18428 string_buffer[bytes++] = '\\';
18429 string_buffer[bytes++] = 't';
18430 break;
18431 }
18432
18433 case 0x0A: // newline
18434 {
18435 string_buffer[bytes++] = '\\';
18436 string_buffer[bytes++] = 'n';
18437 break;
18438 }
18439
18440 case 0x0C: // formfeed
18441 {
18442 string_buffer[bytes++] = '\\';
18443 string_buffer[bytes++] = 'f';
18444 break;
18445 }
18446
18447 case 0x0D: // carriage return
18448 {
18449 string_buffer[bytes++] = '\\';
18450 string_buffer[bytes++] = 'r';
18451 break;
18452 }
18453
18454 case 0x22: // quotation mark
18455 {
18456 string_buffer[bytes++] = '\\';
18457 string_buffer[bytes++] = '\"';
18458 break;
18459 }
18460
18461 case 0x5C: // reverse solidus
18462 {
18463 string_buffer[bytes++] = '\\';
18464 string_buffer[bytes++] = '\\';
18465 break;
18466 }
18467
18468 default:
18469 {
18470 // escape control characters (0x00..0x1F) or, if
18471 // ensure_ascii parameter is used, non-ASCII characters
18472 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
18473 {
18474 if (codepoint <= 0xFFFF)
18475 {
18476 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18477 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
18478 static_cast<std::uint16_t>(codepoint)));
18479 bytes += 6;
18480 }
18481 else
18482 {
18483 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18484 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
18485 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
18486 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
18487 bytes += 12;
18488 }
18489 }
18490 else
18491 {
18492 // copy byte to buffer (all previous bytes
18493 // been copied have in default case above)
18494 string_buffer[bytes++] = s[i];
18495 }
18496 break;
18497 }
18498 }
18499
18500 // write buffer and reset index; there must be 13 bytes
18501 // left, as this is the maximal number of bytes to be
18502 // written ("\uxxxx\uxxxx\0") for one code point
18503 if (string_buffer.size() - bytes < 13)
18504 {
18505 o->write_characters(string_buffer.data(), bytes);
18506 bytes = 0;
18507 }
18508
18509 // remember the byte position of this accept
18511 undumped_chars = 0;
18512 break;
18513 }
18514
18515 case UTF8_REJECT: // decode found invalid UTF-8 byte
18516 {
18517 switch (error_handler)
18518 {
18520 {
18521 JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
18522 }
18523
18526 {
18527 // in case we saw this character the first time, we
18528 // would like to read it again, because the byte
18529 // may be OK for itself, but just not OK for the
18530 // previous sequence
18531 if (undumped_chars > 0)
18532 {
18533 --i;
18534 }
18535
18536 // reset length buffer to the last accepted index;
18537 // thus removing/ignoring the invalid characters
18539
18541 {
18542 // add a replacement character
18543 if (ensure_ascii)
18544 {
18545 string_buffer[bytes++] = '\\';
18546 string_buffer[bytes++] = 'u';
18547 string_buffer[bytes++] = 'f';
18548 string_buffer[bytes++] = 'f';
18549 string_buffer[bytes++] = 'f';
18550 string_buffer[bytes++] = 'd';
18551 }
18552 else
18553 {
18557 }
18558
18559 // write buffer and reset index; there must be 13 bytes
18560 // left, as this is the maximal number of bytes to be
18561 // written ("\uxxxx\uxxxx\0") for one code point
18562 if (string_buffer.size() - bytes < 13)
18563 {
18564 o->write_characters(string_buffer.data(), bytes);
18565 bytes = 0;
18566 }
18567
18569 }
18570
18571 undumped_chars = 0;
18572
18573 // continue processing the string
18575 break;
18576 }
18577
18578 default: // LCOV_EXCL_LINE
18579 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18580 }
18581 break;
18582 }
18583
18584 default: // decode found yet incomplete multi-byte code point
18585 {
18586 if (!ensure_ascii)
18587 {
18588 // code point will not be escaped - copy byte to buffer
18589 string_buffer[bytes++] = s[i];
18590 }
18592 break;
18593 }
18594 }
18595 }
18596
18597 // we finished processing the string
18599 {
18600 // write buffer
18601 if (bytes > 0)
18602 {
18603 o->write_characters(string_buffer.data(), bytes);
18604 }
18605 }
18606 else
18607 {
18608 // we finish reading, but do not accept: string was incomplete
18609 switch (error_handler)
18610 {
18612 {
18613 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));
18614 }
18615
18617 {
18618 // write all accepted bytes
18619 o->write_characters(string_buffer.data(), bytes_after_last_accept);
18620 break;
18621 }
18622
18624 {
18625 // write all accepted bytes
18626 o->write_characters(string_buffer.data(), bytes_after_last_accept);
18627 // add a replacement character
18628 if (ensure_ascii)
18629 {
18630 o->write_characters("\\ufffd", 6);
18631 }
18632 else
18633 {
18634 o->write_characters("\xEF\xBF\xBD", 3);
18635 }
18636 break;
18637 }
18638
18639 default: // LCOV_EXCL_LINE
18640 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18641 }
18642 }
18643 }
18644
18645 private:
18654 inline unsigned int count_digits(number_unsigned_t x) noexcept
18655 {
18656 unsigned int n_digits = 1;
18657 for (;;)
18658 {
18659 if (x < 10)
18660 {
18661 return n_digits;
18662 }
18663 if (x < 100)
18664 {
18665 return n_digits + 1;
18666 }
18667 if (x < 1000)
18668 {
18669 return n_digits + 2;
18670 }
18671 if (x < 10000)
18672 {
18673 return n_digits + 3;
18674 }
18675 x = x / 10000u;
18676 n_digits += 4;
18677 }
18678 }
18679
18685 static std::string hex_bytes(std::uint8_t byte)
18686 {
18687 std::string result = "FF";
18688 constexpr const char* nibble_to_hex = "0123456789ABCDEF";
18689 result[0] = nibble_to_hex[byte / 16];
18690 result[1] = nibble_to_hex[byte % 16];
18691 return result;
18692 }
18693
18694 // templates to avoid warnings about useless casts
18695 template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
18696 bool is_negative_number(NumberType x)
18697 {
18698 return x < 0;
18699 }
18700
18701 template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
18702 bool is_negative_number(NumberType /*unused*/)
18703 {
18704 return false;
18705 }
18706
18716 template < typename NumberType, detail::enable_if_t <
18717 std::is_integral<NumberType>::value ||
18718 std::is_same<NumberType, number_unsigned_t>::value ||
18719 std::is_same<NumberType, number_integer_t>::value ||
18720 std::is_same<NumberType, binary_char_t>::value,
18721 int > = 0 >
18722 void dump_integer(NumberType x)
18723 {
18724 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
18725 {
18726 {
18727 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
18728 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
18729 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
18730 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
18731 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
18732 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
18733 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
18734 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
18735 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
18736 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
18737 }
18738 };
18739
18740 // special case for "0"
18741 if (x == 0)
18742 {
18743 o->write_character('0');
18744 return;
18745 }
18746
18747 // use a pointer to fill the buffer
18748 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18749
18750 number_unsigned_t abs_value;
18751
18752 unsigned int n_chars{};
18753
18754 if (is_negative_number(x))
18755 {
18756 *buffer_ptr = '-';
18757 abs_value = remove_sign(static_cast<number_integer_t>(x));
18758
18759 // account one more byte for the minus sign
18760 n_chars = 1 + count_digits(abs_value);
18761 }
18762 else
18763 {
18764 abs_value = static_cast<number_unsigned_t>(x);
18765 n_chars = count_digits(abs_value);
18766 }
18767
18768 // spare 1 byte for '\0'
18769 JSON_ASSERT(n_chars < number_buffer.size() - 1);
18770
18771 // jump to the end to generate the string from backward,
18772 // so we later avoid reversing the result
18773 buffer_ptr += n_chars;
18774
18775 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18776 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18777 while (abs_value >= 100)
18778 {
18779 const auto digits_index = static_cast<unsigned>((abs_value % 100));
18780 abs_value /= 100;
18781 *(--buffer_ptr) = digits_to_99[digits_index][1];
18782 *(--buffer_ptr) = digits_to_99[digits_index][0];
18783 }
18784
18785 if (abs_value >= 10)
18786 {
18787 const auto digits_index = static_cast<unsigned>(abs_value);
18788 *(--buffer_ptr) = digits_to_99[digits_index][1];
18789 *(--buffer_ptr) = digits_to_99[digits_index][0];
18790 }
18791 else
18792 {
18793 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18794 }
18795
18796 o->write_characters(number_buffer.data(), n_chars);
18797 }
18798
18807 void dump_float(number_float_t x)
18808 {
18809 // NaN / inf
18810 if (!std::isfinite(x))
18811 {
18812 o->write_characters("null", 4);
18813 return;
18814 }
18815
18816 // If number_float_t is an IEEE-754 single or double precision number,
18817 // use the Grisu2 algorithm to produce short numbers which are
18818 // guaranteed to round-trip, using strtof and strtod, resp.
18819 //
18820 // NB: The test below works if <long double> == <double>.
18821 static constexpr bool is_ieee_single_or_double
18822 = (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) ||
18823 (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);
18824
18825 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18826 }
18827
18828 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18829 {
18830 auto* begin = number_buffer.data();
18831 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18832
18833 o->write_characters(begin, static_cast<size_t>(end - begin));
18834 }
18835
18836 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18837 {
18838 // get number of digits for a float -> text -> float round-trip
18839 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18840
18841 // the actual conversion
18842 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18843 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18844
18845 // negative value indicates an error
18846 JSON_ASSERT(len > 0);
18847 // check if buffer was large enough
18848 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18849
18850 // erase thousands separator
18851 if (thousands_sep != '\0')
18852 {
18853 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18854 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18855 std::fill(end, number_buffer.end(), '\0');
18856 JSON_ASSERT((end - number_buffer.begin()) <= len);
18857 len = (end - number_buffer.begin());
18858 }
18859
18860 // convert decimal point to '.'
18861 if (decimal_point != '\0' && decimal_point != '.')
18862 {
18863 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18864 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18865 if (dec_pos != number_buffer.end())
18866 {
18867 *dec_pos = '.';
18868 }
18869 }
18870
18871 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18872
18873 // determine if we need to append ".0"
18874 const bool value_is_int_like =
18875 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18876 [](char c)
18877 {
18878 return c == '.' || c == 'e';
18879 });
18880
18881 if (value_is_int_like)
18882 {
18883 o->write_characters(".0", 2);
18884 }
18885 }
18886
18908 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18909 {
18910 static const std::array<std::uint8_t, 400> utf8d =
18911 {
18912 {
18913 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
18914 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
18915 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
18916 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
18917 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
18918 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
18919 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
18920 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18921 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18922 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18923 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
18924 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
18925 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
18926 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
18927 }
18928 };
18929
18930 JSON_ASSERT(byte < utf8d.size());
18931 const std::uint8_t type = utf8d[byte];
18932
18933 codep = (state != UTF8_ACCEPT)
18934 ? (byte & 0x3fu) | (codep << 6u)
18935 : (0xFFu >> type) & (byte);
18936
18937 const std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18938 JSON_ASSERT(index < utf8d.size());
18939 state = utf8d[index];
18940 return state;
18941 }
18942
18943 /*
18944 * Overload to make the compiler happy while it is instantiating
18945 * dump_integer for number_unsigned_t.
18946 * Must never be called.
18947 */
18948 number_unsigned_t remove_sign(number_unsigned_t x)
18949 {
18950 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18951 return x; // LCOV_EXCL_LINE
18952 }
18953
18954 /*
18955 * Helper function for dump_integer
18956 *
18957 * This function takes a negative signed integer and returns its absolute
18958 * value as unsigned integer. The plus/minus shuffling is necessary as we can
18959 * not directly remove the sign of an arbitrary signed integer as the
18960 * absolute values of INT_MIN and INT_MAX are usually not the same. See
18961 * #1708 for details.
18962 */
18963 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18964 {
18965 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18966 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18967 }
18968
18969 private:
18971 output_adapter_t<char> o = nullptr;
18972
18974 std::array<char, 64> number_buffer{ {} };
18975
18977 const std::lconv* loc = nullptr;
18979 const char thousands_sep = '\0';
18981 const char decimal_point = '\0';
18982
18984 std::array<char, 512> string_buffer{ {} };
18985
18987 const char indent_char;
18990
18993 };
18994
18995} // namespace detail
18997
18998// #include <nlohmann/detail/value_t.hpp>
18999
19000// #include <nlohmann/json_fwd.hpp>
19001
19002// #include <nlohmann/ordered_map.hpp>
19003// __ _____ _____ _____
19004// __| | __| | | | JSON for Modern C++
19005// | | |__ | | | | | | version 3.11.3
19006// |_____|_____|_____|_|___| https://github.com/nlohmann/json
19007//
19008// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
19009// SPDX-License-Identifier: MIT
19010
19011
19012
19013#include <functional> // equal_to, less
19014#include <initializer_list> // initializer_list
19015#include <iterator> // input_iterator_tag, iterator_traits
19016#include <memory> // allocator
19017#include <stdexcept> // for out_of_range
19018#include <type_traits> // enable_if, is_convertible
19019#include <utility> // pair
19020#include <vector> // vector
19021
19022// #include <nlohmann/detail/macro_scope.hpp>
19023
19024// #include <nlohmann/detail/meta/type_traits.hpp>
19025
19026
19028
19031template <class Key, class T, class IgnoredLess = std::less<Key>,
19032 class Allocator = std::allocator<std::pair<const Key, T>>>
19033struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
19034{
19035 using key_type = Key;
19037 using Container = std::vector<std::pair<const Key, T>, Allocator>;
19038 using iterator = typename Container::iterator;
19039 using const_iterator = typename Container::const_iterator;
19040 using size_type = typename Container::size_type;
19041 using value_type = typename Container::value_type;
19042#ifdef JSON_HAS_CPP_14
19043 using key_compare = std::equal_to<>;
19044#else
19045 using key_compare = std::equal_to<Key>;
19046#endif
19047
19048 // Explicit constructors instead of `using Container::Container`
19049 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
19050 ordered_map() noexcept(noexcept(Container())) : Container{} {}
19051 explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{ alloc } {}
19052 template <class It>
19053 ordered_map(It first, It last, const Allocator& alloc = Allocator())
19054 : Container{ first, last, alloc } {}
19055 ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator())
19056 : Container{ init, alloc } {}
19057
19058 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
19059 {
19060 for (auto it = this->begin(); it != this->end(); ++it)
19061 {
19062 if (m_compare(it->first, key))
19063 {
19064 return { it, false };
19065 }
19066 }
19067 Container::emplace_back(key, std::forward<T>(t));
19068 return { std::prev(this->end()), true };
19069 }
19070
19071 template<class KeyType, detail::enable_if_t<
19073 std::pair<iterator, bool> emplace(KeyType&& key, T&& t)
19074 {
19075 for (auto it = this->begin(); it != this->end(); ++it)
19076 {
19077 if (m_compare(it->first, key))
19078 {
19079 return { it, false };
19080 }
19081 }
19082 Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
19083 return { std::prev(this->end()), true };
19084 }
19085
19086 T& operator[](const key_type& key)
19087 {
19088 return emplace(key, T{}).first->second;
19089 }
19090
19091 template<class KeyType, detail::enable_if_t<
19093 T& operator[](KeyType&& key)
19094 {
19095 return emplace(std::forward<KeyType>(key), T{}).first->second;
19096 }
19097
19098 const T& operator[](const key_type& key) const
19099 {
19100 return at(key);
19101 }
19102
19103 template<class KeyType, detail::enable_if_t<
19105 const T& operator[](KeyType&& key) const
19106 {
19107 return at(std::forward<KeyType>(key));
19108 }
19109
19110 T& at(const key_type& key)
19111 {
19112 for (auto it = this->begin(); it != this->end(); ++it)
19113 {
19114 if (m_compare(it->first, key))
19115 {
19116 return it->second;
19117 }
19118 }
19119
19120 JSON_THROW(std::out_of_range("key not found"));
19121 }
19122
19123 template<class KeyType, detail::enable_if_t<
19125 T& at(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
19126 {
19127 for (auto it = this->begin(); it != this->end(); ++it)
19128 {
19129 if (m_compare(it->first, key))
19130 {
19131 return it->second;
19132 }
19133 }
19134
19135 JSON_THROW(std::out_of_range("key not found"));
19136 }
19137
19138 const T& at(const key_type& key) const
19139 {
19140 for (auto it = this->begin(); it != this->end(); ++it)
19141 {
19142 if (m_compare(it->first, key))
19143 {
19144 return it->second;
19145 }
19146 }
19147
19148 JSON_THROW(std::out_of_range("key not found"));
19149 }
19150
19151 template<class KeyType, detail::enable_if_t<
19153 const T& at(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19154 {
19155 for (auto it = this->begin(); it != this->end(); ++it)
19156 {
19157 if (m_compare(it->first, key))
19158 {
19159 return it->second;
19160 }
19161 }
19162
19163 JSON_THROW(std::out_of_range("key not found"));
19164 }
19165
19167 {
19168 for (auto it = this->begin(); it != this->end(); ++it)
19169 {
19170 if (m_compare(it->first, key))
19171 {
19172 // Since we cannot move const Keys, re-construct them in place
19173 for (auto next = it; ++next != this->end(); ++it)
19174 {
19175 it->~value_type(); // Destroy but keep allocation
19176 new (&*it) value_type{ std::move(*next) };
19177 }
19178 Container::pop_back();
19179 return 1;
19180 }
19181 }
19182 return 0;
19183 }
19184
19185 template<class KeyType, detail::enable_if_t<
19187 size_type erase(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
19188 {
19189 for (auto it = this->begin(); it != this->end(); ++it)
19190 {
19191 if (m_compare(it->first, key))
19192 {
19193 // Since we cannot move const Keys, re-construct them in place
19194 for (auto next = it; ++next != this->end(); ++it)
19195 {
19196 it->~value_type(); // Destroy but keep allocation
19197 new (&*it) value_type{ std::move(*next) };
19198 }
19199 Container::pop_back();
19200 return 1;
19201 }
19202 }
19203 return 0;
19204 }
19205
19207 {
19208 return erase(pos, std::next(pos));
19209 }
19210
19212 {
19213 if (first == last)
19214 {
19215 return first;
19216 }
19217
19218 const auto elements_affected = std::distance(first, last);
19219 const auto offset = std::distance(Container::begin(), first);
19220
19221 // This is the start situation. We need to delete elements_affected
19222 // elements (3 in this example: e, f, g), and need to return an
19223 // iterator past the last deleted element (h in this example).
19224 // Note that offset is the distance from the start of the vector
19225 // to first. We will need this later.
19226
19227 // [ a, b, c, d, e, f, g, h, i, j ]
19228 // ^ ^
19229 // first last
19230
19231 // Since we cannot move const Keys, we re-construct them in place.
19232 // We start at first and re-construct (viz. copy) the elements from
19233 // the back of the vector. Example for first iteration:
19234
19235 // ,--------.
19236 // v | destroy e and re-construct with h
19237 // [ a, b, c, d, e, f, g, h, i, j ]
19238 // ^ ^
19239 // it it + elements_affected
19240
19241 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
19242 {
19243 it->~value_type(); // destroy but keep allocation
19244 new (&*it) value_type{ std::move(*std::next(it, elements_affected)) }; // "move" next element to it
19245 }
19246
19247 // [ a, b, c, d, h, i, j, h, i, j ]
19248 // ^ ^
19249 // first last
19250
19251 // remove the unneeded elements at the end of the vector
19252 Container::resize(this->size() - static_cast<size_type>(elements_affected));
19253
19254 // [ a, b, c, d, h, i, j ]
19255 // ^ ^
19256 // first last
19257
19258 // first is now pointing past the last deleted element, but we cannot
19259 // use this iterator, because it may have been invalidated by the
19260 // resize call. Instead, we can return begin() + offset.
19261 return Container::begin() + offset;
19262 }
19263
19264 size_type count(const key_type& key) const
19265 {
19266 for (auto it = this->begin(); it != this->end(); ++it)
19267 {
19268 if (m_compare(it->first, key))
19269 {
19270 return 1;
19271 }
19272 }
19273 return 0;
19274 }
19275
19276 template<class KeyType, detail::enable_if_t<
19278 size_type count(KeyType&& key) const // NOLINT(cppcoreguidelines-missing-std-forward)
19279 {
19280 for (auto it = this->begin(); it != this->end(); ++it)
19281 {
19282 if (m_compare(it->first, key))
19283 {
19284 return 1;
19285 }
19286 }
19287 return 0;
19288 }
19289
19291 {
19292 for (auto it = this->begin(); it != this->end(); ++it)
19293 {
19294 if (m_compare(it->first, key))
19295 {
19296 return it;
19297 }
19298 }
19299 return Container::end();
19300 }
19301
19302 template<class KeyType, detail::enable_if_t<
19304 iterator find(KeyType&& key) // NOLINT(cppcoreguidelines-missing-std-forward)
19305 {
19306 for (auto it = this->begin(); it != this->end(); ++it)
19307 {
19308 if (m_compare(it->first, key))
19309 {
19310 return it;
19311 }
19312 }
19313 return Container::end();
19314 }
19315
19316 const_iterator find(const key_type& key) const
19317 {
19318 for (auto it = this->begin(); it != this->end(); ++it)
19319 {
19320 if (m_compare(it->first, key))
19321 {
19322 return it;
19323 }
19324 }
19325 return Container::end();
19326 }
19327
19328 std::pair<iterator, bool> insert(value_type&& value)
19329 {
19330 return emplace(value.first, std::move(value.second));
19331 }
19332
19333 std::pair<iterator, bool> insert(const value_type& value)
19334 {
19335 for (auto it = this->begin(); it != this->end(); ++it)
19336 {
19337 if (m_compare(it->first, value.first))
19338 {
19339 return { it, false };
19340 }
19341 }
19342 Container::push_back(value);
19343 return { --this->end(), true };
19344 }
19345
19346 template<typename InputIt>
19347 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
19348 std::input_iterator_tag>::value>::type;
19349
19350 template<typename InputIt, typename = require_input_iter<InputIt>>
19351 void insert(InputIt first, InputIt last)
19352 {
19353 for (auto it = first; it != last; ++it)
19354 {
19355 insert(*it);
19356 }
19357 }
19358
19359private:
19361};
19362
19364
19365
19366#if defined(JSON_HAS_CPP_17)
19367#if JSON_HAS_STATIC_RTTI
19368#include <any>
19369#endif
19370#include <string_view>
19371#endif
19372
19379
19399class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
19400 : public ::nlohmann::detail::json_base_class<CustomBaseClass>
19401{
19402private:
19403 template<detail::value_t> friend struct detail::external_constructor;
19404
19405 template<typename>
19406 friend class ::nlohmann::json_pointer;
19407 // can be restored when json_pointer backwards compatibility is removed
19408 // friend ::nlohmann::json_pointer<StringType>;
19409
19410 template<typename BasicJsonType, typename InputType>
19411 friend class ::nlohmann::detail::parser;
19412 friend ::nlohmann::detail::serializer<basic_json>;
19413 template<typename BasicJsonType>
19414 friend class ::nlohmann::detail::iter_impl;
19415 template<typename BasicJsonType, typename CharType>
19416 friend class ::nlohmann::detail::binary_writer;
19417 template<typename BasicJsonType, typename InputType, typename SAX>
19418 friend class ::nlohmann::detail::binary_reader;
19419 template<typename BasicJsonType>
19420 friend class ::nlohmann::detail::json_sax_dom_parser;
19421 template<typename BasicJsonType>
19422 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
19423 friend class ::nlohmann::detail::exception;
19424
19427 using json_base_class_t = ::nlohmann::detail::json_base_class<CustomBaseClass>;
19428
19430 // convenience aliases for types residing in namespace detail;
19431 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
19432
19433 template<typename InputAdapterType>
19434 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
19435 InputAdapterType adapter,
19437 const bool allow_exceptions = true,
19438 const bool ignore_comments = false
19439 )
19440 {
19441 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
19442 std::move(cb), allow_exceptions, ignore_comments);
19443 }
19444
19445private:
19446 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
19447 template<typename BasicJsonType>
19448 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
19449 template<typename BasicJsonType>
19450 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
19451 template<typename Iterator>
19452 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
19453 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
19454
19455 template<typename CharType>
19456 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
19457
19458 template<typename InputType>
19459 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
19460 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
19461
19463 using serializer = ::nlohmann::detail::serializer<basic_json>;
19464
19465public:
19468 using json_pointer = ::nlohmann::json_pointer<StringType>;
19469 template<typename T, typename SFINAE>
19470 using json_serializer = JSONSerializer<T, SFINAE>;
19476 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
19477
19481
19483 // exceptions //
19485
19489
19496
19498
19500 // container types //
19502
19507
19510
19515
19517 using difference_type = std::ptrdiff_t;
19519 using size_type = std::size_t;
19520
19522 using allocator_type = AllocatorType<basic_json>;
19523
19525 using pointer = typename std::allocator_traits<allocator_type>::pointer;
19527 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
19528
19537
19539
19543 {
19544 return allocator_type();
19545 }
19546
19551 {
19552 basic_json result;
19553
19554 result["copyright"] = "(C) 2013-2023 Niels Lohmann";
19555 result["name"] = "JSON for Modern C++";
19556 result["url"] = "https://github.com/nlohmann/json";
19557 result["version"]["string"] =
19558 detail::concat(std::to_string(NLOHMANN_JSON_VERSION_MAJOR), '.',
19559 std::to_string(NLOHMANN_JSON_VERSION_MINOR), '.',
19560 std::to_string(NLOHMANN_JSON_VERSION_PATCH));
19561 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
19562 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
19563 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
19564
19565#ifdef _WIN32
19566 result["platform"] = "win32";
19567#elif defined __linux__
19568 result["platform"] = "linux";
19569#elif defined __APPLE__
19570 result["platform"] = "apple";
19571#elif defined __unix__
19572 result["platform"] = "unix";
19573#else
19574 result["platform"] = "unknown";
19575#endif
19576
19577#if defined(__ICC) || defined(__INTEL_COMPILER)
19578 result["compiler"] = { {"family", "icc"}, {"version", __INTEL_COMPILER} };
19579#elif defined(__clang__)
19580 result["compiler"] = { {"family", "clang"}, {"version", __clang_version__} };
19581#elif defined(__GNUC__) || defined(__GNUG__)
19582 result["compiler"] = { {"family", "gcc"}, {"version", detail::concat(
19583 std::to_string(__GNUC__), '.',
19584 std::to_string(__GNUC_MINOR__), '.',
19585 std::to_string(__GNUC_PATCHLEVEL__))
19586 }
19587 };
19588#elif defined(__HP_cc) || defined(__HP_aCC)
19589 result["compiler"] = "hp"
19590#elif defined(__IBMCPP__)
19591 result["compiler"] = { {"family", "ilecpp"}, {"version", __IBMCPP__} };
19592#elif defined(_MSC_VER)
19593 result["compiler"] = { {"family", "msvc"}, {"version", _MSC_VER} };
19594#elif defined(__PGI)
19595 result["compiler"] = { {"family", "pgcpp"}, {"version", __PGI} };
19596#elif defined(__SUNPRO_CC)
19597 result["compiler"] = { {"family", "sunpro"}, {"version", __SUNPRO_CC} };
19598#else
19599 result["compiler"] = { {"family", "unknown"}, {"version", "unknown"} };
19600#endif
19601
19602#if defined(_MSVC_LANG)
19603 result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
19604#elif defined(__cplusplus)
19605 result["compiler"]["c++"] = std::to_string(__cplusplus);
19606#else
19607 result["compiler"]["c++"] = "unknown";
19608#endif
19609 return result;
19610 }
19611
19613 // JSON value data types //
19615
19620
19625#if defined(JSON_HAS_CPP_14)
19626 // use of transparent comparator avoids unnecessary repeated construction of temporaries
19627 // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
19628 using default_object_comparator_t = std::less<>;
19629#else
19630 using default_object_comparator_t = std::less<StringType>;
19631#endif
19632
19635 using object_t = ObjectType<StringType,
19636 basic_json,
19638 AllocatorType<std::pair<const StringType,
19639 basic_json>>>;
19640
19643 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
19644
19647 using string_t = StringType;
19648
19651 using boolean_t = BooleanType;
19652
19655 using number_integer_t = NumberIntegerType;
19656
19659 using number_unsigned_t = NumberUnsignedType;
19660
19663 using number_float_t = NumberFloatType;
19664
19667 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
19668
19672
19674
19675private:
19676
19678 template<typename T, typename... Args>
19680 static T* create(Args&& ... args)
19681 {
19682 AllocatorType<T> alloc;
19683 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
19684
19685 auto deleter = [&](T* obj)
19686 {
19687 AllocatorTraits::deallocate(alloc, obj, 1);
19688 };
19689 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
19690 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
19691 JSON_ASSERT(obj != nullptr);
19692 return obj.release();
19693 }
19694
19696 // JSON value storage //
19698
19725 union json_value
19726 {
19743
19745 json_value() = default;
19747 json_value(boolean_t v) noexcept : boolean(v) {}
19756 {
19757 switch (t)
19758 {
19759 case value_t::object:
19760 {
19761 object = create<object_t>();
19762 break;
19763 }
19764
19765 case value_t::array:
19766 {
19768 break;
19769 }
19770
19771 case value_t::string:
19772 {
19773 string = create<string_t>("");
19774 break;
19775 }
19776
19777 case value_t::binary:
19778 {
19780 break;
19781 }
19782
19783 case value_t::boolean:
19784 {
19785 boolean = static_cast<boolean_t>(false);
19786 break;
19787 }
19788
19789 case value_t::number_integer:
19790 {
19791 number_integer = static_cast<number_integer_t>(0);
19792 break;
19793 }
19794
19795 case value_t::number_unsigned:
19796 {
19797 number_unsigned = static_cast<number_unsigned_t>(0);
19798 break;
19799 }
19800
19801 case value_t::number_float:
19802 {
19803 number_float = static_cast<number_float_t>(0.0);
19804 break;
19805 }
19806
19807 case value_t::null:
19808 {
19809 object = nullptr; // silence warning, see #821
19810 break;
19811 }
19812
19813 case value_t::discarded:
19814 default:
19815 {
19816 object = nullptr; // silence warning, see #821
19817 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
19818 {
19819 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.11.3", nullptr)); // LCOV_EXCL_LINE
19820 }
19821 break;
19822 }
19823 }
19824 }
19825
19828
19831
19834
19837
19840
19843
19845 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19846
19848 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19849
19852
19855
19857 {
19858 if (
19859 (t == value_t::object && object == nullptr) ||
19860 (t == value_t::array && array == nullptr) ||
19861 (t == value_t::string && string == nullptr) ||
19862 (t == value_t::binary && binary == nullptr)
19863 )
19864 {
19865 //not initialized (e.g. due to exception in the ctor)
19866 return;
19867 }
19868 if (t == value_t::array || t == value_t::object)
19869 {
19870 // flatten the current json_value to a heap-allocated stack
19871 std::vector<basic_json> stack;
19872
19873 // move the top-level items to stack
19874 if (t == value_t::array)
19875 {
19876 stack.reserve(array->size());
19877 std::move(array->begin(), array->end(), std::back_inserter(stack));
19878 }
19879 else
19880 {
19881 stack.reserve(object->size());
19882 for (auto&& it : *object)
19883 {
19884 stack.push_back(std::move(it.second));
19885 }
19886 }
19887
19888 while (!stack.empty())
19889 {
19890 // move the last item to local variable to be processed
19891 basic_json current_item(std::move(stack.back()));
19892 stack.pop_back();
19893
19894 // if current_item is array/object, move
19895 // its children to the stack to be processed later
19896 if (current_item.is_array())
19897 {
19898 std::move(current_item.m_data.m_value.array->begin(), current_item.m_data.m_value.array->end(), std::back_inserter(stack));
19899
19900 current_item.m_data.m_value.array->clear();
19901 }
19902 else if (current_item.is_object())
19903 {
19904 for (auto&& it : *current_item.m_data.m_value.object)
19905 {
19906 stack.push_back(std::move(it.second));
19907 }
19908
19909 current_item.m_data.m_value.object->clear();
19910 }
19911
19912 // it's now safe that current_item get destructed
19913 // since it doesn't have any children
19914 }
19915 }
19916
19917 switch (t)
19918 {
19919 case value_t::object:
19920 {
19921 AllocatorType<object_t> alloc;
19922 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19923 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19924 break;
19925 }
19926
19927 case value_t::array:
19928 {
19929 AllocatorType<array_t> alloc;
19930 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19931 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19932 break;
19933 }
19934
19935 case value_t::string:
19936 {
19937 AllocatorType<string_t> alloc;
19938 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19939 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19940 break;
19941 }
19942
19943 case value_t::binary:
19944 {
19945 AllocatorType<binary_t> alloc;
19946 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19947 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19948 break;
19949 }
19950
19951 case value_t::null:
19952 case value_t::boolean:
19953 case value_t::number_integer:
19954 case value_t::number_unsigned:
19955 case value_t::number_float:
19956 case value_t::discarded:
19957 default:
19958 {
19959 break;
19960 }
19961 }
19962 }
19963 };
19964
19965private:
19984 void assert_invariant(bool check_parents = true) const noexcept
19985 {
19986 JSON_ASSERT(m_data.m_type != value_t::object || m_data.m_value.object != nullptr);
19987 JSON_ASSERT(m_data.m_type != value_t::array || m_data.m_value.array != nullptr);
19988 JSON_ASSERT(m_data.m_type != value_t::string || m_data.m_value.string != nullptr);
19989 JSON_ASSERT(m_data.m_type != value_t::binary || m_data.m_value.binary != nullptr);
19990
19991#if JSON_DIAGNOSTICS
19992 JSON_TRY
19993 {
19994 // cppcheck-suppress assertWithSideEffect
19995 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json& j)
19996 {
19997 return j.m_parent == this;
19998 }));
19999 }
20000 JSON_CATCH(...) {} // LCOV_EXCL_LINE
20001#endif
20002 static_cast<void>(check_parents);
20003 }
20004
20006 {
20007#if JSON_DIAGNOSTICS
20008 switch (m_data.m_type)
20009 {
20010 case value_t::array:
20011 {
20012 for (auto& element : *m_data.m_value.array)
20013 {
20014 element.m_parent = this;
20015 }
20016 break;
20017 }
20018
20019 case value_t::object:
20020 {
20021 for (auto& element : *m_data.m_value.object)
20022 {
20023 element.second.m_parent = this;
20024 }
20025 break;
20026 }
20027
20028 case value_t::null:
20029 case value_t::string:
20030 case value_t::boolean:
20031 case value_t::number_integer:
20032 case value_t::number_unsigned:
20033 case value_t::number_float:
20034 case value_t::binary:
20035 case value_t::discarded:
20036 default:
20037 break;
20038 }
20039#endif
20040 }
20041
20042 iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
20043 {
20044#if JSON_DIAGNOSTICS
20045 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
20046 {
20047 (it + i)->m_parent = this;
20048 }
20049#else
20050 static_cast<void>(count_set_parents);
20051#endif
20052 return it;
20053 }
20054
20055 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
20056 {
20057#if JSON_DIAGNOSTICS
20058 if (old_capacity != static_cast<std::size_t>(-1))
20059 {
20060 // see https://github.com/nlohmann/json/issues/2838
20061 JSON_ASSERT(type() == value_t::array);
20062 if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
20063 {
20064 // capacity has changed: update all parents
20065 set_parents();
20066 return j;
20067 }
20068 }
20069
20070 // ordered_json uses a vector internally, so pointers could have
20071 // been invalidated; see https://github.com/nlohmann/json/issues/2962
20072#ifdef JSON_HEDLEY_MSVC_VERSION
20073#pragma warning(push )
20074#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
20075#endif
20077 {
20078 set_parents();
20079 return j;
20080 }
20081#ifdef JSON_HEDLEY_MSVC_VERSION
20082#pragma warning( pop )
20083#endif
20084
20085 j.m_parent = this;
20086#else
20087 static_cast<void>(j);
20088 static_cast<void>(old_capacity);
20089#endif
20090 return j;
20091 }
20092
20093public:
20095 // JSON parser callback //
20097
20101
20105
20107 // constructors //
20109
20114
20118 : m_data(v)
20119 {
20121 }
20122
20125 basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
20126 : basic_json(value_t::null)
20127 {
20129 }
20130
20133 template < typename CompatibleType,
20137 basic_json(CompatibleType&& val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
20138 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
20139 std::forward<CompatibleType>(val))))
20140 {
20141 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
20142 set_parents();
20144 }
20145
20148 template < typename BasicJsonType,
20150 detail::is_basic_json<BasicJsonType>::value && !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
20151 basic_json(const BasicJsonType& val)
20152 {
20153 using other_boolean_t = typename BasicJsonType::boolean_t;
20154 using other_number_float_t = typename BasicJsonType::number_float_t;
20155 using other_number_integer_t = typename BasicJsonType::number_integer_t;
20156 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
20157 using other_string_t = typename BasicJsonType::string_t;
20158 using other_object_t = typename BasicJsonType::object_t;
20159 using other_array_t = typename BasicJsonType::array_t;
20160 using other_binary_t = typename BasicJsonType::binary_t;
20161
20162 switch (val.type())
20163 {
20164 case value_t::boolean:
20165 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
20166 break;
20167 case value_t::number_float:
20168 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
20169 break;
20170 case value_t::number_integer:
20171 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
20172 break;
20173 case value_t::number_unsigned:
20174 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
20175 break;
20176 case value_t::string:
20177 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
20178 break;
20179 case value_t::object:
20180 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
20181 break;
20182 case value_t::array:
20183 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
20184 break;
20185 case value_t::binary:
20186 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
20187 break;
20188 case value_t::null:
20189 *this = nullptr;
20190 break;
20191 case value_t::discarded:
20192 m_data.m_type = value_t::discarded;
20193 break;
20194 default: // LCOV_EXCL_LINE
20195 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
20196 }
20197 JSON_ASSERT(m_data.m_type == val.type());
20198 set_parents();
20200 }
20201
20205 bool type_deduction = true,
20206 value_t manual_type = value_t::array)
20207 {
20208 // check if each element is an array with two elements whose first
20209 // element is a string
20210 bool is_an_object = std::all_of(init.begin(), init.end(),
20211 [](const detail::json_ref<basic_json>& element_ref)
20212 {
20213 // The cast is to ensure op[size_type] is called, bearing in mind size_type may not be int;
20214 // (many string types can be constructed from 0 via its null-pointer guise, so we get a
20215 // broken call to op[key_type], the wrong semantics and a 4804 warning on Windows)
20216 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[static_cast<size_type>(0)].is_string();
20217 });
20218
20219 // adjust type if type deduction is not wanted
20220 if (!type_deduction)
20221 {
20222 // if array is wanted, do not create an object though possible
20223 if (manual_type == value_t::array)
20224 {
20225 is_an_object = false;
20226 }
20227
20228 // if object is wanted but impossible, throw an exception
20229 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
20230 {
20231 JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
20232 }
20233 }
20234
20235 if (is_an_object)
20236 {
20237 // the initializer list is a list of pairs -> create object
20238 m_data.m_type = value_t::object;
20239 m_data.m_value = value_t::object;
20240
20241 for (auto& element_ref : init)
20242 {
20243 auto element = element_ref.moved_or_copied();
20244 m_data.m_value.object->emplace(
20245 std::move(*((*element.m_data.m_value.array)[0].m_data.m_value.string)),
20246 std::move((*element.m_data.m_value.array)[1]));
20247 }
20248 }
20249 else
20250 {
20251 // the initializer list describes an array -> create array
20252 m_data.m_type = value_t::array;
20253 m_data.m_value.array = create<array_t>(init.begin(), init.end());
20254 }
20255
20256 set_parents();
20258 }
20259
20263 static basic_json binary(const typename binary_t::container_type& init)
20264 {
20265 auto res = basic_json();
20266 res.m_data.m_type = value_t::binary;
20267 res.m_data.m_value = init;
20268 return res;
20269 }
20270
20274 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
20275 {
20276 auto res = basic_json();
20277 res.m_data.m_type = value_t::binary;
20278 res.m_data.m_value = binary_t(init, subtype);
20279 return res;
20280 }
20281
20285 static basic_json binary(typename binary_t::container_type&& init)
20286 {
20287 auto res = basic_json();
20288 res.m_data.m_type = value_t::binary;
20289 res.m_data.m_value = std::move(init);
20290 return res;
20291 }
20292
20296 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
20297 {
20298 auto res = basic_json();
20299 res.m_data.m_type = value_t::binary;
20300 res.m_data.m_value = binary_t(std::move(init), subtype);
20301 return res;
20302 }
20303
20308 {
20309 return basic_json(init, false, value_t::array);
20310 }
20311
20316 {
20317 return basic_json(init, false, value_t::object);
20318 }
20319
20323 m_data{ cnt, val }
20324 {
20325 set_parents();
20327 }
20328
20331 template < class InputIT, typename std::enable_if <
20332 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
20333 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
20334 basic_json(InputIT first, InputIT last)
20335 {
20336 JSON_ASSERT(first.m_object != nullptr);
20337 JSON_ASSERT(last.m_object != nullptr);
20338
20339 // make sure iterator fits the current value
20340 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20341 {
20342 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
20343 }
20344
20345 // copy type from first iterator
20346 m_data.m_type = first.m_object->m_data.m_type;
20347
20348 // check if iterator range is complete for primitive values
20349 switch (m_data.m_type)
20350 {
20351 case value_t::boolean:
20352 case value_t::number_float:
20353 case value_t::number_integer:
20354 case value_t::number_unsigned:
20355 case value_t::string:
20356 {
20357 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
20358 || !last.m_it.primitive_iterator.is_end()))
20359 {
20360 JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
20361 }
20362 break;
20363 }
20364
20365 case value_t::null:
20366 case value_t::object:
20367 case value_t::array:
20368 case value_t::binary:
20369 case value_t::discarded:
20370 default:
20371 break;
20372 }
20373
20374 switch (m_data.m_type)
20375 {
20376 case value_t::number_integer:
20377 {
20378 m_data.m_value.number_integer = first.m_object->m_data.m_value.number_integer;
20379 break;
20380 }
20381
20382 case value_t::number_unsigned:
20383 {
20384 m_data.m_value.number_unsigned = first.m_object->m_data.m_value.number_unsigned;
20385 break;
20386 }
20387
20388 case value_t::number_float:
20389 {
20390 m_data.m_value.number_float = first.m_object->m_data.m_value.number_float;
20391 break;
20392 }
20393
20394 case value_t::boolean:
20395 {
20396 m_data.m_value.boolean = first.m_object->m_data.m_value.boolean;
20397 break;
20398 }
20399
20400 case value_t::string:
20401 {
20402 m_data.m_value = *first.m_object->m_data.m_value.string;
20403 break;
20404 }
20405
20406 case value_t::object:
20407 {
20408 m_data.m_value.object = create<object_t>(first.m_it.object_iterator,
20409 last.m_it.object_iterator);
20410 break;
20411 }
20412
20413 case value_t::array:
20414 {
20415 m_data.m_value.array = create<array_t>(first.m_it.array_iterator,
20416 last.m_it.array_iterator);
20417 break;
20418 }
20419
20420 case value_t::binary:
20421 {
20422 m_data.m_value = *first.m_object->m_data.m_value.binary;
20423 break;
20424 }
20425
20426 case value_t::null:
20427 case value_t::discarded:
20428 default:
20429 JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
20430 }
20431
20432 set_parents();
20434 }
20435
20437 // other constructors and destructor //
20439
20440 template<typename JsonRef,
20442 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
20443 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
20444
20448 : json_base_class_t(other)
20449 {
20450 m_data.m_type = other.m_data.m_type;
20451 // check of passed value is valid
20452 other.assert_invariant();
20453
20454 switch (m_data.m_type)
20455 {
20456 case value_t::object:
20457 {
20458 m_data.m_value = *other.m_data.m_value.object;
20459 break;
20460 }
20461
20462 case value_t::array:
20463 {
20464 m_data.m_value = *other.m_data.m_value.array;
20465 break;
20466 }
20467
20468 case value_t::string:
20469 {
20470 m_data.m_value = *other.m_data.m_value.string;
20471 break;
20472 }
20473
20474 case value_t::boolean:
20475 {
20476 m_data.m_value = other.m_data.m_value.boolean;
20477 break;
20478 }
20479
20480 case value_t::number_integer:
20481 {
20482 m_data.m_value = other.m_data.m_value.number_integer;
20483 break;
20484 }
20485
20486 case value_t::number_unsigned:
20487 {
20488 m_data.m_value = other.m_data.m_value.number_unsigned;
20489 break;
20490 }
20491
20492 case value_t::number_float:
20493 {
20494 m_data.m_value = other.m_data.m_value.number_float;
20495 break;
20496 }
20497
20498 case value_t::binary:
20499 {
20500 m_data.m_value = *other.m_data.m_value.binary;
20501 break;
20502 }
20503
20504 case value_t::null:
20505 case value_t::discarded:
20506 default:
20507 break;
20508 }
20509
20510 set_parents();
20511 assert_invariant();
20512 }
20513
20516 basic_json(basic_json&& other) noexcept
20517 : json_base_class_t(std::forward<json_base_class_t>(other)),
20518 m_data(std::move(other.m_data))
20519 {
20520 // check that passed value is valid
20521 other.assert_invariant(false);
20522
20523 // invalidate payload
20524 other.m_data.m_type = value_t::null;
20525 other.m_data.m_value = {};
20526
20527 set_parents();
20529 }
20530
20534 std::is_nothrow_move_constructible<value_t>::value&&
20535 std::is_nothrow_move_assignable<value_t>::value&&
20536 std::is_nothrow_move_constructible<json_value>::value&&
20537 std::is_nothrow_move_assignable<json_value>::value&&
20538 std::is_nothrow_move_assignable<json_base_class_t>::value
20539 )
20540 {
20541 // check that passed value is valid
20542 other.assert_invariant();
20543
20544 using std::swap;
20545 swap(m_data.m_type, other.m_data.m_type);
20546 swap(m_data.m_value, other.m_data.m_value);
20547 json_base_class_t::operator=(std::move(other));
20548
20549 set_parents();
20551 return *this;
20552 }
20553
20556 ~basic_json() noexcept
20557 {
20558 assert_invariant(false);
20559 }
20560
20562
20563public:
20565 // object inspection //
20567
20571
20574 string_t dump(const int indent = -1,
20575 const char indent_char = ' ',
20576 const bool ensure_ascii = false,
20577 const error_handler_t error_handler = error_handler_t::strict) const
20578 {
20579 string_t result;
20580 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20581
20582 if (indent >= 0)
20583 {
20584 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20585 }
20586 else
20587 {
20588 s.dump(*this, false, ensure_ascii, 0);
20589 }
20590
20591 return result;
20592 }
20593
20596 constexpr value_t type() const noexcept
20597 {
20598 return m_data.m_type;
20599 }
20600
20603 constexpr bool is_primitive() const noexcept
20604 {
20605 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20606 }
20607
20610 constexpr bool is_structured() const noexcept
20611 {
20612 return is_array() || is_object();
20613 }
20614
20617 constexpr bool is_null() const noexcept
20618 {
20619 return m_data.m_type == value_t::null;
20620 }
20621
20624 constexpr bool is_boolean() const noexcept
20625 {
20626 return m_data.m_type == value_t::boolean;
20627 }
20628
20631 constexpr bool is_number() const noexcept
20632 {
20633 return is_number_integer() || is_number_float();
20634 }
20635
20638 constexpr bool is_number_integer() const noexcept
20639 {
20640 return m_data.m_type == value_t::number_integer || m_data.m_type == value_t::number_unsigned;
20641 }
20642
20645 constexpr bool is_number_unsigned() const noexcept
20646 {
20647 return m_data.m_type == value_t::number_unsigned;
20648 }
20649
20652 constexpr bool is_number_float() const noexcept
20653 {
20654 return m_data.m_type == value_t::number_float;
20655 }
20656
20659 constexpr bool is_object() const noexcept
20660 {
20661 return m_data.m_type == value_t::object;
20662 }
20663
20666 constexpr bool is_array() const noexcept
20667 {
20668 return m_data.m_type == value_t::array;
20669 }
20670
20673 constexpr bool is_string() const noexcept
20674 {
20675 return m_data.m_type == value_t::string;
20676 }
20677
20680 constexpr bool is_binary() const noexcept
20681 {
20682 return m_data.m_type == value_t::binary;
20683 }
20684
20687 constexpr bool is_discarded() const noexcept
20688 {
20689 return m_data.m_type == value_t::discarded;
20690 }
20691
20694 constexpr operator value_t() const noexcept
20695 {
20696 return m_data.m_type;
20697 }
20698
20700
20701private:
20703 // value access //
20705
20707 boolean_t get_impl(boolean_t* /*unused*/) const
20708 {
20710 {
20711 return m_data.m_value.boolean;
20712 }
20713
20714 JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
20715 }
20716
20718 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20719 {
20720 return is_object() ? m_data.m_value.object : nullptr;
20721 }
20722
20724 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20725 {
20726 return is_object() ? m_data.m_value.object : nullptr;
20727 }
20728
20730 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20731 {
20732 return is_array() ? m_data.m_value.array : nullptr;
20733 }
20734
20736 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20737 {
20738 return is_array() ? m_data.m_value.array : nullptr;
20739 }
20740
20742 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20743 {
20744 return is_string() ? m_data.m_value.string : nullptr;
20745 }
20746
20748 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20749 {
20750 return is_string() ? m_data.m_value.string : nullptr;
20751 }
20752
20754 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20755 {
20756 return is_boolean() ? &m_data.m_value.boolean : nullptr;
20757 }
20758
20760 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20761 {
20762 return is_boolean() ? &m_data.m_value.boolean : nullptr;
20763 }
20764
20767 {
20768 return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20769 }
20770
20772 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20773 {
20774 return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
20775 }
20776
20779 {
20780 return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20781 }
20782
20784 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20785 {
20786 return is_number_unsigned() ? &m_data.m_value.number_unsigned : nullptr;
20787 }
20788
20791 {
20792 return is_number_float() ? &m_data.m_value.number_float : nullptr;
20793 }
20794
20796 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20797 {
20798 return is_number_float() ? &m_data.m_value.number_float : nullptr;
20799 }
20800
20802 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20803 {
20804 return is_binary() ? m_data.m_value.binary : nullptr;
20805 }
20806
20808 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20809 {
20810 return is_binary() ? m_data.m_value.binary : nullptr;
20811 }
20812
20824 template<typename ReferenceType, typename ThisType>
20825 static ReferenceType get_ref_impl(ThisType& obj)
20826 {
20827 // delegate the call to get_ptr<>()
20829
20830 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20831 {
20832 return *ptr;
20833 }
20834
20835 JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20836 }
20837
20838public:
20842
20845 template<typename PointerType, typename std::enable_if<
20846 std::is_pointer<PointerType>::value, int>::type = 0>
20847 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20848 {
20849 // delegate the call to get_impl_ptr<>()
20850 return get_impl_ptr(static_cast<PointerType>(nullptr));
20851 }
20852
20855 template < typename PointerType, typename std::enable_if <
20856 std::is_pointer<PointerType>::value&&
20857 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20858 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20859 {
20860 // delegate the call to get_impl_ptr<>() const
20861 return get_impl_ptr(static_cast<PointerType>(nullptr));
20862 }
20863
20864private:
20903 template < typename ValueType,
20907 int > = 0 >
20908 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20909 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20910 {
20911 auto ret = ValueType();
20912 JSONSerializer<ValueType>::from_json(*this, ret);
20913 return ret;
20914 }
20915
20946 template < typename ValueType,
20949 int > = 0 >
20950 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20951 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20952 {
20953 return JSONSerializer<ValueType>::from_json(*this);
20954 }
20955
20971 template < typename BasicJsonType,
20974 int > = 0 >
20975 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20976 {
20977 return *this;
20978 }
20979
20994 template<typename BasicJsonType,
20996 std::is_same<BasicJsonType, basic_json_t>::value,
20997 int> = 0>
20999 {
21000 return *this;
21001 }
21002
21007 template<typename PointerType,
21009 std::is_pointer<PointerType>::value,
21010 int> = 0>
21011 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
21012 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
21013 {
21014 // delegate the call to get_ptr
21015 return get_ptr<PointerType>();
21016 }
21017
21018public:
21042 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
21043#if defined(JSON_HAS_CPP_14)
21044 constexpr
21045#endif
21046 auto get() const noexcept(
21047 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
21048 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
21049 {
21050 // we cannot static_assert on ValueTypeCV being non-const, because
21051 // there is support for get<const basic_json_t>(), which is why we
21052 // still need the uncvref
21053 static_assert(!std::is_reference<ValueTypeCV>::value,
21054 "get() cannot be used with reference types, you might want to use get_ref()");
21055 return get_impl<ValueType>(detail::priority_tag<4> {});
21056 }
21057
21085 template<typename PointerType, typename std::enable_if<
21086 std::is_pointer<PointerType>::value, int>::type = 0>
21087 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
21088 {
21089 // delegate the call to get_ptr
21090 return get_ptr<PointerType>();
21091 }
21092
21095 template < typename ValueType,
21099 int > = 0 >
21100 ValueType& get_to(ValueType& v) const noexcept(noexcept(
21101 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
21102 {
21103 JSONSerializer<ValueType>::from_json(*this, v);
21104 return v;
21105 }
21106
21107 // specialization to allow calling get_to with a basic_json value
21108 // see https://github.com/nlohmann/json/issues/2175
21109 template<typename ValueType,
21112 int> = 0>
21113 ValueType& get_to(ValueType& v) const
21114 {
21115 v = *this;
21116 return v;
21117 }
21118
21119 template <
21120 typename T, std::size_t N,
21121 typename Array = T(&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21124 Array get_to(T(&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21125 noexcept(noexcept(JSONSerializer<Array>::from_json(
21126 std::declval<const basic_json_t&>(), v)))
21127 {
21128 JSONSerializer<Array>::from_json(*this, v);
21129 return v;
21130 }
21131
21134 template<typename ReferenceType, typename std::enable_if<
21135 std::is_reference<ReferenceType>::value, int>::type = 0>
21136 ReferenceType get_ref()
21137 {
21138 // delegate call to get_ref_impl
21139 return get_ref_impl<ReferenceType>(*this);
21140 }
21141
21144 template < typename ReferenceType, typename std::enable_if <
21145 std::is_reference<ReferenceType>::value&&
21146 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
21147 ReferenceType get_ref() const
21148 {
21149 // delegate call to get_ref_impl
21150 return get_ref_impl<ReferenceType>(*this);
21151 }
21152
21182 template < typename ValueType, typename std::enable_if <
21190#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21192#endif
21193#if defined(JSON_HAS_CPP_17) && JSON_HAS_STATIC_RTTI
21195#endif
21197 >::value, int >::type = 0 >
21198 JSON_EXPLICIT operator ValueType() const
21199 {
21200 // delegate the call to get<>() const
21201 return get<ValueType>();
21202 }
21203
21207 {
21208 if (!is_binary())
21209 {
21210 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21211 }
21212
21213 return *get_ptr<binary_t*>();
21214 }
21215
21218 const binary_t& get_binary() const
21219 {
21220 if (!is_binary())
21221 {
21222 JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
21223 }
21224
21225 return *get_ptr<const binary_t*>();
21226 }
21227
21229
21231 // element access //
21233
21237
21241 {
21242 // at only works for arrays
21244 {
21245 JSON_TRY
21246 {
21247 return set_parent(m_data.m_value.array->at(idx));
21248 }
21249 JSON_CATCH(std::out_of_range&)
21250 {
21251 // create better exception explanation
21252 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21253 }
21254 }
21255 else
21256 {
21257 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21258 }
21259 }
21260
21264 {
21265 // at only works for arrays
21267 {
21268 JSON_TRY
21269 {
21270 return m_data.m_value.array->at(idx);
21271 }
21272 JSON_CATCH(std::out_of_range&)
21273 {
21274 // create better exception explanation
21275 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21276 }
21277 }
21278 else
21279 {
21280 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21281 }
21282 }
21283
21286 reference at(const typename object_t::key_type& key)
21287 {
21288 // at only works for objects
21290 {
21291 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21292 }
21293
21294 auto it = m_data.m_value.object->find(key);
21295 if (it == m_data.m_value.object->end())
21296 {
21297 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21298 }
21299 return set_parent(it->second);
21300 }
21301
21304 template<class KeyType, detail::enable_if_t<
21306 reference at(KeyType&& key)
21307 {
21308 // at only works for objects
21310 {
21311 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21312 }
21313
21314 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21315 if (it == m_data.m_value.object->end())
21316 {
21317 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21318 }
21319 return set_parent(it->second);
21320 }
21321
21324 const_reference at(const typename object_t::key_type& key) const
21325 {
21326 // at only works for objects
21328 {
21329 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21330 }
21331
21332 auto it = m_data.m_value.object->find(key);
21333 if (it == m_data.m_value.object->end())
21334 {
21335 JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
21336 }
21337 return it->second;
21338 }
21339
21342 template<class KeyType, detail::enable_if_t<
21344 const_reference at(KeyType&& key) const
21345 {
21346 // at only works for objects
21348 {
21349 JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
21350 }
21351
21352 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21353 if (it == m_data.m_value.object->end())
21354 {
21355 JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
21356 }
21357 return it->second;
21358 }
21359
21363 {
21364 // implicitly convert null value to an empty array
21365 if (is_null())
21366 {
21367 m_data.m_type = value_t::array;
21368 m_data.m_value.array = create<array_t>();
21370 }
21371
21372 // operator[] only works for arrays
21374 {
21375 // fill up array with null values if given idx is outside range
21376 if (idx >= m_data.m_value.array->size())
21377 {
21378#if JSON_DIAGNOSTICS
21379 // remember array size & capacity before resizing
21380 const auto old_size = m_data.m_value.array->size();
21381 const auto old_capacity = m_data.m_value.array->capacity();
21382#endif
21383 m_data.m_value.array->resize(idx + 1);
21384
21385#if JSON_DIAGNOSTICS
21386 if (JSON_HEDLEY_UNLIKELY(m_data.m_value.array->capacity() != old_capacity))
21387 {
21388 // capacity has changed: update all parents
21389 set_parents();
21390 }
21391 else
21392 {
21393 // set parent for values added above
21394 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21395 }
21396#endif
21398 }
21399
21400 return m_data.m_value.array->operator[](idx);
21401 }
21402
21403 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21404 }
21405
21409 {
21410 // const operator[] only works for arrays
21412 {
21413 return m_data.m_value.array->operator[](idx);
21414 }
21415
21416 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
21417 }
21418
21421 reference operator[](typename object_t::key_type key)
21422 {
21423 // implicitly convert null value to an empty object
21424 if (is_null())
21425 {
21426 m_data.m_type = value_t::object;
21427 m_data.m_value.object = create<object_t>();
21429 }
21430
21431 // operator[] only works for objects
21433 {
21434 auto result = m_data.m_value.object->emplace(std::move(key), nullptr);
21435 return set_parent(result.first->second);
21436 }
21437
21438 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21439 }
21440
21443 const_reference operator[](const typename object_t::key_type& key) const
21444 {
21445 // const operator[] only works for objects
21447 {
21448 auto it = m_data.m_value.object->find(key);
21449 JSON_ASSERT(it != m_data.m_value.object->end());
21450 return it->second;
21451 }
21452
21453 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21454 }
21455
21456 // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
21457 // (they seemingly cannot be constrained to resolve the ambiguity)
21458 template<typename T>
21460 {
21461 return operator[](typename object_t::key_type(key));
21462 }
21463
21464 template<typename T>
21466 {
21467 return operator[](typename object_t::key_type(key));
21468 }
21469
21472 template<class KeyType, detail::enable_if_t<
21475 {
21476 // implicitly convert null value to an empty object
21477 if (is_null())
21478 {
21479 m_data.m_type = value_t::object;
21480 m_data.m_value.object = create<object_t>();
21482 }
21483
21484 // operator[] only works for objects
21486 {
21487 auto result = m_data.m_value.object->emplace(std::forward<KeyType>(key), nullptr);
21488 return set_parent(result.first->second);
21489 }
21490
21491 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21492 }
21493
21496 template<class KeyType, detail::enable_if_t<
21499 {
21500 // const operator[] only works for objects
21502 {
21503 auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21504 JSON_ASSERT(it != m_data.m_value.object->end());
21505 return it->second;
21506 }
21507
21508 JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
21509 }
21510
21511private:
21512 template<typename KeyType>
21514 object_comparator_t, const typename object_t::key_type&, KeyType >;
21515
21516 template<typename ValueType>
21517 using value_return_type = std::conditional <
21519 string_t, typename std::decay<ValueType>::type >;
21520
21521public:
21524 template < class ValueType, detail::enable_if_t <
21527 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21528 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21529 {
21530 // value only works for objects
21532 {
21533 // if key is found, return value and given default value otherwise
21534 const auto it = find(key);
21535 if (it != end())
21536 {
21537 return it->template get<ValueType>();
21538 }
21539
21540 return default_value;
21541 }
21542
21543 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21544 }
21545
21548 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21552 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21553 ReturnType value(const typename object_t::key_type& key, ValueType&& default_value) const
21554 {
21555 // value only works for objects
21557 {
21558 // if key is found, return value and given default value otherwise
21559 const auto it = find(key);
21560 if (it != end())
21561 {
21562 return it->template get<ReturnType>();
21563 }
21564
21565 return std::forward<ValueType>(default_value);
21566 }
21567
21568 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21569 }
21570
21573 template < class ValueType, class KeyType, detail::enable_if_t <
21576 && is_comparable_with_object_key<KeyType>::value
21578 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21579 ValueType value(KeyType&& key, const ValueType& default_value) const
21580 {
21581 // value only works for objects
21583 {
21584 // if key is found, return value and given default value otherwise
21585 const auto it = find(std::forward<KeyType>(key));
21586 if (it != end())
21587 {
21588 return it->template get<ValueType>();
21589 }
21590
21591 return default_value;
21592 }
21593
21594 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21595 }
21596
21599 template < class ValueType, class KeyType, class ReturnType = typename value_return_type<ValueType>::type,
21603 && is_comparable_with_object_key<KeyType>::value
21605 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21606 ReturnType value(KeyType&& key, ValueType&& default_value) const
21607 {
21608 // value only works for objects
21610 {
21611 // if key is found, return value and given default value otherwise
21612 const auto it = find(std::forward<KeyType>(key));
21613 if (it != end())
21614 {
21615 return it->template get<ReturnType>();
21616 }
21617
21618 return std::forward<ValueType>(default_value);
21619 }
21620
21621 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21622 }
21623
21626 template < class ValueType, detail::enable_if_t <
21628 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21629 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21630 {
21631 // value only works for objects
21633 {
21634 // if pointer resolves a value, return it or use default value
21635 JSON_TRY
21636 {
21637 return ptr.get_checked(this).template get<ValueType>();
21638 }
21640 {
21641 return default_value;
21642 }
21643 }
21644
21645 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21646 }
21647
21650 template < class ValueType, class ReturnType = typename value_return_type<ValueType>::type,
21653 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21654 ReturnType value(const json_pointer& ptr, ValueType&& default_value) const
21655 {
21656 // value only works for objects
21658 {
21659 // if pointer resolves a value, return it or use default value
21660 JSON_TRY
21661 {
21662 return ptr.get_checked(this).template get<ReturnType>();
21663 }
21665 {
21666 return std::forward<ValueType>(default_value);
21667 }
21668 }
21669
21670 JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
21671 }
21672
21673 template < class ValueType, class BasicJsonType, detail::enable_if_t <
21676 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21677 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21678 ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
21679 {
21680 return value(ptr.convert(), default_value);
21681 }
21682
21683 template < class ValueType, class BasicJsonType, class ReturnType = typename value_return_type<ValueType>::type,
21687 && !std::is_same<value_t, detail::uncvref_t<ValueType>>::value, int > = 0 >
21688 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
21689 ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, ValueType&& default_value) const
21690 {
21691 return value(ptr.convert(), std::forward<ValueType>(default_value));
21692 }
21693
21697 {
21698 return *begin();
21699 }
21700
21704 {
21705 return *cbegin();
21706 }
21707
21711 {
21712 auto tmp = end();
21713 --tmp;
21714 return *tmp;
21715 }
21716
21720 {
21721 auto tmp = cend();
21722 --tmp;
21723 return *tmp;
21724 }
21725
21728 template < class IteratorType, detail::enable_if_t <
21729 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21730 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21731 IteratorType erase(IteratorType pos)
21732 {
21733 // make sure iterator fits the current value
21734 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21735 {
21736 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21737 }
21738
21739 IteratorType result = end();
21740
21741 switch (m_data.m_type)
21742 {
21743 case value_t::boolean:
21744 case value_t::number_float:
21745 case value_t::number_integer:
21746 case value_t::number_unsigned:
21747 case value_t::string:
21748 case value_t::binary:
21749 {
21750 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21751 {
21752 JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
21753 }
21754
21755 if (is_string())
21756 {
21757 AllocatorType<string_t> alloc;
21758 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21759 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21760 m_data.m_value.string = nullptr;
21761 }
21762 else if (is_binary())
21763 {
21764 AllocatorType<binary_t> alloc;
21765 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21766 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21767 m_data.m_value.binary = nullptr;
21768 }
21769
21770 m_data.m_type = value_t::null;
21772 break;
21773 }
21774
21775 case value_t::object:
21776 {
21777 result.m_it.object_iterator = m_data.m_value.object->erase(pos.m_it.object_iterator);
21778 break;
21779 }
21780
21781 case value_t::array:
21782 {
21783 result.m_it.array_iterator = m_data.m_value.array->erase(pos.m_it.array_iterator);
21784 break;
21785 }
21786
21787 case value_t::null:
21788 case value_t::discarded:
21789 default:
21790 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21791 }
21792
21793 return result;
21794 }
21795
21798 template < class IteratorType, detail::enable_if_t <
21799 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21800 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
21801 IteratorType erase(IteratorType first, IteratorType last)
21802 {
21803 // make sure iterator fits the current value
21804 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21805 {
21806 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
21807 }
21808
21809 IteratorType result = end();
21810
21811 switch (m_data.m_type)
21812 {
21813 case value_t::boolean:
21814 case value_t::number_float:
21815 case value_t::number_integer:
21816 case value_t::number_unsigned:
21817 case value_t::string:
21818 case value_t::binary:
21819 {
21820 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21821 || !last.m_it.primitive_iterator.is_end()))
21822 {
21823 JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21824 }
21825
21826 if (is_string())
21827 {
21828 AllocatorType<string_t> alloc;
21829 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.string);
21830 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.string, 1);
21831 m_data.m_value.string = nullptr;
21832 }
21833 else if (is_binary())
21834 {
21835 AllocatorType<binary_t> alloc;
21836 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_data.m_value.binary);
21837 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_data.m_value.binary, 1);
21838 m_data.m_value.binary = nullptr;
21839 }
21840
21841 m_data.m_type = value_t::null;
21843 break;
21844 }
21845
21846 case value_t::object:
21847 {
21848 result.m_it.object_iterator = m_data.m_value.object->erase(first.m_it.object_iterator,
21849 last.m_it.object_iterator);
21850 break;
21851 }
21852
21853 case value_t::array:
21854 {
21855 result.m_it.array_iterator = m_data.m_value.array->erase(first.m_it.array_iterator,
21856 last.m_it.array_iterator);
21857 break;
21858 }
21859
21860 case value_t::null:
21861 case value_t::discarded:
21862 default:
21863 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21864 }
21865
21866 return result;
21867 }
21868
21869private:
21870 template < typename KeyType, detail::enable_if_t <
21873 {
21874 // this erase only works for objects
21876 {
21877 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21878 }
21879
21880 return m_data.m_value.object->erase(std::forward<KeyType>(key));
21881 }
21882
21883 template < typename KeyType, detail::enable_if_t <
21886 {
21887 // this erase only works for objects
21889 {
21890 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21891 }
21892
21893 const auto it = m_data.m_value.object->find(std::forward<KeyType>(key));
21894 if (it != m_data.m_value.object->end())
21895 {
21896 m_data.m_value.object->erase(it);
21897 return 1;
21898 }
21899 return 0;
21900 }
21901
21902public:
21903
21906 size_type erase(const typename object_t::key_type& key)
21907 {
21908 // the indirection via erase_internal() is added to avoid making this
21909 // function a template and thus de-rank it during overload resolution
21910 return erase_internal(key);
21911 }
21912
21915 template<class KeyType, detail::enable_if_t<
21918 {
21919 return erase_internal(std::forward<KeyType>(key));
21920 }
21921
21924 void erase(const size_type idx)
21925 {
21926 // this erase only works for arrays
21928 {
21929 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21930 {
21931 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21932 }
21933
21934 m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
21935 }
21936 else
21937 {
21938 JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21939 }
21940 }
21941
21943
21945 // lookup //
21947
21950
21953 iterator find(const typename object_t::key_type& key)
21954 {
21955 auto result = end();
21956
21957 if (is_object())
21958 {
21959 result.m_it.object_iterator = m_data.m_value.object->find(key);
21960 }
21961
21962 return result;
21963 }
21964
21967 const_iterator find(const typename object_t::key_type& key) const
21968 {
21969 auto result = cend();
21970
21971 if (is_object())
21972 {
21973 result.m_it.object_iterator = m_data.m_value.object->find(key);
21974 }
21975
21976 return result;
21977 }
21978
21981 template<class KeyType, detail::enable_if_t<
21983 iterator find(KeyType&& key)
21984 {
21985 auto result = end();
21986
21987 if (is_object())
21988 {
21989 result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
21990 }
21991
21992 return result;
21993 }
21994
21997 template<class KeyType, detail::enable_if_t<
21999 const_iterator find(KeyType&& key) const
22000 {
22001 auto result = cend();
22002
22003 if (is_object())
22004 {
22005 result.m_it.object_iterator = m_data.m_value.object->find(std::forward<KeyType>(key));
22006 }
22007
22008 return result;
22009 }
22010
22013 size_type count(const typename object_t::key_type& key) const
22014 {
22015 // return 0 for all nonobject types
22016 return is_object() ? m_data.m_value.object->count(key) : 0;
22017 }
22018
22021 template<class KeyType, detail::enable_if_t<
22023 size_type count(KeyType&& key) const
22024 {
22025 // return 0 for all nonobject types
22026 return is_object() ? m_data.m_value.object->count(std::forward<KeyType>(key)) : 0;
22027 }
22028
22031 bool contains(const typename object_t::key_type& key) const
22032 {
22033 return is_object() && m_data.m_value.object->find(key) != m_data.m_value.object->end();
22034 }
22035
22038 template<class KeyType, detail::enable_if_t<
22040 bool contains(KeyType&& key) const
22041 {
22042 return is_object() && m_data.m_value.object->find(std::forward<KeyType>(key)) != m_data.m_value.object->end();
22043 }
22044
22047 bool contains(const json_pointer& ptr) const
22048 {
22049 return ptr.contains(this);
22050 }
22051
22052 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
22053 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
22054 bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr) const
22055 {
22056 return ptr.contains(this);
22057 }
22058
22060
22062 // iterators //
22064
22067
22070 iterator begin() noexcept
22071 {
22072 iterator result(this);
22073 result.set_begin();
22074 return result;
22075 }
22076
22079 const_iterator begin() const noexcept
22080 {
22081 return cbegin();
22082 }
22083
22086 const_iterator cbegin() const noexcept
22087 {
22088 const_iterator result(this);
22089 result.set_begin();
22090 return result;
22091 }
22092
22095 iterator end() noexcept
22096 {
22097 iterator result(this);
22098 result.set_end();
22099 return result;
22100 }
22101
22104 const_iterator end() const noexcept
22105 {
22106 return cend();
22107 }
22108
22111 const_iterator cend() const noexcept
22112 {
22113 const_iterator result(this);
22114 result.set_end();
22115 return result;
22116 }
22117
22121 {
22122 return reverse_iterator(end());
22123 }
22124
22128 {
22129 return crbegin();
22130 }
22131
22135 {
22136 return reverse_iterator(begin());
22137 }
22138
22142 {
22143 return crend();
22144 }
22145
22149 {
22150 return const_reverse_iterator(cend());
22151 }
22152
22156 {
22158 }
22159
22160public:
22166 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22168 {
22169 return ref.items();
22170 }
22171
22177 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22179 {
22180 return ref.items();
22181 }
22182
22186 {
22187 return iteration_proxy<iterator>(*this);
22188 }
22189
22193 {
22194 return iteration_proxy<const_iterator>(*this);
22195 }
22196
22198
22200 // capacity //
22202
22205
22208 bool empty() const noexcept
22209 {
22210 switch (m_data.m_type)
22211 {
22212 case value_t::null:
22213 {
22214 // null values are empty
22215 return true;
22216 }
22217
22218 case value_t::array:
22219 {
22220 // delegate call to array_t::empty()
22221 return m_data.m_value.array->empty();
22222 }
22223
22224 case value_t::object:
22225 {
22226 // delegate call to object_t::empty()
22227 return m_data.m_value.object->empty();
22228 }
22229
22230 case value_t::string:
22231 case value_t::boolean:
22232 case value_t::number_integer:
22233 case value_t::number_unsigned:
22234 case value_t::number_float:
22235 case value_t::binary:
22236 case value_t::discarded:
22237 default:
22238 {
22239 // all other types are nonempty
22240 return false;
22241 }
22242 }
22243 }
22244
22247 size_type size() const noexcept
22248 {
22249 switch (m_data.m_type)
22250 {
22251 case value_t::null:
22252 {
22253 // null values are empty
22254 return 0;
22255 }
22256
22257 case value_t::array:
22258 {
22259 // delegate call to array_t::size()
22260 return m_data.m_value.array->size();
22261 }
22262
22263 case value_t::object:
22264 {
22265 // delegate call to object_t::size()
22266 return m_data.m_value.object->size();
22267 }
22268
22269 case value_t::string:
22270 case value_t::boolean:
22271 case value_t::number_integer:
22272 case value_t::number_unsigned:
22273 case value_t::number_float:
22274 case value_t::binary:
22275 case value_t::discarded:
22276 default:
22277 {
22278 // all other types have size 1
22279 return 1;
22280 }
22281 }
22282 }
22283
22286 size_type max_size() const noexcept
22287 {
22288 switch (m_data.m_type)
22289 {
22290 case value_t::array:
22291 {
22292 // delegate call to array_t::max_size()
22293 return m_data.m_value.array->max_size();
22294 }
22295
22296 case value_t::object:
22297 {
22298 // delegate call to object_t::max_size()
22299 return m_data.m_value.object->max_size();
22300 }
22301
22302 case value_t::null:
22303 case value_t::string:
22304 case value_t::boolean:
22305 case value_t::number_integer:
22306 case value_t::number_unsigned:
22307 case value_t::number_float:
22308 case value_t::binary:
22309 case value_t::discarded:
22310 default:
22311 {
22312 // all other types have max_size() == size()
22313 return size();
22314 }
22315 }
22316 }
22317
22319
22321 // modifiers //
22323
22326
22329 void clear() noexcept
22330 {
22331 switch (m_data.m_type)
22332 {
22333 case value_t::number_integer:
22334 {
22335 m_data.m_value.number_integer = 0;
22336 break;
22337 }
22338
22339 case value_t::number_unsigned:
22340 {
22341 m_data.m_value.number_unsigned = 0;
22342 break;
22343 }
22344
22345 case value_t::number_float:
22346 {
22347 m_data.m_value.number_float = 0.0;
22348 break;
22349 }
22350
22351 case value_t::boolean:
22352 {
22353 m_data.m_value.boolean = false;
22354 break;
22355 }
22356
22357 case value_t::string:
22358 {
22359 m_data.m_value.string->clear();
22360 break;
22361 }
22362
22363 case value_t::binary:
22364 {
22365 m_data.m_value.binary->clear();
22366 break;
22367 }
22368
22369 case value_t::array:
22370 {
22371 m_data.m_value.array->clear();
22372 break;
22373 }
22374
22375 case value_t::object:
22376 {
22377 m_data.m_value.object->clear();
22378 break;
22379 }
22380
22381 case value_t::null:
22382 case value_t::discarded:
22383 default:
22384 break;
22385 }
22386 }
22387
22391 {
22392 // push_back only works for null objects or arrays
22393 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22394 {
22395 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22396 }
22397
22398 // transform null object into an array
22399 if (is_null())
22400 {
22401 m_data.m_type = value_t::array;
22402 m_data.m_value = value_t::array;
22404 }
22405
22406 // add element to array (move semantics)
22407 const auto old_capacity = m_data.m_value.array->capacity();
22408 m_data.m_value.array->push_back(std::move(val));
22409 set_parent(m_data.m_value.array->back(), old_capacity);
22410 // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
22411 }
22412
22416 {
22417 push_back(std::move(val));
22418 return *this;
22419 }
22420
22423 void push_back(const basic_json& val)
22424 {
22425 // push_back only works for null objects or arrays
22426 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22427 {
22428 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22429 }
22430
22431 // transform null object into an array
22432 if (is_null())
22433 {
22434 m_data.m_type = value_t::array;
22435 m_data.m_value = value_t::array;
22437 }
22438
22439 // add element to array
22440 const auto old_capacity = m_data.m_value.array->capacity();
22441 m_data.m_value.array->push_back(val);
22442 set_parent(m_data.m_value.array->back(), old_capacity);
22443 }
22444
22448 {
22449 push_back(val);
22450 return *this;
22451 }
22452
22455 void push_back(const typename object_t::value_type& val)
22456 {
22457 // push_back only works for null objects or objects
22458 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22459 {
22460 JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
22461 }
22462
22463 // transform null object into an object
22464 if (is_null())
22465 {
22466 m_data.m_type = value_t::object;
22467 m_data.m_value = value_t::object;
22469 }
22470
22471 // add element to object
22472 auto res = m_data.m_value.object->insert(val);
22473 set_parent(res.first->second);
22474 }
22475
22478 reference operator+=(const typename object_t::value_type& val)
22479 {
22480 push_back(val);
22481 return *this;
22482 }
22483
22487 {
22488 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22489 {
22490 basic_json&& key = init.begin()->moved_or_copied();
22491 push_back(typename object_t::value_type(
22492 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22493 }
22494 else
22495 {
22496 push_back(basic_json(init));
22497 }
22498 }
22499
22503 {
22504 push_back(init);
22505 return *this;
22506 }
22507
22510 template<class... Args>
22511 reference emplace_back(Args&& ... args)
22512 {
22513 // emplace_back only works for null objects or arrays
22514 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22515 {
22516 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
22517 }
22518
22519 // transform null object into an array
22520 if (is_null())
22521 {
22522 m_data.m_type = value_t::array;
22523 m_data.m_value = value_t::array;
22525 }
22526
22527 // add element to array (perfect forwarding)
22528 const auto old_capacity = m_data.m_value.array->capacity();
22529 m_data.m_value.array->emplace_back(std::forward<Args>(args)...);
22530 return set_parent(m_data.m_value.array->back(), old_capacity);
22531 }
22532
22535 template<class... Args>
22536 std::pair<iterator, bool> emplace(Args&& ... args)
22537 {
22538 // emplace only works for null objects or arrays
22539 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22540 {
22541 JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
22542 }
22543
22544 // transform null object into an object
22545 if (is_null())
22546 {
22547 m_data.m_type = value_t::object;
22548 m_data.m_value = value_t::object;
22550 }
22551
22552 // add element to array (perfect forwarding)
22553 auto res = m_data.m_value.object->emplace(std::forward<Args>(args)...);
22554 set_parent(res.first->second);
22555
22556 // create result iterator and set iterator to the result of emplace
22557 auto it = begin();
22558 it.m_it.object_iterator = res.first;
22559
22560 // return pair of iterator and boolean
22561 return { it, res.second };
22562 }
22563
22567 template<typename... Args>
22569 {
22570 iterator result(this);
22571 JSON_ASSERT(m_data.m_value.array != nullptr);
22572
22573 auto insert_pos = std::distance(m_data.m_value.array->begin(), pos.m_it.array_iterator);
22574 m_data.m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22575 result.m_it.array_iterator = m_data.m_value.array->begin() + insert_pos;
22576
22577 // This could have been written as:
22578 // result.m_it.array_iterator = m_data.m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22579 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22580
22581 set_parents();
22582 return result;
22583 }
22584
22588 {
22589 // insert only works for arrays
22591 {
22592 // check if iterator pos fits to this JSON value
22593 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22594 {
22595 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22596 }
22597
22598 // insert to array and return iterator
22599 return insert_iterator(pos, val);
22600 }
22601
22602 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22603 }
22604
22608 {
22609 return insert(pos, val);
22610 }
22611
22615 {
22616 // insert only works for arrays
22618 {
22619 // check if iterator pos fits to this JSON value
22620 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22621 {
22622 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22623 }
22624
22625 // insert to array and return iterator
22626 return insert_iterator(pos, cnt, val);
22627 }
22628
22629 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22630 }
22631
22635 {
22636 // insert only works for arrays
22638 {
22639 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22640 }
22641
22642 // check if iterator pos fits to this JSON value
22643 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22644 {
22645 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22646 }
22647
22648 // check if range iterators belong to the same JSON object
22649 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22650 {
22651 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22652 }
22653
22654 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22655 {
22656 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
22657 }
22658
22659 // insert to array and return iterator
22660 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22661 }
22662
22666 {
22667 // insert only works for arrays
22669 {
22670 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22671 }
22672
22673 // check if iterator pos fits to this JSON value
22674 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22675 {
22676 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
22677 }
22678
22679 // insert to array and return iterator
22680 return insert_iterator(pos, ilist.begin(), ilist.end());
22681 }
22682
22686 {
22687 // insert only works for objects
22689 {
22690 JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
22691 }
22692
22693 // check if range iterators belong to the same JSON object
22694 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22695 {
22696 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22697 }
22698
22699 // passed iterators must belong to objects
22700 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22701 {
22702 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
22703 }
22704
22705 m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22706 }
22707
22710 void update(const_reference j, bool merge_objects = false)
22711 {
22712 update(j.begin(), j.end(), merge_objects);
22713 }
22714
22717 void update(const_iterator first, const_iterator last, bool merge_objects = false)
22718 {
22719 // implicitly convert null value to an empty object
22720 if (is_null())
22721 {
22722 m_data.m_type = value_t::object;
22723 m_data.m_value.object = create<object_t>();
22725 }
22726
22728 {
22729 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
22730 }
22731
22732 // check if range iterators belong to the same JSON object
22733 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22734 {
22735 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
22736 }
22737
22738 // passed iterators must belong to objects
22739 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22740 {
22741 JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
22742 }
22743
22744 for (auto it = first; it != last; ++it)
22745 {
22746 if (merge_objects && it.value().is_object())
22747 {
22748 auto it2 = m_data.m_value.object->find(it.key());
22749 if (it2 != m_data.m_value.object->end())
22750 {
22751 it2->second.update(it.value(), true);
22752 continue;
22753 }
22754 }
22755 m_data.m_value.object->operator[](it.key()) = it.value();
22756#if JSON_DIAGNOSTICS
22757 m_data.m_value.object->operator[](it.key()).m_parent = this;
22758#endif
22759 }
22760 }
22761
22764 void swap(reference other) noexcept (
22765 std::is_nothrow_move_constructible<value_t>::value&&
22766 std::is_nothrow_move_assignable<value_t>::value&&
22767 std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22768 std::is_nothrow_move_assignable<json_value>::value
22769 )
22770 {
22771 std::swap(m_data.m_type, other.m_data.m_type);
22772 std::swap(m_data.m_value, other.m_data.m_value);
22773
22774 set_parents();
22775 other.set_parents();
22777 }
22778
22781 friend void swap(reference left, reference right) noexcept (
22782 std::is_nothrow_move_constructible<value_t>::value&&
22783 std::is_nothrow_move_assignable<value_t>::value&&
22784 std::is_nothrow_move_constructible<json_value>::value&& // NOLINT(cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22785 std::is_nothrow_move_assignable<json_value>::value
22786 )
22787 {
22788 left.swap(right);
22789 }
22790
22793 void swap(array_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22794 {
22795 // swap only works for arrays
22797 {
22798 using std::swap;
22799 swap(*(m_data.m_value.array), other);
22800 }
22801 else
22802 {
22803 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(array_t&) with ", type_name()), this));
22804 }
22805 }
22806
22809 void swap(object_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22810 {
22811 // swap only works for objects
22813 {
22814 using std::swap;
22815 swap(*(m_data.m_value.object), other);
22816 }
22817 else
22818 {
22819 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(object_t&) with ", type_name()), this));
22820 }
22821 }
22822
22825 void swap(string_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22826 {
22827 // swap only works for strings
22829 {
22830 using std::swap;
22831 swap(*(m_data.m_value.string), other);
22832 }
22833 else
22834 {
22835 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(string_t&) with ", type_name()), this));
22836 }
22837 }
22838
22841 void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
22842 {
22843 // swap only works for strings
22845 {
22846 using std::swap;
22847 swap(*(m_data.m_value.binary), other);
22848 }
22849 else
22850 {
22851 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t&) with ", type_name()), this));
22852 }
22853 }
22854
22857 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22858 {
22859 // swap only works for strings
22861 {
22862 using std::swap;
22863 swap(*(m_data.m_value.binary), other);
22864 }
22865 else
22866 {
22867 JSON_THROW(type_error::create(310, detail::concat("cannot use swap(binary_t::container_type&) with ", type_name()), this));
22868 }
22869 }
22870
22872
22874 // lexicographical comparison operators //
22876
22879
22880 // note parentheses around operands are necessary; see
22881 // https://github.com/nlohmann/json/issues/1530
22882#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22883 const auto lhs_type = lhs.type(); \
22884 const auto rhs_type = rhs.type(); \
22885 \
22886 if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22887 { \
22888 switch (lhs_type) \
22889 { \
22890 case value_t::array: \
22891 return (*lhs.m_data.m_value.array) op (*rhs.m_data.m_value.array); \
22892 \
22893 case value_t::object: \
22894 return (*lhs.m_data.m_value.object) op (*rhs.m_data.m_value.object); \
22895 \
22896 case value_t::null: \
22897 return (null_result); \
22898 \
22899 case value_t::string: \
22900 return (*lhs.m_data.m_value.string) op (*rhs.m_data.m_value.string); \
22901 \
22902 case value_t::boolean: \
22903 return (lhs.m_data.m_value.boolean) op (rhs.m_data.m_value.boolean); \
22904 \
22905 case value_t::number_integer: \
22906 return (lhs.m_data.m_value.number_integer) op (rhs.m_data.m_value.number_integer); \
22907 \
22908 case value_t::number_unsigned: \
22909 return (lhs.m_data.m_value.number_unsigned) op (rhs.m_data.m_value.number_unsigned); \
22910 \
22911 case value_t::number_float: \
22912 return (lhs.m_data.m_value.number_float) op (rhs.m_data.m_value.number_float); \
22913 \
22914 case value_t::binary: \
22915 return (*lhs.m_data.m_value.binary) op (*rhs.m_data.m_value.binary); \
22916 \
22917 case value_t::discarded: \
22918 default: \
22919 return (unordered_result); \
22920 } \
22921 } \
22922 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22923 { \
22924 return static_cast<number_float_t>(lhs.m_data.m_value.number_integer) op rhs.m_data.m_value.number_float; \
22925 } \
22926 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22927 { \
22928 return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_integer); \
22929 } \
22930 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22931 { \
22932 return static_cast<number_float_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_float; \
22933 } \
22934 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22935 { \
22936 return lhs.m_data.m_value.number_float op static_cast<number_float_t>(rhs.m_data.m_value.number_unsigned); \
22937 } \
22938 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22939 { \
22940 return static_cast<number_integer_t>(lhs.m_data.m_value.number_unsigned) op rhs.m_data.m_value.number_integer; \
22941 } \
22942 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22943 { \
22944 return lhs.m_data.m_value.number_integer op static_cast<number_integer_t>(rhs.m_data.m_value.number_unsigned); \
22945 } \
22946 else if(compares_unordered(lhs, rhs))\
22947 {\
22948 return (unordered_result);\
22949 }\
22950 \
22951 return (default_result);
22952
22954 // returns true if:
22955 // - any operand is NaN and the other operand is of number type
22956 // - any operand is discarded
22957 // in legacy mode, discarded values are considered ordered if
22958 // an operation is computed as an odd number of inverses of others
22959 static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22960 {
22961 if ((lhs.is_number_float() && std::isnan(lhs.m_data.m_value.number_float) && rhs.is_number())
22962 || (rhs.is_number_float() && std::isnan(rhs.m_data.m_value.number_float) && lhs.is_number()))
22963 {
22964 return true;
22965 }
22966#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22967 return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22968#else
22969 static_cast<void>(inverse);
22970 return lhs.is_discarded() || rhs.is_discarded();
22971#endif
22972 }
22973
22974private:
22975 bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22976 {
22977 return compares_unordered(*this, rhs, inverse);
22978 }
22979
22980public:
22981#if JSON_HAS_THREE_WAY_COMPARISON
22984 bool operator==(const_reference rhs) const noexcept
22985 {
22986#ifdef __GNUC__
22987#pragma GCC diagnostic push
22988#pragma GCC diagnostic ignored "-Wfloat-equal"
22989#endif
22990 const_reference lhs = *this;
22991 JSON_IMPLEMENT_OPERATOR(== , true, false, false)
22992#ifdef __GNUC__
22993#pragma GCC diagnostic pop
22994#endif
22995 }
22996
22999 template<typename ScalarType>
23000 requires std::is_scalar_v<ScalarType>
23001 bool operator==(ScalarType rhs) const noexcept
23002 {
23003 return *this == basic_json(rhs);
23004 }
23005
23008 bool operator!=(const_reference rhs) const noexcept
23009 {
23010 if (compares_unordered(rhs, true))
23011 {
23012 return false;
23013 }
23014 return !operator==(rhs);
23015 }
23016
23019 std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
23020 {
23021 const_reference lhs = *this;
23022 // default_result is used if we cannot compare values. In that case,
23023 // we compare types.
23024 JSON_IMPLEMENT_OPERATOR(<=> , // *NOPAD*
23025 std::partial_ordering::equivalent,
23026 std::partial_ordering::unordered,
23027 lhs_type <=> rhs_type) // *NOPAD*
23028 }
23029
23032 template<typename ScalarType>
23033 requires std::is_scalar_v<ScalarType>
23034 std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
23035 {
23036 return *this <=> basic_json(rhs); // *NOPAD*
23037 }
23038
23039#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23040 // all operators that are computed as an odd number of inverses of others
23041 // need to be overloaded to emulate the legacy comparison behavior
23042
23046 bool operator<=(const_reference rhs) const noexcept
23047 {
23048 if (compares_unordered(rhs, true))
23049 {
23050 return false;
23051 }
23052 return !(rhs < *this);
23053 }
23054
23057 template<typename ScalarType>
23058 requires std::is_scalar_v<ScalarType>
23059 bool operator<=(ScalarType rhs) const noexcept
23060 {
23061 return *this <= basic_json(rhs);
23062 }
23063
23067 bool operator>=(const_reference rhs) const noexcept
23068 {
23069 if (compares_unordered(rhs, true))
23070 {
23071 return false;
23072 }
23073 return !(*this < rhs);
23074 }
23075
23078 template<typename ScalarType>
23079 requires std::is_scalar_v<ScalarType>
23080 bool operator>=(ScalarType rhs) const noexcept
23081 {
23082 return *this >= basic_json(rhs);
23083 }
23084#endif
23085#else
23088 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23089 {
23090#ifdef __GNUC__
23091#pragma GCC diagnostic push
23092#pragma GCC diagnostic ignored "-Wfloat-equal"
23093#endif
23094 JSON_IMPLEMENT_OPERATOR(== , true, false, false)
23095#ifdef __GNUC__
23096#pragma GCC diagnostic pop
23097#endif
23098 }
23099
23102 template<typename ScalarType, typename std::enable_if<
23103 std::is_scalar<ScalarType>::value, int>::type = 0>
23104 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23105 {
23106 return lhs == basic_json(rhs);
23107 }
23108
23111 template<typename ScalarType, typename std::enable_if<
23112 std::is_scalar<ScalarType>::value, int>::type = 0>
23113 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23114 {
23115 return basic_json(lhs) == rhs;
23116 }
23117
23120 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23121 {
23122 if (compares_unordered(lhs, rhs, true))
23123 {
23124 return false;
23125 }
23126 return !(lhs == rhs);
23127 }
23128
23131 template<typename ScalarType, typename std::enable_if<
23132 std::is_scalar<ScalarType>::value, int>::type = 0>
23133 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23134 {
23135 return lhs != basic_json(rhs);
23136 }
23137
23140 template<typename ScalarType, typename std::enable_if<
23141 std::is_scalar<ScalarType>::value, int>::type = 0>
23142 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23143 {
23144 return basic_json(lhs) != rhs;
23145 }
23146
23149 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23150 {
23151 // default_result is used if we cannot compare values. In that case,
23152 // we compare types. Note we have to call the operator explicitly,
23153 // because MSVC has problems otherwise.
23154 JSON_IMPLEMENT_OPERATOR(< , false, false, operator<(lhs_type, rhs_type))
23155 }
23156
23159 template<typename ScalarType, typename std::enable_if<
23160 std::is_scalar<ScalarType>::value, int>::type = 0>
23161 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
23162 {
23163 return lhs < basic_json(rhs);
23164 }
23165
23168 template<typename ScalarType, typename std::enable_if<
23169 std::is_scalar<ScalarType>::value, int>::type = 0>
23170 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
23171 {
23172 return basic_json(lhs) < rhs;
23173 }
23174
23177 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
23178 {
23179 if (compares_unordered(lhs, rhs, true))
23180 {
23181 return false;
23182 }
23183 return !(rhs < lhs);
23184 }
23185
23188 template<typename ScalarType, typename std::enable_if<
23189 std::is_scalar<ScalarType>::value, int>::type = 0>
23190 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
23191 {
23192 return lhs <= basic_json(rhs);
23193 }
23194
23197 template<typename ScalarType, typename std::enable_if<
23198 std::is_scalar<ScalarType>::value, int>::type = 0>
23199 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
23200 {
23201 return basic_json(lhs) <= rhs;
23202 }
23203
23206 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23207 {
23208 // double inverse
23209 if (compares_unordered(lhs, rhs))
23210 {
23211 return false;
23212 }
23213 return !(lhs <= rhs);
23214 }
23215
23218 template<typename ScalarType, typename std::enable_if<
23219 std::is_scalar<ScalarType>::value, int>::type = 0>
23220 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
23221 {
23222 return lhs > basic_json(rhs);
23223 }
23224
23227 template<typename ScalarType, typename std::enable_if<
23228 std::is_scalar<ScalarType>::value, int>::type = 0>
23229 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
23230 {
23231 return basic_json(lhs) > rhs;
23232 }
23233
23236 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23237 {
23238 if (compares_unordered(lhs, rhs, true))
23239 {
23240 return false;
23241 }
23242 return !(lhs < rhs);
23243 }
23244
23247 template<typename ScalarType, typename std::enable_if<
23248 std::is_scalar<ScalarType>::value, int>::type = 0>
23249 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
23250 {
23251 return lhs >= basic_json(rhs);
23252 }
23253
23256 template<typename ScalarType, typename std::enable_if<
23257 std::is_scalar<ScalarType>::value, int>::type = 0>
23258 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
23259 {
23260 return basic_json(lhs) >= rhs;
23261 }
23262#endif
23263
23264#undef JSON_IMPLEMENT_OPERATOR
23265
23267
23269 // serialization //
23271
23274#ifndef JSON_NO_IO
23277 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23278 {
23279 // read width member and use it as indentation parameter if nonzero
23280 const bool pretty_print = o.width() > 0;
23281 const auto indentation = pretty_print ? o.width() : 0;
23282
23283 // reset width to 0 for subsequent calls to this stream
23284 o.width(0);
23285
23286 // do the actual serialization
23287 serializer s(detail::output_adapter<char>(o), o.fill());
23288 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23289 return o;
23290 }
23291
23298 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23299 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23300 {
23301 return o << j;
23302 }
23303#endif // JSON_NO_IO
23305
23307 // deserialization //
23309
23312
23315 template<typename InputType>
23317 static basic_json parse(InputType&& i,
23318 const parser_callback_t cb = nullptr,
23319 const bool allow_exceptions = true,
23320 const bool ignore_comments = false)
23321 {
23322 basic_json result;
23323 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23324 return result;
23325 }
23326
23329 template<typename IteratorType>
23331 static basic_json parse(IteratorType first,
23332 IteratorType last,
23333 const parser_callback_t cb = nullptr,
23334 const bool allow_exceptions = true,
23335 const bool ignore_comments = false)
23336 {
23337 basic_json result;
23338 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23339 return result;
23340 }
23341
23343 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23344 static basic_json parse(detail::span_input_adapter&& i,
23345 const parser_callback_t cb = nullptr,
23346 const bool allow_exceptions = true,
23347 const bool ignore_comments = false)
23348 {
23349 basic_json result;
23350 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23351 return result;
23352 }
23353
23356 template<typename InputType>
23357 static bool accept(InputType&& i,
23358 const bool ignore_comments = false)
23359 {
23360 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23361 }
23362
23365 template<typename IteratorType>
23366 static bool accept(IteratorType first, IteratorType last,
23367 const bool ignore_comments = false)
23368 {
23369 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23370 }
23371
23373 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23374 static bool accept(detail::span_input_adapter&& i,
23375 const bool ignore_comments = false)
23376 {
23377 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23378 }
23379
23382 template <typename InputType, typename SAX>
23384 static bool sax_parse(InputType&& i, SAX* sax,
23386 const bool strict = true,
23387 const bool ignore_comments = false)
23388 {
23389 auto ia = detail::input_adapter(std::forward<InputType>(i));
23390 return format == input_format_t::json
23391 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23392 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23393 }
23394
23397 template<class IteratorType, class SAX>
23399 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23401 const bool strict = true,
23402 const bool ignore_comments = false)
23403 {
23404 auto ia = detail::input_adapter(std::move(first), std::move(last));
23405 return format == input_format_t::json
23406 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23407 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23408 }
23409
23415 template <typename SAX>
23416 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23418 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23420 const bool strict = true,
23421 const bool ignore_comments = false)
23422 {
23423 auto ia = i.get();
23424 return format == input_format_t::json
23425 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23426 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23427 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23428 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
23429 }
23430#ifndef JSON_NO_IO
23437 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23438 friend std::istream& operator<<(basic_json& j, std::istream& i)
23439 {
23440 return operator>>(i, j);
23441 }
23442
23445 friend std::istream& operator>>(std::istream& i, basic_json& j)
23446 {
23447 parser(detail::input_adapter(i)).parse(false, j);
23448 return i;
23449 }
23450#endif // JSON_NO_IO
23452
23454 // convenience functions //
23456
23460 const char* type_name() const noexcept
23461 {
23462 switch (m_data.m_type)
23463 {
23464 case value_t::null:
23465 return "null";
23466 case value_t::object:
23467 return "object";
23468 case value_t::array:
23469 return "array";
23470 case value_t::string:
23471 return "string";
23472 case value_t::boolean:
23473 return "boolean";
23474 case value_t::binary:
23475 return "binary";
23476 case value_t::discarded:
23477 return "discarded";
23478 case value_t::number_integer:
23479 case value_t::number_unsigned:
23480 case value_t::number_float:
23481 default:
23482 return "number";
23483 }
23484 }
23485
23488 // member variables //
23490
23491 struct data
23492 {
23494 value_t m_type = value_t::null;
23495
23498
23499 data(const value_t v)
23500 : m_type(v), m_value(v)
23501 {
23502 }
23503
23504 data(size_type cnt, const basic_json& val)
23505 : m_type(value_t::array)
23506 {
23507 m_value.array = create<array_t>(cnt, val);
23508 }
23509
23510 data() noexcept = default;
23511 data(data&&) noexcept = default;
23512 data(const data&) noexcept = delete;
23513 data& operator=(data&&) noexcept = delete;
23514 data& operator=(const data&) noexcept = delete;
23515
23516 ~data() noexcept
23517 {
23518 m_value.destroy(m_type);
23519 }
23520 };
23521
23523
23524#if JSON_DIAGNOSTICS
23526 basic_json* m_parent = nullptr;
23527#endif
23528
23530 // binary serialization/deserialization //
23532
23535
23536public:
23539 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
23540 {
23541 std::vector<std::uint8_t> result;
23542 to_cbor(j, result);
23543 return result;
23544 }
23545
23549 {
23550 binary_writer<std::uint8_t>(o).write_cbor(j);
23551 }
23552
23556 {
23557 binary_writer<char>(o).write_cbor(j);
23558 }
23559
23562 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
23563 {
23564 std::vector<std::uint8_t> result;
23565 to_msgpack(j, result);
23566 return result;
23567 }
23568
23572 {
23573 binary_writer<std::uint8_t>(o).write_msgpack(j);
23574 }
23575
23579 {
23580 binary_writer<char>(o).write_msgpack(j);
23581 }
23582
23585 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
23586 const bool use_size = false,
23587 const bool use_type = false)
23588 {
23589 std::vector<std::uint8_t> result;
23590 to_ubjson(j, result, use_size, use_type);
23591 return result;
23592 }
23593
23597 const bool use_size = false, const bool use_type = false)
23598 {
23599 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
23600 }
23601
23605 const bool use_size = false, const bool use_type = false)
23606 {
23607 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23608 }
23609
23612 static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
23613 const bool use_size = false,
23614 const bool use_type = false)
23615 {
23616 std::vector<std::uint8_t> result;
23617 to_bjdata(j, result, use_size, use_type);
23618 return result;
23619 }
23620
23624 const bool use_size = false, const bool use_type = false)
23625 {
23626 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
23627 }
23628
23632 const bool use_size = false, const bool use_type = false)
23633 {
23634 binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
23635 }
23636
23639 static std::vector<std::uint8_t> to_bson(const basic_json& j)
23640 {
23641 std::vector<std::uint8_t> result;
23642 to_bson(j, result);
23643 return result;
23644 }
23645
23649 {
23650 binary_writer<std::uint8_t>(o).write_bson(j);
23651 }
23652
23656 {
23657 binary_writer<char>(o).write_bson(j);
23658 }
23659
23662 template<typename InputType>
23664 static basic_json from_cbor(InputType&& i,
23665 const bool strict = true,
23666 const bool allow_exceptions = true,
23667 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23668 {
23669 basic_json result;
23670 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23671 auto ia = detail::input_adapter(std::forward<InputType>(i));
23672 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23673 return res ? result : basic_json(value_t::discarded);
23674 }
23675
23678 template<typename IteratorType>
23680 static basic_json from_cbor(IteratorType first, IteratorType last,
23681 const bool strict = true,
23682 const bool allow_exceptions = true,
23683 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23684 {
23685 basic_json result;
23686 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23687 auto ia = detail::input_adapter(std::move(first), std::move(last));
23688 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23689 return res ? result : basic_json(value_t::discarded);
23690 }
23691
23692 template<typename T>
23694 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23695 static basic_json from_cbor(const T* ptr, std::size_t len,
23696 const bool strict = true,
23697 const bool allow_exceptions = true,
23698 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23699 {
23700 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23701 }
23702
23704 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
23705 static basic_json from_cbor(detail::span_input_adapter&& i,
23706 const bool strict = true,
23707 const bool allow_exceptions = true,
23708 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23709 {
23710 basic_json result;
23711 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23712 auto ia = i.get();
23713 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23714 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23715 return res ? result : basic_json(value_t::discarded);
23716 }
23717
23720 template<typename InputType>
23722 static basic_json from_msgpack(InputType&& i,
23723 const bool strict = true,
23724 const bool allow_exceptions = true)
23725 {
23726 basic_json result;
23727 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23728 auto ia = detail::input_adapter(std::forward<InputType>(i));
23729 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23730 return res ? result : basic_json(value_t::discarded);
23731 }
23732
23735 template<typename IteratorType>
23737 static basic_json from_msgpack(IteratorType first, IteratorType last,
23738 const bool strict = true,
23739 const bool allow_exceptions = true)
23740 {
23741 basic_json result;
23742 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23743 auto ia = detail::input_adapter(std::move(first), std::move(last));
23744 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23745 return res ? result : basic_json(value_t::discarded);
23746 }
23747
23748 template<typename T>
23750 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23751 static basic_json from_msgpack(const T* ptr, std::size_t len,
23752 const bool strict = true,
23753 const bool allow_exceptions = true)
23754 {
23755 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
23756 }
23757
23759 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
23760 static basic_json from_msgpack(detail::span_input_adapter&& i,
23761 const bool strict = true,
23762 const bool allow_exceptions = true)
23763 {
23764 basic_json result;
23765 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23766 auto ia = i.get();
23767 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23768 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
23769 return res ? result : basic_json(value_t::discarded);
23770 }
23771
23774 template<typename InputType>
23776 static basic_json from_ubjson(InputType&& i,
23777 const bool strict = true,
23778 const bool allow_exceptions = true)
23779 {
23780 basic_json result;
23781 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23782 auto ia = detail::input_adapter(std::forward<InputType>(i));
23783 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23784 return res ? result : basic_json(value_t::discarded);
23785 }
23786
23789 template<typename IteratorType>
23791 static basic_json from_ubjson(IteratorType first, IteratorType last,
23792 const bool strict = true,
23793 const bool allow_exceptions = true)
23794 {
23795 basic_json result;
23796 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23797 auto ia = detail::input_adapter(std::move(first), std::move(last));
23798 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23799 return res ? result : basic_json(value_t::discarded);
23800 }
23801
23802 template<typename T>
23804 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23805 static basic_json from_ubjson(const T* ptr, std::size_t len,
23806 const bool strict = true,
23807 const bool allow_exceptions = true)
23808 {
23809 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
23810 }
23811
23813 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
23814 static basic_json from_ubjson(detail::span_input_adapter&& i,
23815 const bool strict = true,
23816 const bool allow_exceptions = true)
23817 {
23818 basic_json result;
23819 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23820 auto ia = i.get();
23821 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23822 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
23823 return res ? result : basic_json(value_t::discarded);
23824 }
23825
23828 template<typename InputType>
23830 static basic_json from_bjdata(InputType&& i,
23831 const bool strict = true,
23832 const bool allow_exceptions = true)
23833 {
23834 basic_json result;
23835 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23836 auto ia = detail::input_adapter(std::forward<InputType>(i));
23837 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23838 return res ? result : basic_json(value_t::discarded);
23839 }
23840
23843 template<typename IteratorType>
23845 static basic_json from_bjdata(IteratorType first, IteratorType last,
23846 const bool strict = true,
23847 const bool allow_exceptions = true)
23848 {
23849 basic_json result;
23850 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23851 auto ia = detail::input_adapter(std::move(first), std::move(last));
23852 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23853 return res ? result : basic_json(value_t::discarded);
23854 }
23855
23858 template<typename InputType>
23860 static basic_json from_bson(InputType&& i,
23861 const bool strict = true,
23862 const bool allow_exceptions = true)
23863 {
23864 basic_json result;
23865 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23866 auto ia = detail::input_adapter(std::forward<InputType>(i));
23867 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23868 return res ? result : basic_json(value_t::discarded);
23869 }
23870
23873 template<typename IteratorType>
23875 static basic_json from_bson(IteratorType first, IteratorType last,
23876 const bool strict = true,
23877 const bool allow_exceptions = true)
23878 {
23879 basic_json result;
23880 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23881 auto ia = detail::input_adapter(std::move(first), std::move(last));
23882 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23883 return res ? result : basic_json(value_t::discarded);
23884 }
23885
23886 template<typename T>
23888 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23889 static basic_json from_bson(const T* ptr, std::size_t len,
23890 const bool strict = true,
23891 const bool allow_exceptions = true)
23892 {
23893 return from_bson(ptr, ptr + len, strict, allow_exceptions);
23894 }
23895
23897 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23898 static basic_json from_bson(detail::span_input_adapter&& i,
23899 const bool strict = true,
23900 const bool allow_exceptions = true)
23901 {
23902 basic_json result;
23903 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23904 auto ia = i.get();
23905 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23906 const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23907 return res ? result : basic_json(value_t::discarded);
23908 }
23909
23910
23912 // JSON Pointer support //
23914
23917
23921 {
23922 return ptr.get_unchecked(this);
23923 }
23924
23925 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23926 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23927 reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23928 {
23929 return ptr.get_unchecked(this);
23930 }
23931
23935 {
23936 return ptr.get_unchecked(this);
23937 }
23938
23939 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23940 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23941 const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23942 {
23943 return ptr.get_unchecked(this);
23944 }
23945
23949 {
23950 return ptr.get_checked(this);
23951 }
23952
23953 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23954 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23955 reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23956 {
23957 return ptr.get_checked(this);
23958 }
23959
23963 {
23964 return ptr.get_checked(this);
23965 }
23966
23967 template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23968 JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer<basic_json::string_t>) // NOLINT(readability/alt_tokens)
23969 const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23970 {
23971 return ptr.get_checked(this);
23972 }
23973
23977 {
23978 basic_json result(value_t::object);
23979 json_pointer::flatten("", *this, result);
23980 return result;
23981 }
23982
23986 {
23987 return json_pointer::unflatten(*this);
23988 }
23989
23991
23993 // JSON Patch functions //
23995
23998
24001 void patch_inplace(const basic_json& json_patch)
24002 {
24003 basic_json& result = *this;
24004 // the valid JSON Patch operations
24005 enum class patch_operations { add, remove, replace, move, copy, test, invalid };
24006
24007 const auto get_op = [](const std::string& op)
24008 {
24009 if (op == "add")
24010 {
24011 return patch_operations::add;
24012 }
24013 if (op == "remove")
24014 {
24015 return patch_operations::remove;
24016 }
24017 if (op == "replace")
24018 {
24019 return patch_operations::replace;
24020 }
24021 if (op == "move")
24022 {
24023 return patch_operations::move;
24024 }
24025 if (op == "copy")
24026 {
24027 return patch_operations::copy;
24028 }
24029 if (op == "test")
24030 {
24031 return patch_operations::test;
24032 }
24033
24034 return patch_operations::invalid;
24035 };
24036
24037 // wrapper for "add" operation; add value at ptr
24038 const auto operation_add = [&result](json_pointer& ptr, basic_json val)
24039 {
24040 // adding to the root of the target document means replacing it
24041 if (ptr.empty())
24042 {
24043 result = val;
24044 return;
24045 }
24046
24047 // make sure the top element of the pointer exists
24048 json_pointer const top_pointer = ptr.top();
24049 if (top_pointer != ptr)
24050 {
24051 result.at(top_pointer);
24052 }
24053
24054 // get reference to parent of JSON pointer ptr
24055 const auto last_path = ptr.back();
24056 ptr.pop_back();
24057 // parent must exist when performing patch add per RFC6902 specs
24058 basic_json& parent = result.at(ptr);
24059
24060 switch (parent.m_data.m_type)
24061 {
24062 case value_t::null:
24063 case value_t::object:
24064 {
24065 // use operator[] to add value
24066 parent[last_path] = val;
24067 break;
24068 }
24069
24070 case value_t::array:
24071 {
24072 if (last_path == "-")
24073 {
24074 // special case: append to back
24075 parent.push_back(val);
24076 }
24077 else
24078 {
24079 const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
24080 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24081 {
24082 // avoid undefined behavior
24083 JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
24084 }
24085
24086 // default case: insert add offset
24087 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24088 }
24089 break;
24090 }
24091
24092 // if there exists a parent it cannot be primitive
24093 case value_t::string: // LCOV_EXCL_LINE
24094 case value_t::boolean: // LCOV_EXCL_LINE
24095 case value_t::number_integer: // LCOV_EXCL_LINE
24096 case value_t::number_unsigned: // LCOV_EXCL_LINE
24097 case value_t::number_float: // LCOV_EXCL_LINE
24098 case value_t::binary: // LCOV_EXCL_LINE
24099 case value_t::discarded: // LCOV_EXCL_LINE
24100 default: // LCOV_EXCL_LINE
24101 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
24102 }
24103 };
24104
24105 // wrapper for "remove" operation; remove value at ptr
24106 const auto operation_remove = [this, &result](json_pointer& ptr)
24107 {
24108 // get reference to parent of JSON pointer ptr
24109 const auto last_path = ptr.back();
24110 ptr.pop_back();
24111 basic_json& parent = result.at(ptr);
24112
24113 // remove child
24114 if (parent.is_object())
24115 {
24116 // perform range check
24117 auto it = parent.find(last_path);
24118 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24119 {
24120 parent.erase(it);
24121 }
24122 else
24123 {
24124 JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
24125 }
24126 }
24127 else if (parent.is_array())
24128 {
24129 // note erase performs range check
24130 parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
24131 }
24132 };
24133
24134 // type check: top level value must be an array
24135 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24136 {
24137 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
24138 }
24139
24140 // iterate and apply the operations
24141 for (const auto& val : json_patch)
24142 {
24143 // wrapper to get a value for an operation
24144 const auto get_value = [&val](const std::string& op,
24145 const std::string& member,
24146 bool string_type) -> basic_json&
24147 {
24148 // find value
24149 auto it = val.m_data.m_value.object->find(member);
24150
24151 // context-sensitive error message
24152 const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\''); // NOLINT(bugprone-unused-local-non-trivial-variable)
24153
24154 // check if desired value is present
24155 if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
24156 {
24157 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24158 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
24159 }
24160
24161 // check if result is of type string
24162 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24163 {
24164 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
24165 JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
24166 }
24167
24168 // no error: return value
24169 return it->second;
24170 };
24171
24172 // type check: every element of the array must be an object
24173 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24174 {
24175 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
24176 }
24177
24178 // collect mandatory members
24179 const auto op = get_value("op", "op", true).template get<std::string>();
24180 const auto path = get_value(op, "path", true).template get<std::string>();
24181 json_pointer ptr(path);
24182
24183 switch (get_op(op))
24184 {
24185 case patch_operations::add:
24186 {
24187 operation_add(ptr, get_value("add", "value", false));
24188 break;
24189 }
24190
24191 case patch_operations::remove:
24192 {
24193 operation_remove(ptr);
24194 break;
24195 }
24196
24197 case patch_operations::replace:
24198 {
24199 // the "path" location must exist - use at()
24200 result.at(ptr) = get_value("replace", "value", false);
24201 break;
24202 }
24203
24204 case patch_operations::move:
24205 {
24206 const auto from_path = get_value("move", "from", true).template get<std::string>();
24207 json_pointer from_ptr(from_path);
24208
24209 // the "from" location must exist - use at()
24210 basic_json const v = result.at(from_ptr);
24211
24212 // The move operation is functionally identical to a
24213 // "remove" operation on the "from" location, followed
24214 // immediately by an "add" operation at the target
24215 // location with the value that was just removed.
24216 operation_remove(from_ptr);
24217 operation_add(ptr, v);
24218 break;
24219 }
24220
24221 case patch_operations::copy:
24222 {
24223 const auto from_path = get_value("copy", "from", true).template get<std::string>();
24224 const json_pointer from_ptr(from_path);
24225
24226 // the "from" location must exist - use at()
24227 basic_json const v = result.at(from_ptr);
24228
24229 // The copy is functionally identical to an "add"
24230 // operation at the target location using the value
24231 // specified in the "from" member.
24232 operation_add(ptr, v);
24233 break;
24234 }
24235
24236 case patch_operations::test:
24237 {
24238 bool success = false;
24239 JSON_TRY
24240 {
24241 // check if "value" matches the one at "path"
24242 // the "path" location must exist - use at()
24243 success = (result.at(ptr) == get_value("test", "value", false));
24244 }
24246 {
24247 // ignore out of range errors: success remains false
24248 }
24249
24250 // throw an exception if test fails
24251 if (JSON_HEDLEY_UNLIKELY(!success))
24252 {
24253 JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
24254 }
24255
24256 break;
24257 }
24258
24259 case patch_operations::invalid:
24260 default:
24261 {
24262 // op must be "add", "remove", "replace", "move", "copy", or
24263 // "test"
24264 JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
24265 }
24266 }
24267 }
24268 }
24269
24272 basic_json patch(const basic_json& json_patch) const
24273 {
24274 basic_json result = *this;
24275 result.patch_inplace(json_patch);
24276 return result;
24277 }
24278
24282 static basic_json diff(const basic_json& source, const basic_json& target,
24283 const std::string& path = "")
24284 {
24285 // the patch
24286 basic_json result(value_t::array);
24287
24288 // if the values are the same, return empty patch
24289 if (source == target)
24290 {
24291 return result;
24292 }
24293
24294 if (source.type() != target.type())
24295 {
24296 // different types: replace value
24297 result.push_back(
24298 {
24299 {"op", "replace"}, {"path", path}, {"value", target}
24300 });
24301 return result;
24302 }
24303
24304 switch (source.type())
24305 {
24306 case value_t::array:
24307 {
24308 // first pass: traverse common elements
24309 std::size_t i = 0;
24310 while (i < source.size() && i < target.size())
24311 {
24312 // recursive call to compare array values at index i
24313 auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
24314 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24315 ++i;
24316 }
24317
24318 // We now reached the end of at least one array
24319 // in a second pass, traverse the remaining elements
24320
24321 // remove my remaining elements
24322 const auto end_index = static_cast<difference_type>(result.size());
24323 while (i < source.size())
24324 {
24325 // add operations in reverse order to avoid invalid
24326 // indices
24327 result.insert(result.begin() + end_index, object(
24328 {
24329 {"op", "remove"},
24330 {"path", detail::concat(path, '/', std::to_string(i))}
24331 }));
24332 ++i;
24333 }
24334
24335 // add other remaining elements
24336 while (i < target.size())
24337 {
24338 result.push_back(
24339 {
24340 {"op", "add"},
24341 {"path", detail::concat(path, "/-")},
24342 {"value", target[i]}
24343 });
24344 ++i;
24345 }
24346
24347 break;
24348 }
24349
24350 case value_t::object:
24351 {
24352 // first pass: traverse this object's elements
24353 for (auto it = source.cbegin(); it != source.cend(); ++it)
24354 {
24355 // escape the key name to be used in a JSON patch
24356 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24357
24358 if (target.find(it.key()) != target.end())
24359 {
24360 // recursive call to compare object values at key it
24361 auto temp_diff = diff(it.value(), target[it.key()], path_key);
24362 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24363 }
24364 else
24365 {
24366 // found a key that is not in o -> remove it
24367 result.push_back(object(
24368 {
24369 {"op", "remove"}, {"path", path_key}
24370 }));
24371 }
24372 }
24373
24374 // second pass: traverse other object's elements
24375 for (auto it = target.cbegin(); it != target.cend(); ++it)
24376 {
24377 if (source.find(it.key()) == source.end())
24378 {
24379 // found a key that is not in this -> add it
24380 const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
24381 result.push_back(
24382 {
24383 {"op", "add"}, {"path", path_key},
24384 {"value", it.value()}
24385 });
24386 }
24387 }
24388
24389 break;
24390 }
24391
24392 case value_t::null:
24393 case value_t::string:
24394 case value_t::boolean:
24395 case value_t::number_integer:
24396 case value_t::number_unsigned:
24397 case value_t::number_float:
24398 case value_t::binary:
24399 case value_t::discarded:
24400 default:
24401 {
24402 // both primitive type: replace value
24403 result.push_back(
24404 {
24405 {"op", "replace"}, {"path", path}, {"value", target}
24406 });
24407 break;
24408 }
24409 }
24410
24411 return result;
24412 }
24413
24414
24416 // JSON Merge Patch functions //
24418
24421
24424 void merge_patch(const basic_json& apply_patch)
24425 {
24426 if (apply_patch.is_object())
24427 {
24428 if (!is_object())
24429 {
24430 *this = object();
24431 }
24432 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24433 {
24434 if (it.value().is_null())
24435 {
24436 erase(it.key());
24437 }
24438 else
24439 {
24440 operator[](it.key()).merge_patch(it.value());
24441 }
24442 }
24443 }
24444 else
24445 {
24446 *this = apply_patch;
24447 }
24448 }
24449
24451};
24452
24457{
24458 return j.dump();
24459}
24460
24461inline namespace literals
24462{
24463 inline namespace json_literals
24464 {
24465
24469#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24470 inline nlohmann::json operator ""_json(const char* s, std::size_t n)
24471#else
24472 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24473#endif
24474 {
24475 return nlohmann::json::parse(s, s + n);
24476 }
24477
24481#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24482 inline nlohmann::json::json_pointer operator ""_json_pointer(const char* s, std::size_t n)
24483#else
24484 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24485#endif
24486 {
24487 return nlohmann::json::json_pointer(std::string(s, n));
24488 }
24489
24490 } // namespace json_literals
24491} // namespace literals
24493
24495// nonmember support //
24497
24498namespace std // NOLINT(cert-dcl58-cpp)
24499{
24500
24504 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL> // NOLINT(cert-dcl58-cpp)
24505 {
24506 std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
24507 {
24508 return nlohmann::detail::hash(j);
24509 }
24510 };
24511
24512 // specialization for std::less<value_t>
24513 template<>
24514 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
24515 {
24520 bool operator()(::nlohmann::detail::value_t lhs,
24521 ::nlohmann::detail::value_t rhs) const noexcept
24522 {
24523#if JSON_HAS_THREE_WAY_COMPARISON
24524 return std::is_lt(lhs <=> rhs); // *NOPAD*
24525#else
24526 return ::nlohmann::detail::operator<(lhs, rhs);
24527#endif
24528 }
24529 };
24530
24531 // C++20 prohibit function specialization in the std namespace.
24532#ifndef JSON_HAS_CPP_20
24533
24537 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp)
24538 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap)
24539 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
24540 {
24541 j1.swap(j2);
24542 }
24543
24544#endif
24545
24546} // namespace std
24547
24548#if JSON_USE_GLOBAL_UDLS
24549#if !defined(JSON_HEDLEY_GCC_VERSION) || JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
24550using nlohmann::literals::json_literals::operator ""_json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24551using nlohmann::literals::json_literals::operator ""_json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24552#else
24553using nlohmann::literals::json_literals::operator "" _json; // NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24554using nlohmann::literals::json_literals::operator "" _json_pointer; //NOLINT(misc-unused-using-decls,google-global-names-in-headers)
24555#endif
24556#endif
24557
24558// #include <nlohmann/detail/macro_unscope.hpp>
24559// __ _____ _____ _____
24560// __| | __| | | | JSON for Modern C++
24561// | | |__ | | | | | | version 3.11.3
24562// |_____|_____|_____|_|___| https://github.com/nlohmann/json
24563//
24564// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
24565// SPDX-License-Identifier: MIT
24566
24567
24568
24569// restore clang diagnostic settings
24570#if defined(__clang__)
24571#pragma clang diagnostic pop
24572#endif
24573
24574// clean up
24575#undef JSON_ASSERT
24576#undef JSON_INTERNAL_CATCH
24577#undef JSON_THROW
24578#undef JSON_PRIVATE_UNLESS_TESTED
24579#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24580#undef NLOHMANN_BASIC_JSON_TPL
24581#undef JSON_EXPLICIT
24582#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
24583#undef JSON_INLINE_VARIABLE
24584#undef JSON_NO_UNIQUE_ADDRESS
24585#undef JSON_DISABLE_ENUM_SERIALIZATION
24586#undef JSON_USE_GLOBAL_UDLS
24587
24588#ifndef JSON_TEST_KEEP_MACROS
24589#undef JSON_CATCH
24590#undef JSON_TRY
24591#undef JSON_HAS_CPP_11
24592#undef JSON_HAS_CPP_14
24593#undef JSON_HAS_CPP_17
24594#undef JSON_HAS_CPP_20
24595#undef JSON_HAS_FILESYSTEM
24596#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
24597#undef JSON_HAS_THREE_WAY_COMPARISON
24598#undef JSON_HAS_RANGES
24599#undef JSON_HAS_STATIC_RTTI
24600#undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
24601#endif
24602
24603// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24604// __ _____ _____ _____
24605// __| | __| | | | JSON for Modern C++
24606// | | |__ | | | | | | version 3.11.3
24607// |_____|_____|_____|_|___| https://github.com/nlohmann/json
24608//
24609// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
24610// SPDX-License-Identifier: MIT
24611
24612
24613
24614#undef JSON_HEDLEY_ALWAYS_INLINE
24615#undef JSON_HEDLEY_ARM_VERSION
24616#undef JSON_HEDLEY_ARM_VERSION_CHECK
24617#undef JSON_HEDLEY_ARRAY_PARAM
24618#undef JSON_HEDLEY_ASSUME
24619#undef JSON_HEDLEY_BEGIN_C_DECLS
24620#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24621#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24622#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24623#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24624#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24625#undef JSON_HEDLEY_CLANG_HAS_FEATURE
24626#undef JSON_HEDLEY_CLANG_HAS_WARNING
24627#undef JSON_HEDLEY_COMPCERT_VERSION
24628#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24629#undef JSON_HEDLEY_CONCAT
24630#undef JSON_HEDLEY_CONCAT3
24631#undef JSON_HEDLEY_CONCAT3_EX
24632#undef JSON_HEDLEY_CONCAT_EX
24633#undef JSON_HEDLEY_CONST
24634#undef JSON_HEDLEY_CONSTEXPR
24635#undef JSON_HEDLEY_CONST_CAST
24636#undef JSON_HEDLEY_CPP_CAST
24637#undef JSON_HEDLEY_CRAY_VERSION
24638#undef JSON_HEDLEY_CRAY_VERSION_CHECK
24639#undef JSON_HEDLEY_C_DECL
24640#undef JSON_HEDLEY_DEPRECATED
24641#undef JSON_HEDLEY_DEPRECATED_FOR
24642#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24643#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24644#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24645#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24646#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24647#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
24648#undef JSON_HEDLEY_DIAGNOSTIC_POP
24649#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24650#undef JSON_HEDLEY_DMC_VERSION
24651#undef JSON_HEDLEY_DMC_VERSION_CHECK
24652#undef JSON_HEDLEY_EMPTY_BASES
24653#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24654#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24655#undef JSON_HEDLEY_END_C_DECLS
24656#undef JSON_HEDLEY_FLAGS
24657#undef JSON_HEDLEY_FLAGS_CAST
24658#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24659#undef JSON_HEDLEY_GCC_HAS_BUILTIN
24660#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24661#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24662#undef JSON_HEDLEY_GCC_HAS_EXTENSION
24663#undef JSON_HEDLEY_GCC_HAS_FEATURE
24664#undef JSON_HEDLEY_GCC_HAS_WARNING
24665#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24666#undef JSON_HEDLEY_GCC_VERSION
24667#undef JSON_HEDLEY_GCC_VERSION_CHECK
24668#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24669#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24670#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24671#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24672#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24673#undef JSON_HEDLEY_GNUC_HAS_FEATURE
24674#undef JSON_HEDLEY_GNUC_HAS_WARNING
24675#undef JSON_HEDLEY_GNUC_VERSION
24676#undef JSON_HEDLEY_GNUC_VERSION_CHECK
24677#undef JSON_HEDLEY_HAS_ATTRIBUTE
24678#undef JSON_HEDLEY_HAS_BUILTIN
24679#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24680#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24681#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24682#undef JSON_HEDLEY_HAS_EXTENSION
24683#undef JSON_HEDLEY_HAS_FEATURE
24684#undef JSON_HEDLEY_HAS_WARNING
24685#undef JSON_HEDLEY_IAR_VERSION
24686#undef JSON_HEDLEY_IAR_VERSION_CHECK
24687#undef JSON_HEDLEY_IBM_VERSION
24688#undef JSON_HEDLEY_IBM_VERSION_CHECK
24689#undef JSON_HEDLEY_IMPORT
24690#undef JSON_HEDLEY_INLINE
24691#undef JSON_HEDLEY_INTEL_CL_VERSION
24692#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
24693#undef JSON_HEDLEY_INTEL_VERSION
24694#undef JSON_HEDLEY_INTEL_VERSION_CHECK
24695#undef JSON_HEDLEY_IS_CONSTANT
24696#undef JSON_HEDLEY_IS_CONSTEXPR_
24697#undef JSON_HEDLEY_LIKELY
24698#undef JSON_HEDLEY_MALLOC
24699#undef JSON_HEDLEY_MCST_LCC_VERSION
24700#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
24701#undef JSON_HEDLEY_MESSAGE
24702#undef JSON_HEDLEY_MSVC_VERSION
24703#undef JSON_HEDLEY_MSVC_VERSION_CHECK
24704#undef JSON_HEDLEY_NEVER_INLINE
24705#undef JSON_HEDLEY_NON_NULL
24706#undef JSON_HEDLEY_NO_ESCAPE
24707#undef JSON_HEDLEY_NO_RETURN
24708#undef JSON_HEDLEY_NO_THROW
24709#undef JSON_HEDLEY_NULL
24710#undef JSON_HEDLEY_PELLES_VERSION
24711#undef JSON_HEDLEY_PELLES_VERSION_CHECK
24712#undef JSON_HEDLEY_PGI_VERSION
24713#undef JSON_HEDLEY_PGI_VERSION_CHECK
24714#undef JSON_HEDLEY_PREDICT
24715#undef JSON_HEDLEY_PRINTF_FORMAT
24716#undef JSON_HEDLEY_PRIVATE
24717#undef JSON_HEDLEY_PUBLIC
24718#undef JSON_HEDLEY_PURE
24719#undef JSON_HEDLEY_REINTERPRET_CAST
24720#undef JSON_HEDLEY_REQUIRE
24721#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24722#undef JSON_HEDLEY_REQUIRE_MSG
24723#undef JSON_HEDLEY_RESTRICT
24724#undef JSON_HEDLEY_RETURNS_NON_NULL
24725#undef JSON_HEDLEY_SENTINEL
24726#undef JSON_HEDLEY_STATIC_ASSERT
24727#undef JSON_HEDLEY_STATIC_CAST
24728#undef JSON_HEDLEY_STRINGIFY
24729#undef JSON_HEDLEY_STRINGIFY_EX
24730#undef JSON_HEDLEY_SUNPRO_VERSION
24731#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24732#undef JSON_HEDLEY_TINYC_VERSION
24733#undef JSON_HEDLEY_TINYC_VERSION_CHECK
24734#undef JSON_HEDLEY_TI_ARMCL_VERSION
24735#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24736#undef JSON_HEDLEY_TI_CL2000_VERSION
24737#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24738#undef JSON_HEDLEY_TI_CL430_VERSION
24739#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24740#undef JSON_HEDLEY_TI_CL6X_VERSION
24741#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24742#undef JSON_HEDLEY_TI_CL7X_VERSION
24743#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24744#undef JSON_HEDLEY_TI_CLPRU_VERSION
24745#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24746#undef JSON_HEDLEY_TI_VERSION
24747#undef JSON_HEDLEY_TI_VERSION_CHECK
24748#undef JSON_HEDLEY_UNAVAILABLE
24749#undef JSON_HEDLEY_UNLIKELY
24750#undef JSON_HEDLEY_UNPREDICTABLE
24751#undef JSON_HEDLEY_UNREACHABLE
24752#undef JSON_HEDLEY_UNREACHABLE_RETURN
24753#undef JSON_HEDLEY_VERSION
24754#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24755#undef JSON_HEDLEY_VERSION_DECODE_MINOR
24756#undef JSON_HEDLEY_VERSION_DECODE_REVISION
24757#undef JSON_HEDLEY_VERSION_ENCODE
24758#undef JSON_HEDLEY_WARNING
24759#undef JSON_HEDLEY_WARN_UNUSED_RESULT
24760#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
24761#undef JSON_HEDLEY_FALL_THROUGH
24762
24763
24764
24765#endif // INCLUDE_NLOHMANN_JSON_HPP_
bool operator<(const Index2D &lhs, const Index2D &rhs)
@ out
namespace for Niels Lohmann
Definition json.hpp:19401
constexpr bool is_string() const noexcept
Definition json.hpp:20673
reference set_parent(reference j, std::size_t old_capacity=static_cast< std::size_t >(-1))
Definition json.hpp:20055
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition json.hpp:20766
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition json.hpp:21906
detail::cbor_tag_handler_t cbor_tag_handler_t
Definition json.hpp:19474
reference operator[](KeyType &&key)
access specified object element
Definition json.hpp:21474
json_value(object_t &&value)
constructor for rvalue objects
Definition json.hpp:19836
size_type size() const noexcept
Definition json.hpp:22247
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:23680
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition json.hpp:19848
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:23612
number_unsigned_t number_unsigned
Definition json.hpp:19740
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 > {}))
Definition json.hpp:21046
::nlohmann::detail::iteration_proxy< Iterator > iteration_proxy
Definition json.hpp:19452
const_iterator end() const noexcept
returns an iterator to one past the last element
Definition json.hpp:22104
reference back()
access the last element
Definition json.hpp:21710
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:20137
detail::parse_error parse_error
Definition json.hpp:19491
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition json.hpp:22120
detail::input_format_t input_format_t
Definition json.hpp:19478
basic_json patch(const basic_json &json_patch) const
applies a JSON patch to a copy of the current object
Definition json.hpp:24272
json_value(const array_t &value)
constructor for arrays
Definition json.hpp:19839
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition json.hpp:20730
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
Definition json.hpp:23460
const_reference front() const
access the first element
Definition json.hpp:21703
constexpr bool is_array() const noexcept
return whether value is an array
Definition json.hpp:20666
nlohmann::ordered_map< std::string, basic_json, default_object_comparator_t, std::allocator< std::pair< const std::string, basic_json > > > object_t
Definition json.hpp:19635
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition json.hpp:20790
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 &&//NOLINT(cppcoreguidelines-noexcept-swap, performance-noexcept-swap) std::is_nothrow_move_assignable< json_value >::value)
Definition json.hpp:22764
ReturnType value(const json_pointer &ptr, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition json.hpp:21654
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition json.hpp:22023
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition json.hpp:20772
iter_impl< const basic_json > const_iterator
Definition json.hpp:19532
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:23631
std::conditional< detail::is_c_string_uncvref< ValueType >::value, string_t, typename std::decay< ValueType >::type > value_return_type
Definition json.hpp:21517
constexpr bool is_number_integer() const noexcept
Definition json.hpp:20638
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
Definition json.hpp:19536
data(size_type cnt, const basic_json &val)
Definition json.hpp:23504
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:23875
::nlohmann::detail::json_base_class< void > json_base_class_t
Definition json.hpp:19427
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition json.hpp:20998
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:23623
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition json.hpp:23920
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
Definition json.hpp:19527
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition json.hpp:19680
constexpr bool is_structured() const noexcept
Definition json.hpp:20610
json_value(boolean_t v) noexcept
constructor for booleans
Definition json.hpp:19747
const_reference operator[](KeyType &&key) const
access specified object element
Definition json.hpp:21498
detail::error_handler_t error_handler_t
Definition json.hpp:19472
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition json.hpp:20707
const value_type & const_reference
Definition json.hpp:19514
detail::invalid_iterator invalid_iterator
Definition json.hpp:19492
void swap(binary_t &other)
exchanges the values
Definition json.hpp:22841
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition json.hpp:22286
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition json.hpp:22710
::nlohmann::detail::iter_impl< BasicJsonType > iter_impl
Definition json.hpp:19450
ReferenceType get_ref() const
get a reference value (implicit)
Definition json.hpp:21147
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition json.hpp:20687
JSON_PRIVATE_UNLESS_TESTED const_reference rhs
Definition json.hpp:22959
reference operator+=(initializer_list_t init)
add an object to an object
Definition json.hpp:22502
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition json.hpp:19456
void push_back(basic_json &&val)
add an object to an array
Definition json.hpp:22390
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition json.hpp:21443
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition json.hpp:22192
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition json.hpp:19749
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition json.hpp:20825
::nlohmann::detail::json_reverse_iterator< Base > json_reverse_iterator
Definition json.hpp:19453
const_reference back() const
access the last element
Definition json.hpp:21719
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition json.hpp:21801
reference operator+=(const basic_json &val)
add an object to an array
Definition json.hpp:22447
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 &&//NOLINT(cppcoreguidelines-noexcept-swap, performance-noexcept-swap) std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition json.hpp:22781
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:23776
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition json.hpp:20748
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:20274
detail::is_comparable< object_comparator_t, const typename object_t::key_type &, KeyType > is_comparable_with_object_key
Definition json.hpp:21513
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition json.hpp:22614
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition json.hpp:20718
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:23860
static allocator_type get_allocator()
returns the allocator associated with the container
Definition json.hpp:19542
nlohmann::byte_container_with_subtype< std::vector< std::uint8_t > > binary_t
Definition json.hpp:19667
reference at(KeyType &&key)
access specified object element with bounds checking
Definition json.hpp:21306
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition json.hpp:20645
json_value(array_t &&value)
constructor for rvalue arrays
Definition json.hpp:19842
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:22717
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition json.hpp:23639
const_reverse_iterator rbegin() const noexcept
returns an iterator to the reverse-beginning
Definition json.hpp:22127
data m_data
Definition json.hpp:23522
void push_back(initializer_list_t init)
add an object to an object
Definition json.hpp:22486
detail::parser_callback_t< basic_json > parser_callback_t
Definition json.hpp:20104
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
Definition json.hpp:20315
ValueType & get_to(ValueType &v) const
Definition json.hpp:21113
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:23578
detail::parse_event_t parse_event_t
Definition json.hpp:20100
JSON_PRIVATE_UNLESS_TESTED const_reference bool inverse
Definition json.hpp:22959
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition json.hpp:19984
ReturnType value(const typename object_t::key_type &key, ValueType &&default_value) const
access specified object element with default value
Definition json.hpp:21553
void destroy(value_t t)
Definition json.hpp:19856
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition json.hpp:20908
json_value(string_t &&value)
constructor for rvalue strings
Definition json.hpp:19830
const_iterator cend() const noexcept
Definition json.hpp:22111
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition json.hpp:20808
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:23830
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition json.hpp:23962
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition json.hpp:20285
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition json.hpp:20125
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:23664
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition json.hpp:20784
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition json.hpp:20760
basic_json flatten() const
return flattened JSON value
Definition json.hpp:23976
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition json.hpp:20736
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:23791
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition json.hpp:19751
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition json.hpp:21917
std::vector< basic_json, std::allocator< basic_json > > array_t
Definition json.hpp:19643
::nlohmann::detail::primitive_iterator_t primitive_iterator_t
Definition json.hpp:19446
json_value(const string_t &value)
constructor for strings
Definition json.hpp:19827
const binary_t & get_binary() const
get a binary value
Definition json.hpp:21218
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition json.hpp:22634
void patch_inplace(const basic_json &json_patch)
applies a JSON patch in-place without copying the object
Definition json.hpp:24001
ReturnType value(KeyType &&key, ValueType &&default_value) const
access specified object element via JSON Pointer with default value
Definition json.hpp:21606
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:24282
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition json.hpp:23934
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition json.hpp:19753
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
Definition json.hpp:19476
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition json.hpp:22040
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:23548
::nlohmann::detail::binary_reader< basic_json, InputType > binary_reader
Definition json.hpp:19459
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:23655
iterator find(const typename object_t::key_type &key)
Definition json.hpp:21953
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:20263
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition json.hpp:20975
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition json.hpp:21344
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition json.hpp:19550
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition json.hpp:20322
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition json.hpp:21967
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition json.hpp:23539
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition json.hpp:21731
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition json.hpp:22587
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
Definition json.hpp:21528
std::allocator< basic_json > allocator_type
Definition json.hpp:19522
typename std::allocator_traits< allocator_type >::pointer pointer
Definition json.hpp:19525
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:20574
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition json.hpp:24424
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:21100
reference operator[](T *key)
Definition json.hpp:21459
reference at(size_type idx)
access specified array element with bounds checking
Definition json.hpp:21240
iterator find(KeyType &&key)
find an element in a JSON object
Definition json.hpp:21983
constexpr bool is_number_float() const noexcept
Definition json.hpp:20652
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition json.hpp:22134
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:23585
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition json.hpp:23948
::nlohmann::detail::internal_iterator< BasicJsonType > internal_iterator
Definition json.hpp:19448
void set_parents()
Definition json.hpp:20005
size_type erase_internal(KeyType &&key)
Definition json.hpp:21872
std::less< std::string > default_object_comparator_t
Definition json.hpp:19630
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition json.hpp:22478
const_iterator cbegin() const noexcept
Definition json.hpp:22086
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition json.hpp:20796
reference operator[](typename object_t::key_type key)
access specified object element
Definition json.hpp:21421
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition json.hpp:20742
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:20858
~basic_json() noexcept
destructor
Definition json.hpp:20556
detail::out_of_range out_of_range
Definition json.hpp:19494
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition json.hpp:19854
const_reverse_iterator crend() const noexcept
Definition json.hpp:22155
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:20204
json_value(const object_t &value)
constructor for objects
Definition json.hpp:19833
void swap(typename binary_t::container_type &other)
exchanges the values
Definition json.hpp:22857
binary_t & get_binary()
get a binary value
Definition json.hpp:21206
const_iterator begin() const noexcept
returns an iterator to the first element
Definition json.hpp:22079
constexpr bool is_number() const noexcept
Definition json.hpp:20631
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition json.hpp:20778
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition json.hpp:22685
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:23722
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition json.hpp:21087
const_reference operator[](T *key) const
Definition json.hpp:21465
reference operator[](size_type idx)
access specified array element
Definition json.hpp:21362
basic_json(const JsonRef &ref)
Definition json.hpp:20443
adl_serializer< T, SFINAE > json_serializer
Definition json.hpp:19470
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 &&std::is_nothrow_move_assignable< json_base_class_t >::value)
copy assignment
Definition json.hpp:20533
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
Definition json.hpp:22167
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:23604
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition json.hpp:21124
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
Definition json.hpp:20847
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition json.hpp:21324
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition json.hpp:20802
constexpr bool is_binary() const noexcept
Definition json.hpp:20680
void swap(object_t &other)
exchanges the values
Definition json.hpp:22809
iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
Definition json.hpp:20042
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition json.hpp:21011
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition json.hpp:23985
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition json.hpp:22665
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:20296
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition json.hpp:22185
bool empty() const noexcept
checks whether the container is empty.
Definition json.hpp:22208
void swap(array_t &other)
exchanges the values
Definition json.hpp:22793
void erase(const size_type idx)
remove element from a JSON array given an index
Definition json.hpp:21924
reference operator+=(basic_json &&val)
add an object to an array
Definition json.hpp:22415
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition json.hpp:22047
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition json.hpp:20950
constexpr value_t type() const noexcept
Definition json.hpp:20596
reference emplace_back(Args &&... args)
add an object to an array
Definition json.hpp:22511
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition json.hpp:21629
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition json.hpp:20307
data() noexcept=default
friend class ::nlohmann::detail::parser
Definition json.hpp:19411
void push_back(const basic_json &val)
add an object to an array
Definition json.hpp:22423
ValueType value(KeyType &&key, const ValueType &default_value) const
access specified object element with default value
Definition json.hpp:21579
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition json.hpp:21286
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:23845
const_reverse_iterator crbegin() const noexcept
Definition json.hpp:22148
json_sax< basic_json > json_sax_t
Definition json.hpp:19480
constexpr bool is_boolean() const noexcept
Definition json.hpp:20624
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:22013
reference front()
access the first element
Definition json.hpp:21696
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition json.hpp:20603
constexpr bool is_null() const noexcept
Definition json.hpp:20617
void clear() noexcept
clears the contents
Definition json.hpp:22329
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition json.hpp:20724
json_value(value_t t)
constructor for empty values of a given type
Definition json.hpp:19755
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition json.hpp:19434
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:23596
detail::other_error other_error
Definition json.hpp:19495
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:23384
basic_json(basic_json &&other) noexcept
move constructor
Definition json.hpp:20516
iter_impl< basic_json > iterator
Definition json.hpp:19530
basic_json(const value_t v)
create an empty value with a given type
Definition json.hpp:20117
const_reference operator[](size_type idx) const
access specified array element
Definition json.hpp:21408
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition json.hpp:22607
const_reverse_iterator rend() const noexcept
returns an iterator to the reverse-end
Definition json.hpp:22141
friend std::istream & operator>>(std::istream &i, basic_json &j)
Definition json.hpp:23445
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition json.hpp:23562
void swap(string_t &other)
exchanges the values
Definition json.hpp:22825
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition json.hpp:20151
NLOHMANN_BASIC_JSON_TPL basic_json_t
Definition json.hpp:19426
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition json.hpp:20754
::nlohmann::detail::binary_writer< basic_json, CharType > binary_writer
Definition json.hpp:19460
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
Definition json.hpp:19534
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition json.hpp:19851
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition json.hpp:21263
detail::actual_object_comparator_t< basic_json > object_comparator_t
Definition json.hpp:19671
basic_json(const basic_json &other)
copy constructor
Definition json.hpp:20447
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition json.hpp:22455
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition json.hpp:22536
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:23555
constexpr bool is_object() const noexcept
return whether value is an object
Definition json.hpp:20659
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:23571
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:23737
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition json.hpp:22568
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition json.hpp:20334
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition json.hpp:22031
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:23648
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition json.hpp:21999
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition json.hpp:19845
::nlohmann::json_pointer< std::string > json_pointer
Definition json.hpp:19468
bool operator!=(const byte_container_with_subtype &rhs) const
Definition json.hpp:5933
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition json.hpp:5899
std::uint64_t subtype_type
Definition json.hpp:5896
bool operator==(const byte_container_with_subtype &rhs) const
Definition json.hpp:5927
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition json.hpp:5921
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition json.hpp:5909
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition json.hpp:5948
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition json.hpp:5914
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition json.hpp:5955
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition json.hpp:5904
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition json.hpp:5940
void clear_subtype() noexcept
clears the binary subtype
Definition json.hpp:5962
deserialization of CBOR, MessagePack, and UBJSON values
Definition json.hpp:9213
json_sax_t * sax
the SAX parser
Definition json.hpp:12113
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition json.hpp:11975
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result, bool inside_ndarray=false)
determine the type and size for a container
Definition json.hpp:11377
binary_reader(const binary_reader &)=delete
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition json.hpp:9535
typename BasicJsonType::string_t string_t
Definition json.hpp:9217
std::size_t chars_read
the number of characters read
Definition json.hpp:12104
std::pair< char_int_type, string_t > bjd_type
Definition json.hpp:12139
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition json.hpp:9497
typename InputAdapterType::char_type char_type
Definition json.hpp:9220
bool parse_msgpack_internal()
Definition json.hpp:10341
std::string get_token_string() const
Definition json.hpp:12045
const bool is_little_endian
whether we can assume little endianness
Definition json.hpp:12107
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:9215
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition json.hpp:10722
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition json.hpp:12058
InputAdapterType ia
input adapter
Definition json.hpp:12098
bool get_ubjson_high_precision_number()
Definition json.hpp:11818
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition json.hpp:12008
binary_reader(binary_reader &&)=default
char_int_type get_ignore_noop()
Definition json.hpp:11906
bool get_ubjson_value(const char_int_type prefix)
Definition json.hpp:11444
bool get_ubjson_ndarray_size(std::vector< size_t > &dim)
Definition json.hpp:11089
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition json.hpp:9417
bool get_msgpack_object(const std::size_t len)
Definition json.hpp:10938
typename char_traits< char_type >::int_type char_int_type
Definition json.hpp:9221
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition json.hpp:9229
typename BasicJsonType::binary_t binary_t
Definition json.hpp:9218
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition json.hpp:9313
binary_reader & operator=(const binary_reader &)=delete
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition json.hpp:10285
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition json.hpp:10152
bool get_number(const input_format_t format, NumberType &result)
Definition json.hpp:11932
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:9214
bool unexpect_eof(const input_format_t format, const char *context) const
Definition json.hpp:12032
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition json.hpp:9338
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:9250
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition json.hpp:10247
char_int_type current
the current character
Definition json.hpp:12101
bool get_msgpack_array(const std::size_t len)
Definition json.hpp:10916
char_int_type get()
get next character from the input
Definition json.hpp:11897
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:9216
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition json.hpp:10805
bool parse_ubjson_internal(const bool get_char=true)
Definition json.hpp:10975
bool get_ubjson_size_value(std::size_t &result, bool &is_ndarray, char_int_type prefix=0)
Definition json.hpp:11154
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition json.hpp:9565
const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map
Definition json.hpp:12141
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition json.hpp:9368
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition json.hpp:10994
static JSON_INLINE_VARIABLE constexpr std::size_t npos
Definition json.hpp:12095
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition json.hpp:10056
const input_format_t input_format
input format
Definition json.hpp:12110
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition json.hpp:9390
binary_reader & operator=(binary_reader &&)=default
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition json.hpp:16188
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition json.hpp:16026
void write_bson(const BasicJsonType &j)
Definition json.hpp:15099
typename BasicJsonType::binary_t binary_t
Definition json.hpp:15081
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition json.hpp:16086
typename BasicJsonType::string_t string_t
Definition json.hpp:15080
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition json.hpp:16834
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition json.hpp:16104
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition json.hpp:16169
bool write_bjdata_ndarray(const typename BasicJsonType::object_t &value, const bool use_count, const bool use_type)
Definition json.hpp:16657
static CharType to_char_type(std::uint8_t x) noexcept
Definition json.hpp:16841
static constexpr CharType get_cbor_float_prefix(double)
Definition json.hpp:16334
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition json.hpp:16054
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition json.hpp:15090
static constexpr CharType get_ubjson_float_prefix(double)
Definition json.hpp:16649
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix, const bool use_bjdata)
Definition json.hpp:16360
static constexpr CharType get_msgpack_float_prefix(double)
Definition json.hpp:16348
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition json.hpp:16251
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition json.hpp:16863
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition json.hpp:16313
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:15778
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition json.hpp:16036
static std::size_t calc_bson_string_size(const string_t &value)
Definition json.hpp:16046
void write_number(const NumberType n, const bool OutputIsLittleEndian=false)
Definition json.hpp:16784
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition json.hpp:15999
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition json.hpp:16068
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:15082
CharType ubjson_prefix(const BasicJsonType &j, const bool use_bjdata) const noexcept
determine the type prefix of container values
Definition json.hpp:16543
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition json.hpp:16114
static constexpr CharType get_ubjson_float_prefix(float)
Definition json.hpp:16644
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition json.hpp:16161
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition json.hpp:16203
void write_msgpack(const BasicJsonType &j)
Definition json.hpp:15452
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition json.hpp:16298
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition json.hpp:16800
output_adapter_t< CharType > oa
the output
Definition json.hpp:16873
void write_cbor(const BasicJsonType &j)
Definition json.hpp:15128
static constexpr CharType get_cbor_float_prefix(float)
Definition json.hpp:16329
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition json.hpp:16014
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition json.hpp:16136
static constexpr CharType get_msgpack_float_prefix(float)
Definition json.hpp:16343
const bool is_little_endian
whether we can assume little endianness
Definition json.hpp:16870
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition json.hpp:16146
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition json.hpp:16076
general exception of the basic_json class
Definition json.hpp:4373
exception(int id_, const char *what_arg)
Definition json.hpp:4386
const int id
the id of the exception
Definition json.hpp:4382
static std::string diagnostics(std::nullptr_t)
Definition json.hpp:4393
std::runtime_error m
an exception object as storage for error messages
Definition json.hpp:4465
static std::string name(const std::string &ename, int id_)
Definition json.hpp:4388
const char * what() const noexcept override
returns the explanatory string
Definition json.hpp:4376
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition json.hpp:4399
file_input_adapter(const file_input_adapter &)=delete
std::FILE * m_file
the file pointer to read from
Definition json.hpp:6215
file_input_adapter(std::FILE *f) noexcept
Definition json.hpp:6195
std::char_traits< char >::int_type get_character() noexcept
Definition json.hpp:6208
file_input_adapter(file_input_adapter &&) noexcept=default
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::istream * is
the associated input stream
Definition json.hpp:6274
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition json.hpp:6251
std::char_traits< char >::int_type get_character()
Definition json.hpp:6261
input_stream_adapter(const input_stream_adapter &)=delete
std::streambuf * sb
Definition json.hpp:6275
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(std::istream &i)
Definition json.hpp:6242
exception indicating errors with iterators
Definition json.hpp:4524
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4527
invalid_iterator(int id_, const char *what_arg)
Definition json.hpp:4535
~iter_impl()=default
iter_impl operator+(difference_type i) const
add to iterator
Definition json.hpp:13490
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition json.hpp:13053
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
Definition json.hpp:12948
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition json.hpp:13435
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition json.hpp:13043
bool operator<(const iter_impl &other) const
comparison: smaller
Definition json.hpp:13382
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition json.hpp:13417
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition json.hpp:13481
iter_impl & operator--()
pre-decrement (–it)
Definition json.hpp:13296
const object_t::key_type & key() const
return the key of an object iterator
Definition json.hpp:13590
bool operator==(const IterImpl &other) const
comparison: equal
Definition json.hpp:13337
iter_impl operator++(int) &
post-increment (it++)
Definition json.hpp:13234
iter_impl & operator+=(difference_type i)
add to iterator
Definition json.hpp:13444
reference operator[](difference_type n) const
access to successor
Definition json.hpp:13552
pointer operator->() const
dereference the iterator
Definition json.hpp:13192
difference_type operator-(const iter_impl &other) const
return difference
Definition json.hpp:13523
iter_impl(iter_impl &&) noexcept=default
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition json.hpp:13501
bool operator>(const iter_impl &other) const
comparison: greater than
Definition json.hpp:13426
iter_impl & operator++()
pre-increment (++it)
Definition json.hpp:13245
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
Definition json.hpp:12952
reference operator*() const
return a reference to the value pointed to by the iterator
Definition json.hpp:13148
iter_impl operator-(difference_type i) const
subtract from iterator
Definition json.hpp:13512
iter_impl< typename std::conditional< std::is_const< BasicJsonType >::value, typename std::remove_const< BasicJsonType >::type, const BasicJsonType >::type > other_iter_impl
the iterator with BasicJsonType of different const-ness
Definition json.hpp:12918
iter_impl()=default
friend BasicJsonType
Definition json.hpp:12921
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition json.hpp:13028
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition json.hpp:13373
iter_impl operator--(int) &
post-decrement (it–)
Definition json.hpp:13285
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition json.hpp:13018
void set_end() noexcept
set the iterator past the last value
Definition json.hpp:13109
iteration_proxy_value operator++(int) &
Definition json.hpp:5243
iteration_proxy_value(iteration_proxy_value const &)=default
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition json.hpp:5252
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition json.hpp:5258
std::ptrdiff_t difference_type
Definition json.hpp:5189
string_type empty_str
an empty string (to return a reference for primitive values)
Definition json.hpp:5206
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:5210
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition json.hpp:5235
iteration_proxy_value value_type
Definition json.hpp:5190
std::size_t array_index_last
last stringified array index
Definition json.hpp:5202
std::size_t array_index
an index for arrays (used to create key names)
Definition json.hpp:5200
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition json.hpp:5194
IteratorType::reference value() const
return value of the iterator
Definition json.hpp:5300
const string_type & key() const
return key of the iterator
Definition json.hpp:5264
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
std::input_iterator_tag iterator_category
Definition json.hpp:5193
string_type array_index_str
a string representation of the array index
Definition json.hpp:5204
IteratorType anchor
the iterator
Definition json.hpp:5198
proxy class for the items() function
Definition json.hpp:5308
IteratorType::pointer container
the container to iterate
Definition json.hpp:5311
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition json.hpp:5333
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:5327
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition json.hpp:5317
iteration_proxy & operator=(iteration_proxy const &)=default
char_traits< char_type >::int_type get_character()
Definition json.hpp:6291
iterator_input_adapter(IteratorType first, IteratorType last)
Definition json.hpp:6287
typename std::iterator_traits< IteratorType >::value_type char_type
Definition json.hpp:6285
value_type owned_value
Definition json.hpp:14870
json_ref(json_ref &&) noexcept=default
json_ref(const value_type &value)
Definition json.hpp:14828
json_ref(value_type &&value)
Definition json.hpp:14824
value_type const & operator*() const
Definition json.hpp:14859
value_type const * operator->() const
Definition json.hpp:14864
json_ref(std::initializer_list< json_ref > init)
Definition json.hpp:14832
json_ref(Args &&... args)
Definition json.hpp:14839
value_type moved_or_copied() const
Definition json.hpp:14850
BasicJsonType value_type
Definition json.hpp:14822
value_type const * value_ref
Definition json.hpp:14871
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition json.hpp:13685
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition json.hpp:13697
json_reverse_iterator & operator++()
pre-increment (++it)
Definition json.hpp:13691
std::ptrdiff_t difference_type
Definition json.hpp:13671
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition json.hpp:13709
reference operator[](difference_type n) const
access to successor
Definition json.hpp:13733
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition json.hpp:13739
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition json.hpp:13727
typename Base::reference reference
the reference type for the pointed-to element
Definition json.hpp:13675
reference value() const
return the value of an iterator
Definition json.hpp:13746
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition json.hpp:13682
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition json.hpp:13703
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition json.hpp:13673
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition json.hpp:13721
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition json.hpp:13678
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition json.hpp:13715
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:7295
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition json.hpp:7335
bool binary(binary_t &)
Definition json.hpp:7330
bool number_integer(number_integer_t)
Definition json.hpp:7310
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition json.hpp:7350
bool number_unsigned(number_unsigned_t)
Definition json.hpp:7315
bool string(string_t &)
Definition json.hpp:7325
typename BasicJsonType::binary_t binary_t
Definition json.hpp:7298
bool number_float(number_float_t, const string_t &)
Definition json.hpp:7320
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition json.hpp:7360
bool key(string_t &)
Definition json.hpp:7340
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:7294
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:7296
typename BasicJsonType::string_t string_t
Definition json.hpp:7297
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition json.hpp:7173
const parser_callback_t callback
callback function
Definition json.hpp:7283
BasicJsonType & root
the parsed JSON value
Definition json.hpp:7271
typename BasicJsonType::string_t string_t
Definition json.hpp:6990
bool number_float(number_float_t val, const string_t &)
Definition json.hpp:7034
constexpr bool is_errored() const
Definition json.hpp:7185
bool errored
whether a syntax error occurred
Definition json.hpp:7281
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:6988
typename BasicJsonType::binary_t binary_t
Definition json.hpp:6991
bool start_object(std::size_t len)
Definition json.hpp:7052
bool start_array(std::size_t len)
Definition json.hpp:7123
std::vector< bool > key_keep_stack
stack to manage which object keys to keep
Definition json.hpp:7277
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:6987
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition json.hpp:7285
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
Definition json.hpp:7273
std::vector< bool > keep_stack
stack to manage which values to keep
Definition json.hpp:7275
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition json.hpp:7207
typename BasicJsonType::parse_event_t parse_event_t
Definition json.hpp:6993
BasicJsonType discarded
a discarded value for the callback
Definition json.hpp:7287
typename BasicJsonType::parser_callback_t parser_callback_t
Definition json.hpp:6992
bool number_unsigned(number_unsigned_t val)
Definition json.hpp:7028
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
BasicJsonType * object_element
helper to hold the reference for the next object element
Definition json.hpp:7279
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition json.hpp:6995
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:6989
bool number_integer(number_integer_t val)
Definition json.hpp:7022
SAX implementation to create a JSON value from SAX events.
Definition json.hpp:6802
bool errored
whether a syntax error occurred
Definition json.hpp:6978
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:6856
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition json.hpp:6815
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition json.hpp:6923
typename BasicJsonType::string_t string_t
Definition json.hpp:6807
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition json.hpp:6980
bool start_object(std::size_t len)
Definition json.hpp:6868
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
Definition json.hpp:6974
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:6805
bool number_unsigned(number_unsigned_t val)
Definition json.hpp:6844
bool number_integer(number_integer_t val)
Definition json.hpp:6838
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition json.hpp:6949
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:6804
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool binary(binary_t &val)
Definition json.hpp:6862
json_sax_dom_parser(json_sax_dom_parser &&)=default
BasicJsonType & root
the parsed JSON value
Definition json.hpp:6972
bool boolean(bool val)
Definition json.hpp:6832
bool number_float(number_float_t val, const string_t &)
Definition json.hpp:6850
constexpr bool is_errored() const
Definition json.hpp:6935
typename BasicJsonType::binary_t binary_t
Definition json.hpp:6808
BasicJsonType * object_element
helper to hold the reference for the next object element
Definition json.hpp:6976
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:6806
bool start_array(std::size_t len)
Definition json.hpp:6900
bool key(string_t &val)
Definition json.hpp:6880
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:7436
token_type
token types for the parser
Definition json.hpp:7413
@ value_float
an floating point number – use get_number_float() for actual value
Definition json.hpp:7421
@ begin_array
the character for array begin [
Definition json.hpp:7422
@ value_string
a string – use get_string() for actual value
Definition json.hpp:7418
@ end_array
the character for array end ]
Definition json.hpp:7424
@ uninitialized
indicating the scanner is uninitialized
Definition json.hpp:7414
@ parse_error
indicating a parse error
Definition json.hpp:7428
@ value_integer
a signed integer – use get_number_integer() for actual value
Definition json.hpp:7420
@ value_separator
the value separator ,
Definition json.hpp:7427
@ end_object
the character for object end }
Definition json.hpp:7425
@ literal_true
the true literal
Definition json.hpp:7415
@ begin_object
the character for object begin {
Definition json.hpp:7423
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
Definition json.hpp:7419
@ literal_null
the null literal
Definition json.hpp:7417
@ end_of_input
indicating the end of the input buffer
Definition json.hpp:7429
@ name_separator
the name separator :
Definition json.hpp:7426
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
Definition json.hpp:7430
@ literal_false
the false literal
Definition json.hpp:7416
lexical analysis
Definition json.hpp:7486
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition json.hpp:8694
bool skip_bom()
skip the UTF-8 byte order mark
Definition json.hpp:8860
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition json.hpp:8990
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition json.hpp:7543
token_type scan_string()
scan a string literal
Definition json.hpp:7628
number_integer_t value_integer
Definition json.hpp:8996
void skip_whitespace()
Definition json.hpp:8874
const bool ignore_comments
whether comments should be ignored (true) or signaled as errors (false)
Definition json.hpp:8975
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition json.hpp:7497
char_int_type current
the current character
Definition json.hpp:8978
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition json.hpp:8847
std::string get_token_string() const
Definition json.hpp:8822
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:7489
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition json.hpp:8786
typename BasicJsonType::string_t string_t
Definition json.hpp:7490
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:7488
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition json.hpp:7591
char_int_type get()
Definition json.hpp:8711
constexpr position_t get_position() const noexcept
return position of last read token
Definition json.hpp:8814
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition json.hpp:8286
const char_int_type decimal_point_char
the decimal point
Definition json.hpp:9001
number_unsigned_t value_unsigned
Definition json.hpp:8997
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:7487
token_type scan()
Definition json.hpp:8882
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition json.hpp:8792
typename char_traits< char_type >::int_type char_int_type
Definition json.hpp:7492
bool scan_comment()
scan a comment
Definition json.hpp:8218
typename lexer_base< BasicJsonType >::token_type token_type
Definition json.hpp:7495
lexer(lexer &&)=default
~lexer()=default
const char * error_message
a description of occurred lexer errors
Definition json.hpp:8993
lexer & operator=(lexer &&)=default
bool next_unget
whether the next get() call should just return current
Definition json.hpp:8981
lexer(const lexer &)=delete
typename InputAdapterType::char_type char_type
Definition json.hpp:7491
InputAdapterType ia
input adapter
Definition json.hpp:8972
lexer & operator=(lexer &)=delete
token_type scan_number()
scan a number literal
Definition json.hpp:8343
number_float_t value_float
Definition json.hpp:8998
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition json.hpp:8804
token_type scan_literal(const char_type *literal_text, const std::size_t length, token_type return_type)
Definition json.hpp:8674
std::vector< char_type > token_string
raw input token string (for error messages)
Definition json.hpp:8987
void add(char_int_type c)
add a character to token_buffer
Definition json.hpp:8775
position_t position
the start position of the current token
Definition json.hpp:8984
void unget()
unget current character (read it again on next get)
Definition json.hpp:8748
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition json.hpp:8798
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition json.hpp:7517
exception indicating other library errors
Definition json.hpp:4576
other_error(int id_, const char *what_arg)
Definition json.hpp:4587
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4579
exception indicating access out of the defined range
Definition json.hpp:4559
out_of_range(int id_, const char *what_arg)
Definition json.hpp:4570
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4562
output_adapter(StringType &s)
Definition json.hpp:15048
output_adapter_t< CharType > oa
Definition json.hpp:15057
output_adapter(std::basic_ostream< CharType > &s)
Definition json.hpp:15044
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition json.hpp:15040
output adapter for output streams
Definition json.hpp:14989
void write_characters(const CharType *s, std::size_t length) override
Definition json.hpp:15001
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition json.hpp:14991
void write_character(CharType c) override
Definition json.hpp:14995
std::basic_ostream< CharType > & stream
Definition json.hpp:15007
output adapter for basic_string
Definition json.hpp:15014
void write_character(CharType c) override
Definition json.hpp:15020
output_string_adapter(StringType &s) noexcept
Definition json.hpp:15016
void write_characters(const CharType *s, std::size_t length) override
Definition json.hpp:15026
output adapter for byte vectors
Definition json.hpp:14964
std::vector< CharType, AllocatorType > & v
Definition json.hpp:14982
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition json.hpp:14966
void write_characters(const CharType *s, std::size_t length) override
Definition json.hpp:14976
void write_character(CharType c) override
Definition json.hpp:14970
exception indicating a parse error
Definition json.hpp:4471
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:4483
static std::string position_string(const position_t &pos)
Definition json.hpp:4514
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4491
const std::size_t byte
byte index of the parse error
Definition json.hpp:4508
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition json.hpp:4511
std::string exception_message(const token_type expected, const std::string &context)
Definition json.hpp:12646
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition json.hpp:12683
bool sax_parse_internal(SAX *sax)
Definition json.hpp:12348
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:12239
typename lexer_t::token_type token_type
Definition json.hpp:12235
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition json.hpp:12261
token_type last_token
the type of the last read token
Definition json.hpp:12679
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:12231
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:12230
typename BasicJsonType::string_t string_t
Definition json.hpp:12233
lexer_t m_lexer
the lexer
Definition json.hpp:12681
lexer< BasicJsonType, InputAdapterType > lexer_t
Definition json.hpp:12234
bool accept(const bool strict=true)
public accept interface
Definition json.hpp:12321
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:12232
const parser_callback_t< BasicJsonType > callback
callback function
Definition json.hpp:12677
bool sax_parse(SAX *sax, const bool strict=true)
Definition json.hpp:12329
token_type get_token()
get next token from lexer
Definition json.hpp:12641
primitive_iterator_t & operator++() noexcept
Definition json.hpp:12795
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition json.hpp:12827
static constexpr difference_type end_value
Definition json.hpp:12737
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition json.hpp:12762
primitive_iterator_t & operator--() noexcept
Definition json.hpp:12808
static constexpr difference_type begin_value
Definition json.hpp:12736
void set_end() noexcept
set iterator to a defined past the end
Definition json.hpp:12756
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:12778
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition json.hpp:12768
primitive_iterator_t operator++(int) &noexcept
Definition json.hpp:12801
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition json.hpp:12821
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:12773
constexpr difference_type get_value() const noexcept
Definition json.hpp:12744
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:12790
primitive_iterator_t operator+(difference_type n) noexcept
Definition json.hpp:12783
void set_begin() noexcept
set iterator to a defined beginning
Definition json.hpp:12750
primitive_iterator_t operator--(int) &noexcept
Definition json.hpp:12814
std::ptrdiff_t difference_type
Definition json.hpp:12735
typename BasicJsonType::binary_t::value_type binary_char_t
Definition json.hpp:18065
std::array< char, 512 > string_buffer
string buffer
Definition json.hpp:18984
std::uint8_t state
Definition json.hpp:18402
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:18064
std::size_t bytes_after_last_accept
Definition json.hpp:18406
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition json.hpp:18075
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition json.hpp:18400
std::size_t undumped_chars
Definition json.hpp:18407
const char thousands_sep
the locale's thousand separator character
Definition json.hpp:18979
static constexpr std::uint8_t UTF8_REJECT
Definition json.hpp:18067
const char decimal_point
the locale's decimal point character
Definition json.hpp:18981
serializer & operator=(const serializer &)=delete
~serializer()=default
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition json.hpp:18992
string_t indent_string
the indentation string
Definition json.hpp:18989
const std::lconv * loc
the locale
Definition json.hpp:18977
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:18063
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:18062
serializer & operator=(serializer &&)=delete
typename BasicJsonType::string_t string_t
Definition json.hpp:18061
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition json.hpp:18974
const char indent_char
the indentation character
Definition json.hpp:18987
std::size_t bytes
Definition json.hpp:18403
static constexpr std::uint8_t UTF8_ACCEPT
Definition json.hpp:18066
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:18115
serializer(const serializer &)=delete
serializer(serializer &&)=delete
span_input_adapter(CharT b, std::size_t l)
Definition json.hpp:6615
contiguous_bytes_input_adapter ia
Definition json.hpp:6631
span_input_adapter(IteratorType first, IteratorType last)
Definition json.hpp:6622
contiguous_bytes_input_adapter && get()
Definition json.hpp:6625
exception indicating executing a member function with a wrong type
Definition json.hpp:4542
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition json.hpp:4545
type_error(int id_, const char *what_arg)
Definition json.hpp:4553
std::char_traits< char >::int_type get_character() noexcept
Definition json.hpp:6449
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
Definition json.hpp:6476
wide_string_input_adapter(BaseInputAdapter base)
Definition json.hpp:6446
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition json.hpp:13841
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition json.hpp:14227
json_pointer< string_t > convert() const &
Definition json.hpp:14640
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:13936
static BasicJsonType::size_type array_index(const string_t &s)
Definition json.hpp:14019
typename string_t_helper< RefStringType >::type string_t
Definition json.hpp:13863
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:13943
json_pointer result
Definition json.hpp:14064
result reference_tokens
Definition json.hpp:14065
json_pointer(const string_t &s="")
create JSON pointer
Definition json.hpp:13867
static std::vector< string_t > split(const string_t &reference_string)
split the string input to reference tokens
Definition json.hpp:14471
bool empty() const noexcept
return whether pointer points to the root document
Definition json.hpp:14002
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition json.hpp:14079
void pop_back()
remove last reference token
Definition json.hpp:13964
string_t to_string() const
return a string representation of the JSON pointer
Definition json.hpp:13873
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition json.hpp:13921
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition json.hpp:13995
json_pointer< string_t > convert() &&
Definition json.hpp:14647
static void flatten(const string_t &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition json.hpp:14540
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition json.hpp:13903
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:13928
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition json.hpp:14159
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition json.hpp:13950
static BasicJsonType unflatten(const BasicJsonType &value)
Definition json.hpp:14612
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition json.hpp:13913
friend class json_pointer
Definition json.hpp:13847
const string_t & back() const
return last reference token
Definition json.hpp:13976
friend std::ostream & operator<<(std::ostream &o, const json_pointer &ptr)
write string representation of the JSON pointer to stream
Definition json.hpp:13894
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition json.hpp:14285
friend class basic_json
Definition json.hpp:13844
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition json.hpp:13988
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition json.hpp:14334
bool contains(const BasicJsonType *ptr) const
Definition json.hpp:14383
decltype( get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition json.hpp:5379
#define V(a, b, c)
#define T(t)
#define N(x, y, z)
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition json.hpp:2596
#define JSON_HEDLEY_CONST
Definition json.hpp:1818
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition json.hpp:1102
#define JSON_INLINE_VARIABLE
Definition json.hpp:2499
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition json.hpp:1448
#define JSON_PRIVATE_UNLESS_TESTED
Definition json.hpp:2559
#define NLOHMANN_JSON_VERSION_PATCH
Definition json.hpp:70
#define JSON_HEDLEY_LIKELY(expr)
Definition json.hpp:1713
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.hpp:14736
#define JSON_HEDLEY_NON_NULL(...)
Definition json.hpp:1606
#define JSON_INTERNAL_CATCH(exception)
Definition json.hpp:2526
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:24456
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition json.hpp:2047
#define JSON_CATCH(exception)
Definition json.hpp:2525
#define JSON_ASSERT(x)
Definition json.hpp:2552
#define JSON_THROW(exception)
Definition json.hpp:2523
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition json.hpp:77
#define NLOHMANN_JSON_VERSION_MAJOR
Definition json.hpp:68
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.hpp:14786
#define NLOHMANN_BASIC_JSON_TPL
Definition json.hpp:2606
#define JSON_HEDLEY_UNLIKELY(expr)
Definition json.hpp:1714
#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_
Definition json.hpp:12119
#define JSON_TRY
Definition json.hpp:2524
#define NLOHMANN_JSON_NAMESPACE_END
Definition json.hpp:144
#define JSON_NO_UNIQUE_ADDRESS
Definition json.hpp:2505
basic_json< nlohmann::ordered_map > ordered_json
specialization that maintains the insertion order of object keys
Definition json.hpp:3432
#define NLOHMANN_JSON_VERSION_MINOR
Definition json.hpp:69
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition json.hpp:2786
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.hpp:14761
#define NLOHMANN_JSON_NAMESPACE_BEGIN
Definition json.hpp:134
#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_
Definition json.hpp:12116
basic_json<> json
default specialization
Definition json.hpp:3423
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition json.hpp:1103
#define JSON_EXPLICIT
Definition json.hpp:2823
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition json.hpp:1396
#define JSON_HEDLEY_PURE
Definition json.hpp:1787
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition json.hpp:22882
std::ostream & operator<<(std::ostream &s, const Guid &guid)
Definition guid.cpp:70
implements the Grisu2 algorithm for binary to decimal floating-point conversion.
Definition json.hpp:16952
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition json.hpp:17399
cached_power get_cached_power_for_binary_exponent(int e)
Definition json.hpp:17235
Target reinterpret_bits(const Source source)
Definition json.hpp:16955
boundaries compute_boundaries(FloatType value)
Definition json.hpp:17096
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:17453
constexpr int kAlpha
Definition json.hpp:17218
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition json.hpp:17735
constexpr int kGamma
Definition json.hpp:17219
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition json.hpp:17494
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition json.hpp:17835
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:17887
constexpr bool is_transparent()
Definition json.hpp:4195
constexpr bool is_c_string()
Definition json.hpp:4167
detail namespace with internal helper functions
Definition Export.hpp:7
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition json.hpp:12219
make_integer_sequence< size_t, N > make_index_sequence
Definition json.hpp:3192
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition json.hpp:9039
input_format_t
the supported input formats
Definition json.hpp:6178
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition json.hpp:300
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition json.hpp:5782
static void unescape(StringType &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition json.hpp:3006
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition json.hpp:3518
detector< Default, void, Op, Args... > detected_or
Definition json.hpp:303
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition json.hpp:9063
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition json.hpp:4291
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition json.hpp:9071
OutStringType concat(Args &&... args)
Definition json.hpp:4350
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition json.hpp:9055
typename T::value_type value_type_t
Definition json.hpp:3503
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition json.hpp:9059
constexpr std::array< T, sizeof...(Args)> make_array(Args &&... args)
Definition json.hpp:3223
decltype(std::declval< T & >().number_float( std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition json.hpp:9051
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:17972
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition json.hpp:309
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition json.hpp:4273
typename std::enable_if< B, T >::type enable_if_t
Definition json.hpp:3096
parse_event_t
Definition json.hpp:12203
@ value
the parser finished reading a JSON value
Definition json.hpp:12215
@ key
the parser read a key of a value in an object
Definition json.hpp:12213
@ array_end
the parser read ] and finished processing a JSON array
Definition json.hpp:12211
@ array_start
the parser read [ and started to process a JSON array
Definition json.hpp:12209
@ object_start
the parser read { and started to process a JSON object
Definition json.hpp:12205
@ object_end
the parser read } and finished processing a JSON object
Definition json.hpp:12207
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition json.hpp:294
typename T::pointer pointer_t
Definition json.hpp:3509
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition json.hpp:5011
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition json.hpp:4822
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition json.hpp:3184
conjunction< std::is_integral< Types >... > all_integral
Definition json.hpp:4063
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition json.hpp:14959
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition json.hpp:306
decltype(std::declval< T & >().null()) null_function_t
Definition json.hpp:9036
T conditional_static_cast(U value)
Definition json.hpp:4051
typename T::difference_type difference_type_t
Definition json.hpp:3506
conjunction< std::is_unsigned< Types >... > all_unsigned
Definition json.hpp:4069
constexpr T static_const< T >::value
Definition json.hpp:3219
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition json.hpp:2971
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition json.hpp:4285
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition json.hpp:5343
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition json.hpp:3597
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition json.hpp:4020
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition json.hpp:6580
cbor_tag_handler_t
how to treat CBOR tags
Definition json.hpp:9186
@ store
store tags as binary type
Definition json.hpp:9189
@ error
throw a parse_error exception in case of a tag
Definition json.hpp:9187
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition json.hpp:3748
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition json.hpp:3200
void concat_into(OutStringType &)
Definition json.hpp:4266
constexpr bool value_in_range_of(T val)
Definition json.hpp:4151
value_t
the JSON type enumeration
Definition json.hpp:2873
@ null
null value
Definition json.hpp:2874
@ number_integer
number value (signed integer)
Definition json.hpp:2879
@ boolean
boolean value
Definition json.hpp:2878
@ discarded
discarded by the parser callback function
Definition json.hpp:2883
@ binary
binary array (ordered collection of bytes)
Definition json.hpp:2882
@ object
object (unordered set of name/value pairs)
Definition json.hpp:2875
@ string
string value
Definition json.hpp:2877
@ number_float
number value (floating-point)
Definition json.hpp:2881
@ number_unsigned
number value (unsigned integer)
Definition json.hpp:2880
@ array
array (ordered collection of values)
Definition json.hpp:2876
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition json.hpp:3521
conjunction< std::is_signed< Types >... > all_signed
Definition json.hpp:4066
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:4905
static bool little_endianness(int num=1) noexcept
determine system byte order
Definition json.hpp:9199
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition json.hpp:6024
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition json.hpp:4270
typename make_void< Ts... >::type void_t
Definition json.hpp:255
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition json.hpp:6006
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:9081
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition json.hpp:2902
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition json.hpp:6523
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition json.hpp:3745
typename T::iterator_category iterator_category_t
Definition json.hpp:3515
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition json.hpp:9067
is_c_string< uncvref_t< T > > is_c_string_uncvref
Definition json.hpp:4185
error_handler_t
how to treat decoding errors
Definition json.hpp:18052
@ strict
throw a type_error exception in case of invalid UTF-8
Definition json.hpp:18053
@ ignore
ignore invalid UTF-8 sequences
Definition json.hpp:18055
@ replace
replace invalid UTF-8 sequences with U+FFFD
Definition json.hpp:18054
std::size_t concat_length()
Definition json.hpp:4235
std::integral_constant< bool, Value > bool_constant
Definition json.hpp:4157
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition json.hpp:312
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition json.hpp:3082
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition json.hpp:4665
typename T::key_compare detect_key_compare
Definition json.hpp:3581
typename std::conditional< std::is_same< T, void >::value, json_default_base, T >::type json_base_class
Definition json.hpp:13791
void to_json(BasicJsonType &j, T b) noexcept
Definition json.hpp:5643
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition json.hpp:4679
integer_sequence< size_t, Ints... > index_sequence
Definition json.hpp:3138
is_specialization_of<::nlohmann::json_pointer, uncvref_t< T > > is_json_pointer
Definition json.hpp:3974
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition json.hpp:4282
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition json.hpp:9078
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition json.hpp:5005
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:4011
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition json.hpp:9043
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:4024
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition json.hpp:4288
typename T::key_type key_type_t
Definition json.hpp:3500
typename T::reference reference_t
Definition json.hpp:3512
typename T::is_transparent detect_is_transparent
Definition json.hpp:3987
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition json.hpp:4279
typename T::mapped_type mapped_type_t
Definition json.hpp:3497
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition json.hpp:9047
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition json.hpp:2991
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition json.hpp:4073
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:3993
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:4077
void int_to_string(string_type &target, std::size_t value)
Definition json.hpp:5180
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition json.hpp:9074
decltype(std::declval< T >().template get< U >()) get_template_function
Definition json.hpp:3524
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition json.hpp:4276
DYN_FUNC bool operator<=(const priority_queue< T, Container, Compare > &a, const priority_queue< T, Container, Compare > &b)
DYN_FUNC bool operator>(const priority_queue< T, Container, Compare > &a, const priority_queue< T, Container, Compare > &b)
unsigned char byte
Definition GltfFunc.h:18
DYN_FUNC bool operator>=(const priority_queue< T, Container, Compare > &a, const priority_queue< T, Container, Compare > &b)
Definition guid.cpp:136
void swap(Wt::Guid &lhs, Wt::Guid &rhs) noexcept
Definition guid.cpp:138
namespace for Niels Lohmann
Definition json.hpp:5835
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:5859
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:5849
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:5839
typename BasicJsonType::object_t object_t
Definition json.hpp:3590
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition json.hpp:3591
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition json.hpp:3592
static constexpr int_type eof() noexcept
Definition json.hpp:3650
static char_type to_char_type(int_type i) noexcept
Definition json.hpp:3645
static int_type to_int_type(char_type c) noexcept
Definition json.hpp:3640
static char_type to_char_type(int_type i) noexcept
Definition json.hpp:3621
static constexpr int_type eof() noexcept
Definition json.hpp:3626
static int_type to_int_type(char_type c) noexcept
Definition json.hpp:3616
std::false_type value_t
Definition json.hpp:282
Default type
Definition json.hpp:283
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition json.hpp:16989
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:17071
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition json.hpp:17054
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition json.hpp:16977
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition json.hpp:16971
static constexpr int kPrecision
Definition json.hpp:16966
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition json.hpp:5568
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition json.hpp:5543
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition json.hpp:5533
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition json.hpp:5555
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition json.hpp:5584
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition json.hpp:5472
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition json.hpp:5481
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition json.hpp:5426
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition json.hpp:5494
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition json.hpp:5520
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition json.hpp:5507
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition json.hpp:5603
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition json.hpp:5624
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition json.hpp:5613
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition json.hpp:5448
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition json.hpp:5459
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition json.hpp:5439
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:5102
typename BasicJsonType::template json_serializer< T, void > serializer
Definition json.hpp:3543
typename BasicJsonType::template json_serializer< T, void > serializer
Definition json.hpp:3558
typename BasicJsonType::template json_serializer< T, void > serializer
Definition json.hpp:3573
static constexpr std::size_t size() noexcept
Definition json.hpp:3126
an iterator value
Definition json.hpp:12849
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition json.hpp:12853
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition json.hpp:12855
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition json.hpp:12851
static constexpr auto value
Definition json.hpp:3820
ConstructibleStringType laundered_type
Definition json.hpp:3831
static constexpr auto value
Definition json.hpp:3834
static constexpr bool value
Definition json.hpp:3537
typename std::iterator_traits< T >::value_type value_type
Definition json.hpp:6500
static one test(decltype(&C::capacity))
static two test(...)
detected_t< result_of_end, t_ref > sentinel
Definition json.hpp:3732
detected_t< result_of_begin, t_ref > iterator
Definition json.hpp:3731
typename std::add_lvalue_reference< T >::type t_ref
Definition json.hpp:3729
static constexpr bool value
Definition json.hpp:3741
static constexpr auto is_iterator_begin
Definition json.hpp:3737
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:9123
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:9124
typename BasicJsonType::binary_t binary_t
Definition json.hpp:9127
typename BasicJsonType::exception exception_t
Definition json.hpp:9128
typename BasicJsonType::string_t string_t
Definition json.hpp:9126
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:9125
typename BasicJsonType::binary_t binary_t
Definition json.hpp:9096
typename BasicJsonType::exception exception_t
Definition json.hpp:9097
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:9094
typename BasicJsonType::string_t string_t
Definition json.hpp:9095
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:9093
static constexpr bool value
Definition json.hpp:9100
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:9092
iterator_input_adapter< iterator_type > adapter_type
Definition json.hpp:6489
typename std::iterator_traits< iterator_type >::value_type char_type
Definition json.hpp:6488
static adapter_type create(IteratorType first, IteratorType last)
Definition json.hpp:6491
Default base class of the basic_json class.
Definition json.hpp:13788
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:14945
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:3037
std::size_t chars_read_current_line
the number of characters read in the current line
Definition json.hpp:3041
std::size_t lines_read
the number of lines read
Definition json.hpp:3043
std::size_t chars_read_total
the total number of characters read
Definition json.hpp:3039
static JSON_INLINE_VARIABLE constexpr T value
Definition json.hpp:3214
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:5804
integer_sequence< T, Ints...,(Ints+SeqSize)..., 2 *SeqSize > type
Definition json.hpp:3156
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition json.hpp:3164
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:6381
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:6323
SAX interface.
Definition json.hpp:6672
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:6673
typename BasicJsonType::string_t string_t
Definition json.hpp:6676
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:6675
virtual bool null()=0
a null value was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:6674
json_sax(json_sax &&) noexcept=default
typename BasicJsonType::binary_t binary_t
Definition json.hpp:6677
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:19034
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:19347
std::vector< std::pair< const Key, T >, Allocator > Container
Definition json.hpp:19037
std::pair< iterator, bool > insert(value_type &&value)
Definition json.hpp:19328
typename Container::value_type value_type
Definition json.hpp:19041
std::equal_to< Key > key_compare
Definition json.hpp:19045
iterator erase(iterator pos)
Definition json.hpp:19206
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition json.hpp:19051
T & operator[](KeyType &&key)
Definition json.hpp:19093
typename Container::iterator iterator
Definition json.hpp:19038
const T & at(KeyType &&key) const
Definition json.hpp:19153
T & at(KeyType &&key)
Definition json.hpp:19125
const T & operator[](KeyType &&key) const
Definition json.hpp:19105
iterator find(const key_type &key)
Definition json.hpp:19290
iterator erase(iterator first, iterator last)
Definition json.hpp:19211
const T & at(const key_type &key) const
Definition json.hpp:19138
const_iterator find(const key_type &key) const
Definition json.hpp:19316
T & operator[](const key_type &key)
Definition json.hpp:19086
size_type erase(KeyType &&key)
Definition json.hpp:19187
typename Container::size_type size_type
Definition json.hpp:19040
ordered_map() noexcept(noexcept(Container()))
Definition json.hpp:19050
void insert(InputIt first, InputIt last)
Definition json.hpp:19351
size_type count(const key_type &key) const
Definition json.hpp:19264
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition json.hpp:19073
size_type erase(const key_type &key)
Definition json.hpp:19166
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition json.hpp:19055
std::pair< iterator, bool > insert(const value_type &value)
Definition json.hpp:19333
size_type count(KeyType &&key) const
Definition json.hpp:19278
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition json.hpp:19053
const T & operator[](const key_type &key) const
Definition json.hpp:19098
JSON_NO_UNIQUE_ADDRESS key_compare m_compare
Definition json.hpp:19360
iterator find(KeyType &&key)
Definition json.hpp:19304
T & at(const key_type &key)
Definition json.hpp:19110
typename Container::const_iterator const_iterator
Definition json.hpp:19039
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition json.hpp:19058
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition json.hpp:24506
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition json.hpp:24520